diff --git a/Android.bp b/Android.bp
index fab53d1..4097571 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,13 +83,14 @@
         "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",
+        "android.hardware.radio.config-V2-java",
+        "android.hardware.radio.data-V2-java",
+        "android.hardware.radio.ims-V1-java",
+        "android.hardware.radio.messaging-V2-java",
+        "android.hardware.radio.modem-V2-java",
+        "android.hardware.radio.network-V2-java",
+        "android.hardware.radio.sim-V2-java",
+        "android.hardware.radio.voice-V2-java",
         "voip-common",
         "ims-common",
         "unsupportedappusage",
diff --git a/OWNERS b/OWNERS
index c7cafda..a061cf0 100644
--- a/OWNERS
+++ b/OWNERS
@@ -17,12 +17,6 @@
 tnd@google.com
 xiaotonj@google.com
 
-# Temporarily reduced the owner during refactoring
-per-file SubscriptionController.java=set noparent
-per-file SubscriptionController.java=jackyu@google.com,amruthr@google.com
-per-file SubscriptionInfoUpdater.java=set noparent
-per-file SubscriptionInfoUpdater.java=jackyu@google.com,amruthr@google.com
-
 
 
 
diff --git a/README.txt b/README.txt
index 9e40b77..1a44beb 100644
--- a/README.txt
+++ b/README.txt
@@ -15,7 +15,7 @@
 implement in this directory and packages/services/Telephony. This IPC scheme
 allows us to run public API code in the calling process, while the
 telephony-related code runs in the privileged com.android.phone process. Such
-implementations include PhoneInterfaceManager, SubscriptionController and
+implementations include PhoneInterfaceManager, SubscriptionManagerService and
 others.
 
 The declaration of the com.android.phone process is in
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 0f87e95..61e44a3 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: 53
+// Next id: 70
 message PersistAtoms {
     /* Aggregated RAT usage during the call. */
     repeated VoiceCallRatUsage voice_call_rat_usage = 1;
@@ -180,6 +180,57 @@
 
     /* Unmetered networks information. */
     repeated UnmeteredNetworks unmetered_networks = 52;
+
+    /* Outgoing Short Code SMS statistics and information. */
+    repeated OutgoingShortCodeSms outgoing_short_code_sms = 53;
+
+    /* Timestamp of last outgoing_short_code_sms pull. */
+    optional int64 outgoing_short_code_sms_pull_timestamp_millis = 54;
+
+    /* Number of time the user toggled the data switch feature since the last collection. */
+    optional int32 auto_data_switch_toggle_count = 55;
+
+    /** Snapshot of satellite controller. */
+    repeated SatelliteController satellite_controller = 58;
+
+    /* Timestamp of last satellite_controller pull. */
+    optional int64 satellite_controller_pull_timestamp_millis = 59;
+
+    /** Snapshot of satellite controller. */
+    repeated SatelliteSession satellite_session = 60;
+
+    /* Timestamp of last satellite_controller pull. */
+    optional int64 satellite_session_pull_timestamp_millis = 61;
+
+    /** Snapshot of satellite incoming datagram. */
+    repeated SatelliteIncomingDatagram satellite_incoming_datagram = 62;
+
+    /* Timestamp of last satellite_incoming_datagram pull. */
+    optional int64 satellite_incoming_datagram_pull_timestamp_millis = 63;
+
+    /** Snapshot of satellite outgoing datagram. */
+    repeated SatelliteOutgoingDatagram satellite_outgoing_datagram = 64;
+
+    /* Timestamp of last satellite_outgoing_datagram pull. */
+    optional int64 satellite_outgoing_datagram_pull_timestamp_millis = 65;
+
+    /** Snapshot of satellite provision datagram. */
+    repeated SatelliteProvision satellite_provision = 66;
+
+    /* Timestamp of last satellite_provision pull. */
+    optional int64 satellite_provision_pull_timestamp_millis = 67;
+
+    /** Snapshot of satellite SOS message recommender. */
+    repeated SatelliteSosMessageRecommender satellite_sos_message_recommender = 68;
+
+    /* Timestamp of last satellite_sos_message_recommender pull. */
+    optional int64 satellite_sos_message_recommender_pull_timestamp_millis = 69;
+
+    /* Consolidated emergency numbers list information. */
+    repeated EmergencyNumbersInfo emergency_numbers_info = 56;
+
+    /* Timestamp of last emergency number pull. */
+    optional int64 emergency_number_pull_timestamp_millis = 57;
 }
 
 // The canonical versions of the following enums live in:
@@ -223,6 +274,8 @@
     optional bool is_multiparty = 31;
     optional int32 call_duration = 32;
     optional int32 last_known_rat = 33;
+    optional int32 fold_state = 34;
+
     // Internal use only
     optional int64 setup_begin_millis = 10001;
 }
@@ -250,6 +303,7 @@
     optional int32 carrier_id = 13;
     optional int64 message_id = 14;
     optional int32 count = 15;
+    optional bool is_managed_profile = 16;
 
     // Internal use only
     optional int32 hashCode = 10001;
@@ -271,6 +325,9 @@
     optional int32 retry_id = 13;
     optional int64 interval_millis = 14;
     optional int32 count = 15;
+    optional int32 send_error_code = 16;
+    optional int32 network_error_code = 17;
+    optional bool is_managed_profile = 18;
 
     // Internal use only
     optional int32 hashCode = 10001;
@@ -319,6 +376,8 @@
     optional int32 carrier_id = 8;
     optional int64 total_time_millis = 9; // Duration needs to be rounded when pulled
     optional bool is_emergency_only = 10;
+    optional bool is_internet_pdn_up = 11;
+    optional int32 fold_state = 12;
 
     // Internal use only
     optional int64 last_used_millis = 10001;
@@ -524,3 +583,92 @@
     optional int32 xml_version = 2;
     optional int32 short_code_sms_count = 3;
 }
+
+message SatelliteController {
+    optional int32 count_of_satellite_service_enablements_success = 1;
+    optional int32 count_of_satellite_service_enablements_fail = 2;
+    optional int32 count_of_outgoing_datagram_success = 3;
+    optional int32 count_of_outgoing_datagram_fail = 4;
+    optional int32 count_of_incoming_datagram_success = 5;
+    optional int32 count_of_incoming_datagram_fail = 6;
+    optional int32 count_of_datagram_type_sos_sms_success = 7;
+    optional int32 count_of_datagram_type_sos_sms_fail = 8;
+    optional int32 count_of_datagram_type_location_sharing_success = 9;
+    optional int32 count_of_datagram_type_location_sharing_fail = 10;
+    optional int32 count_of_provision_success = 11;
+    optional int32 count_of_provision_fail = 12;
+    optional int32 count_of_deprovision_success = 13;
+    optional int32 count_of_deprovision_fail = 14;
+    optional int32 total_service_uptime_sec = 15;
+    optional int32 total_battery_consumption_percent = 16;
+    optional int32 total_battery_charged_time_sec = 17;
+}
+
+message SatelliteSession {
+    optional int32 satellite_service_initialization_result = 1;
+    optional int32 satellite_technology = 2;
+    optional int32 count = 3;
+}
+
+message SatelliteIncomingDatagram {
+    optional int32 result_code = 1;
+    optional int32 datagram_size_bytes = 2;
+    optional int64 datagram_transfer_time_millis = 3;
+}
+
+message SatelliteOutgoingDatagram {
+    optional int32 datagram_type = 1;
+    optional int32 result_code = 2;
+    optional int32 datagram_size_bytes = 3;
+    optional int64 datagram_transfer_time_millis = 4;
+}
+
+message SatelliteProvision {
+    optional int32 result_code = 1;
+    optional int32 provisioning_time_sec = 2;
+    optional bool is_provision_request = 3;
+    optional bool is_canceled = 4;
+}
+
+message SatelliteSosMessageRecommender {
+    optional bool is_display_sos_message_sent = 1;
+    optional int32 count_of_timer_started = 2;
+    optional bool is_ims_registered = 3;
+    optional int32 cellular_service_state = 4;
+    optional int32 count = 5;
+}
+
+message EmergencyNumbersInfo {
+    enum ServiceCategory {
+        EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED = 0;
+        EMERGENCY_SERVICE_CATEGORY_POLICE = 1;
+        EMERGENCY_SERVICE_CATEGORY_AMBULANCE = 2;
+        EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE = 3;
+        EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD = 4;
+        EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE = 5;
+        EMERGENCY_SERVICE_CATEGORY_MIEC = 6;
+        EMERGENCY_SERVICE_CATEGORY_AIEC = 7;
+    }
+    enum Source {
+        EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING = 0;
+        EMERGENCY_NUMBER_SOURCE_SIM = 1;
+        EMERGENCY_NUMBER_SOURCE_DATABASE = 2;
+        EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = 3;
+        EMERGENCY_NUMBER_SOURCE_DEFAULT = 4;
+    }
+    enum CallRoute {
+        EMERGENCY_CALL_ROUTE_UNKNOWN = 0;
+        EMERGENCY_CALL_ROUTE_EMERGENCY = 1;
+        EMERGENCY_CALL_ROUTE_NORMAL = 2;
+    }
+    optional bool is_db_version_ignored = 1;
+    optional int32 asset_version = 2;
+    optional int32 ota_version = 3;
+    optional string number = 4;
+    optional string country_iso = 5;
+    optional string mnc = 6;
+    optional CallRoute route = 7;
+    repeated string urns = 8;
+    repeated ServiceCategory service_categories = 9;
+    repeated Source sources = 10;
+}
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index 972884a..b8de975 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -17,6 +17,8 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
@@ -26,6 +28,7 @@
 import android.os.Registrant;
 import android.os.RegistrantList;
 import android.telephony.Annotation.RadioPowerState;
+import android.telephony.BarringInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
 
@@ -114,6 +117,17 @@
     protected RegistrantList mBarringInfoChangedRegistrants = new RegistrantList();
     protected RegistrantList mSimPhonebookChangedRegistrants = new RegistrantList();
     protected RegistrantList mSimPhonebookRecordsReceivedRegistrants = new RegistrantList();
+    protected RegistrantList mEmergencyNetworkScanRegistrants = new RegistrantList();
+    protected RegistrantList mConnectionSetupFailureRegistrants = new RegistrantList();
+    protected RegistrantList mNotifyAnbrRegistrants = new RegistrantList();
+    protected RegistrantList mTriggerImsDeregistrationRegistrants = new RegistrantList();
+    protected RegistrantList mPendingSatelliteMessageCountRegistrants = new RegistrantList();
+    protected RegistrantList mNewSatelliteMessagesRegistrants = new RegistrantList();
+    protected RegistrantList mSatelliteMessagesTransferCompleteRegistrants = new RegistrantList();
+    protected RegistrantList mSatellitePointingInfoChangedRegistrants = new RegistrantList();
+    protected RegistrantList mSatelliteModeChangedRegistrants = new RegistrantList();
+    protected RegistrantList mSatelliteRadioTechnologyChangedRegistrants = new RegistrantList();
+    protected RegistrantList mSatelliteProvisionStateChangedRegistrants = new RegistrantList();
 
     @UnsupportedAppUsage
     protected Registrant mGsmSmsRegistrant;
@@ -160,6 +174,8 @@
     // Cache last emergency number list indication from radio
     private final List<EmergencyNumber> mLastEmergencyNumberListIndication = new ArrayList<>();
 
+    // The last barring information received
+    protected BarringInfo mLastBarringInfo = new BarringInfo();
     // Preferred network type received from PhoneFactory.
     // This is used when establishing a connection to the
     // vendor ril so it starts up in the correct mode.
@@ -900,6 +916,7 @@
                     || mState == TelephonyManager.RADIO_POWER_UNAVAILABLE)
                     && (oldState == TelephonyManager.RADIO_POWER_ON)) {
                 mOffOrNotAvailRegistrants.notifyRegistrants();
+                mLastBarringInfo = new BarringInfo();
             }
         }
     }
@@ -918,6 +935,12 @@
         }
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public @NonNull BarringInfo getLastBarringInfo() {
+        return mLastBarringInfo;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1132,4 +1155,133 @@
     @Override
     public void updateSimPhonebookRecord(SimPhonebookRecord phonebookRecord, Message result) {
     }
+
+    /**
+     * Register for Emergency network scan result.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    @Override
+    public void registerForEmergencyNetworkScan(Handler h, int what, Object obj) {
+        mEmergencyNetworkScanRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregister for Emergency network scan result.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    @Override
+    public void unregisterForEmergencyNetworkScan(Handler h) {
+        mEmergencyNetworkScanRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForConnectionSetupFailure(Handler h, int what, Object obj) {
+        mConnectionSetupFailureRegistrants.addUnique(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForConnectionSetupFailure(Handler h) {
+        mConnectionSetupFailureRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForNotifyAnbr(Handler h, int what, Object obj) {
+        mNotifyAnbrRegistrants.addUnique(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForNotifyAnbr(Handler h) {
+        mNotifyAnbrRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForTriggerImsDeregistration(Handler h, int what, Object obj) {
+        mTriggerImsDeregistrationRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForTriggerImsDeregistration(Handler h) {
+        mTriggerImsDeregistrationRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForPendingSatelliteMessageCount(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mPendingSatelliteMessageCountRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForPendingSatelliteMessageCount(@NonNull Handler h) {
+        mPendingSatelliteMessageCountRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForNewSatelliteMessages(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mNewSatelliteMessagesRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForNewSatelliteMessages(@NonNull Handler h) {
+        mNewSatelliteMessagesRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForSatelliteMessagesTransferComplete(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mSatelliteMessagesTransferCompleteRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForSatelliteMessagesTransferComplete(@NonNull Handler h) {
+        mSatelliteMessagesTransferCompleteRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForSatellitePointingInfoChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mSatellitePointingInfoChangedRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForSatellitePointingInfoChanged(@NonNull Handler h) {
+        mSatellitePointingInfoChangedRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForSatelliteModeChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mSatelliteModeChangedRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForSatelliteModeChanged(@NonNull Handler h) {
+        mSatelliteModeChangedRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForSatelliteRadioTechnologyChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mSatelliteRadioTechnologyChangedRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForSatelliteRadioTechnologyChanged(@NonNull Handler h) {
+        mSatelliteRadioTechnologyChangedRegistrants.remove(h);
+    }
+
+    @Override
+    public void registerForSatelliteProvisionStateChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mSatelliteProvisionStateChangedRegistrants.add(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForSatelliteProvisionStateChanged(@NonNull Handler h) {
+        mSatelliteProvisionStateChangedRegistrants.remove(h);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/CallWaitingController.java b/src/java/com/android/internal/telephony/CallWaitingController.java
new file mode 100644
index 0000000..49940fc
--- /dev/null
+++ b/src/java/com/android/internal/telephony/CallWaitingController.java
@@ -0,0 +1,684 @@
+/*
+ * 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.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_FIRST_CHANGE;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_FIRST_POWER_UP;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_IMS_ONLY;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_NONE;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_USER_CHANGE;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsSs.SUPPLEMENTARY_SERVICE_CW;
+
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE;
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
+
+import java.io.PrintWriter;
+
+/**
+ * Controls the change of the user setting of the call waiting service
+ */
+public class CallWaitingController extends Handler {
+
+    public static final String LOG_TAG = "CallWaitingCtrl";
+    private static final boolean DBG = false; /* STOPSHIP if true */
+
+    // Terminal-based call waiting is not supported. */
+    public static final int TERMINAL_BASED_NOT_SUPPORTED = -1;
+    // Terminal-based call waiting is supported but not activated. */
+    public static final int TERMINAL_BASED_NOT_ACTIVATED = 0;
+    // Terminal-based call waiting is supported and activated. */
+    public static final int TERMINAL_BASED_ACTIVATED = 1;
+
+    private static final int EVENT_SET_CALL_WAITING_DONE = 1;
+    private static final int EVENT_GET_CALL_WAITING_DONE = 2;
+    private static final int EVENT_REGISTERED_TO_NETWORK = 3;
+
+    // Class to pack mOnComplete object passed by the caller
+    private static class Cw {
+        final boolean mEnable;
+        final Message mOnComplete;
+        final boolean mImsRegistered;
+
+        Cw(boolean enable, boolean imsRegistered, Message onComplete) {
+            mEnable = enable;
+            mOnComplete = onComplete;
+            mImsRegistered = imsRegistered;
+        }
+    }
+
+    @VisibleForTesting
+    public static final String PREFERENCE_TBCW = "terminal_based_call_waiting";
+    @VisibleForTesting
+    public static final String KEY_SUB_ID = "subId";
+    @VisibleForTesting
+    public static final String KEY_STATE = "state";
+    @VisibleForTesting
+    public static final String KEY_CS_SYNC = "cs_sync";
+
+    private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            (slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigurationChanged(
+                    slotIndex);
+
+    private boolean mSupportedByImsService = false;
+    private boolean mValidSubscription = false;
+
+    // The user's last setting of terminal-based call waiting
+    private int mCallWaitingState = TERMINAL_BASED_NOT_SUPPORTED;
+
+    private int mSyncPreference = CALL_WAITING_SYNC_NONE;
+    private int mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+    private boolean mCsEnabled = false;
+    private boolean mRegisteredForNetworkAttach = false;
+    private boolean mImsRegistered = false;
+
+    private final GsmCdmaPhone mPhone;
+    private final ServiceStateTracker mSST;
+    private final Context mContext;
+
+    // Constructors
+    public CallWaitingController(GsmCdmaPhone phone) {
+        mPhone = phone;
+        mSST = phone.getServiceStateTracker();
+        mContext = phone.getContext();
+    }
+
+    private void initialize() {
+        CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
+        if (ccm != null) {
+            // Callback directly handle carrier config change should be executed in handler thread
+            ccm.registerCarrierConfigChangeListener(this::post, mCarrierConfigChangeListener);
+        } else {
+            loge("CarrierConfigLoader is not available.");
+        }
+
+        int phoneId = mPhone.getPhoneId();
+        int subId = mPhone.getSubId();
+        SharedPreferences sp =
+                mContext.getSharedPreferences(PREFERENCE_TBCW, Context.MODE_PRIVATE);
+        mLastSubId = sp.getInt(KEY_SUB_ID + phoneId, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mCallWaitingState = sp.getInt(KEY_STATE + subId, TERMINAL_BASED_NOT_SUPPORTED);
+        mSyncPreference = sp.getInt(KEY_CS_SYNC + phoneId, CALL_WAITING_SYNC_NONE);
+
+        logi("initialize phoneId=" + phoneId
+                + ", lastSubId=" + mLastSubId + ", subId=" + subId
+                + ", state=" + mCallWaitingState + ", sync=" + mSyncPreference
+                + ", csEnabled=" + mCsEnabled);
+    }
+
+    /**
+     * Returns the cached user setting.
+     *
+     * Possible values are
+     * {@link #TERMINAL_BASED_NOT_SUPPORTED},
+     * {@link #TERMINAL_BASED_NOT_ACTIVATED}, and
+     * {@link #TERMINAL_BASED_ACTIVATED}.
+     *
+     * @param forCsOnly indicates the caller expects the result for CS calls only
+     */
+    @VisibleForTesting
+    public synchronized int getTerminalBasedCallWaitingState(boolean forCsOnly) {
+        if (forCsOnly && (!mImsRegistered) && mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY) {
+            return TERMINAL_BASED_NOT_SUPPORTED;
+        }
+        if (!mValidSubscription) return TERMINAL_BASED_NOT_SUPPORTED;
+        return mCallWaitingState;
+    }
+
+    /**
+     * Serves the user's requests to interrogate the call waiting service
+     *
+     * @return true when terminal-based call waiting is supported, otherwise false
+     */
+    @VisibleForTesting
+    public synchronized boolean getCallWaiting(@Nullable Message onComplete) {
+        if (mCallWaitingState == TERMINAL_BASED_NOT_SUPPORTED) return false;
+
+        logi("getCallWaiting " + mCallWaitingState);
+
+        if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+            // Interrogate CW in CS network
+            if (!mCsEnabled) {
+                // skip interrogation if CS is not available and IMS is registered
+                if (isCircuitSwitchedNetworkAvailable() || !isImsRegistered()) {
+                    Cw cw = new Cw(false, isImsRegistered(), onComplete);
+                    Message resp = obtainMessage(EVENT_GET_CALL_WAITING_DONE, 0, 0, cw);
+                    mPhone.mCi.queryCallWaiting(SERVICE_CLASS_NONE, resp);
+                    return true;
+                }
+            }
+        }
+
+        if (mSyncPreference == CALL_WAITING_SYNC_NONE
+                || mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE
+                || mSyncPreference == CALL_WAITING_SYNC_FIRST_POWER_UP
+                || isSyncImsOnly()) {
+            sendGetCallWaitingResponse(onComplete);
+            return true;
+        } else if (mSyncPreference == CALL_WAITING_SYNC_USER_CHANGE
+                || mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY) {
+            Cw cw = new Cw(false, isImsRegistered(), onComplete);
+            Message resp = obtainMessage(EVENT_GET_CALL_WAITING_DONE, 0, 0, cw);
+            mPhone.mCi.queryCallWaiting(SERVICE_CLASS_NONE, resp);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Serves the user's requests to set the call waiting service
+     *
+     * @param serviceClass the target service class. Values are CommandsInterface.SERVICE_CLASS_*.
+     * @return true when terminal-based call waiting is supported, otherwise false
+     */
+    @VisibleForTesting
+    public synchronized boolean setCallWaiting(boolean enable,
+            int serviceClass, @Nullable Message onComplete) {
+        if (mCallWaitingState == TERMINAL_BASED_NOT_SUPPORTED) return false;
+
+        if ((serviceClass & SERVICE_CLASS_VOICE) != SERVICE_CLASS_VOICE) return false;
+
+        logi("setCallWaiting enable=" + enable + ", service=" + serviceClass);
+
+        if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+            // Enable CW in the CS network
+            if (!mCsEnabled && enable) {
+                if (isCircuitSwitchedNetworkAvailable() || !isImsRegistered()) {
+                    Cw cw = new Cw(true, isImsRegistered(), onComplete);
+                    Message resp = obtainMessage(EVENT_SET_CALL_WAITING_DONE, 0, 0, cw);
+                    mPhone.mCi.setCallWaiting(true, serviceClass, resp);
+                    return true;
+                } else {
+                    // CS network is not available, however, IMS is registered.
+                    // Enabling the service in the CS network will be delayed.
+                    registerForNetworkAttached();
+                }
+            }
+        }
+
+        if (mSyncPreference == CALL_WAITING_SYNC_NONE
+                || mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE
+                || mSyncPreference == CALL_WAITING_SYNC_FIRST_POWER_UP
+                || isSyncImsOnly()) {
+            updateState(
+                    enable ? TERMINAL_BASED_ACTIVATED : TERMINAL_BASED_NOT_ACTIVATED);
+
+            sendToTarget(onComplete, null, null);
+            return true;
+        } else if (mSyncPreference == CALL_WAITING_SYNC_USER_CHANGE
+                || mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY) {
+            Cw cw = new Cw(enable, isImsRegistered(), onComplete);
+            Message resp = obtainMessage(EVENT_SET_CALL_WAITING_DONE, 0, 0, cw);
+            mPhone.mCi.setCallWaiting(enable, serviceClass, resp);
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case EVENT_SET_CALL_WAITING_DONE:
+                onSetCallWaitingDone((AsyncResult) msg.obj);
+                break;
+            case EVENT_GET_CALL_WAITING_DONE:
+                onGetCallWaitingDone((AsyncResult) msg.obj);
+                break;
+            case EVENT_REGISTERED_TO_NETWORK:
+                onRegisteredToNetwork();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private synchronized void onSetCallWaitingDone(AsyncResult ar) {
+        if (ar.userObj == null) {
+            // For the case, CALL_WAITING_SYNC_FIRST_POWER_UP
+            if (DBG) logd("onSetCallWaitingDone to sync on network attached");
+            if (ar.exception == null) {
+                updateSyncState(true);
+            } else {
+                loge("onSetCallWaitingDone e=" + ar.exception);
+            }
+            return;
+        }
+
+        if (!(ar.userObj instanceof Cw)) {
+            // Unexpected state
+            if (DBG) logd("onSetCallWaitingDone unexpected result");
+            return;
+        }
+
+        if (DBG) logd("onSetCallWaitingDone");
+        Cw cw = (Cw) ar.userObj;
+
+        if (mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY) {
+            // do not synchronize service state between CS and IMS
+            sendToTarget(cw.mOnComplete, ar.result, ar.exception);
+            return;
+        }
+
+        if (ar.exception == null) {
+            if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+                // SYNC_FIRST_CHANGE implies cw.mEnable is true.
+                updateSyncState(true);
+            }
+            updateState(
+                    cw.mEnable ? TERMINAL_BASED_ACTIVATED : TERMINAL_BASED_NOT_ACTIVATED);
+        } else if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+            if (cw.mImsRegistered) {
+                // IMS is registered. Do not notify error.
+                // SYNC_FIRST_CHANGE implies cw.mEnable is true.
+                updateState(TERMINAL_BASED_ACTIVATED);
+                sendToTarget(cw.mOnComplete, null, null);
+                return;
+            }
+        }
+        sendToTarget(cw.mOnComplete, ar.result, ar.exception);
+    }
+
+    private synchronized void onGetCallWaitingDone(AsyncResult ar) {
+        if (ar.userObj == null) {
+            // For the case, CALL_WAITING_SYNC_FIRST_POWER_UP
+            if (DBG) logd("onGetCallWaitingDone to sync on network attached");
+            boolean enabled = false;
+            if (ar.exception == null) {
+                //resp[0]: 1 if enabled, 0 otherwise
+                //resp[1]: bitwise ORs of SERVICE_CLASS_* constants
+                int[] resp = (int[]) ar.result;
+                if (resp != null && resp.length > 1) {
+                    enabled = (resp[0] == 1)
+                            && (resp[1] & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE;
+                } else {
+                    loge("onGetCallWaitingDone unexpected response");
+                }
+            } else {
+                loge("onGetCallWaitingDone e=" + ar.exception);
+            }
+            if (enabled) {
+                updateSyncState(true);
+            } else {
+                logi("onGetCallWaitingDone enabling CW service in CS network");
+                mPhone.mCi.setCallWaiting(true, SERVICE_CLASS_VOICE,
+                        obtainMessage(EVENT_SET_CALL_WAITING_DONE));
+            }
+            unregisterForNetworkAttached();
+            return;
+        }
+
+        if (!(ar.userObj instanceof Cw)) {
+            // Unexpected state
+            if (DBG) logd("onGetCallWaitingDone unexpected result");
+            return;
+        }
+
+        if (DBG) logd("onGetCallWaitingDone");
+        Cw cw = (Cw) ar.userObj;
+
+        if (mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY) {
+            // do not synchronize service state between CS and IMS
+            sendToTarget(cw.mOnComplete, ar.result, ar.exception);
+            return;
+        }
+
+        if (ar.exception == null) {
+            int[] resp = (int[]) ar.result;
+            //resp[0]: 1 if enabled, 0 otherwise
+            //resp[1]: bitwise ORs of SERVICE_CLASS_
+            if (resp == null || resp.length < 2) {
+                logi("onGetCallWaitingDone unexpected response");
+                if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+                    // no exception but unexpected response, local setting is preferred.
+                    sendGetCallWaitingResponse(cw.mOnComplete);
+                } else {
+                    sendToTarget(cw.mOnComplete, ar.result, ar.exception);
+                }
+                return;
+            }
+
+            boolean enabled = resp[0] == 1
+                    && (resp[1] & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE;
+
+            if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+                updateSyncState(enabled);
+
+                if (!enabled && !cw.mImsRegistered) {
+                    // IMS is not registered, change the local setting
+                    logi("onGetCallWaitingDone CW in CS network is disabled.");
+                    updateState(TERMINAL_BASED_NOT_ACTIVATED);
+                }
+
+                // return the user setting saved
+                sendGetCallWaitingResponse(cw.mOnComplete);
+                return;
+            }
+            updateState(enabled ? TERMINAL_BASED_ACTIVATED : TERMINAL_BASED_NOT_ACTIVATED);
+        } else if (mSyncPreference == CALL_WAITING_SYNC_FIRST_CHANGE) {
+            // Got an exception
+            if (cw.mImsRegistered) {
+                // queryCallWaiting failed. However, IMS is registered. Do not notify error.
+                // return the user setting saved
+                logi("onGetCallWaitingDone get an exception, but IMS is registered");
+                sendGetCallWaitingResponse(cw.mOnComplete);
+                return;
+            }
+        }
+        sendToTarget(cw.mOnComplete, ar.result, ar.exception);
+    }
+
+    private void sendToTarget(Message onComplete, Object result, Throwable exception) {
+        if (onComplete != null) {
+            AsyncResult.forMessage(onComplete, result, exception);
+            onComplete.sendToTarget();
+        }
+    }
+
+    private void sendGetCallWaitingResponse(Message onComplete) {
+        if (onComplete != null) {
+            int serviceClass = SERVICE_CLASS_NONE;
+            if (mCallWaitingState == TERMINAL_BASED_ACTIVATED) {
+                serviceClass = SERVICE_CLASS_VOICE;
+            }
+            sendToTarget(onComplete, new int[] { mCallWaitingState, serviceClass }, null);
+        }
+    }
+
+    private synchronized void onRegisteredToNetwork() {
+        if (mCsEnabled) return;
+
+        if (DBG) logd("onRegisteredToNetwork");
+
+        mPhone.mCi.queryCallWaiting(SERVICE_CLASS_NONE,
+                obtainMessage(EVENT_GET_CALL_WAITING_DONE));
+    }
+
+    private synchronized void onCarrierConfigurationChanged(int slotIndex) {
+        if (slotIndex != mPhone.getPhoneId()) return;
+
+        int subId = mPhone.getSubId();
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            logi("onCarrierConfigChanged invalid subId=" + subId);
+
+            mValidSubscription = false;
+            unregisterForNetworkAttached();
+            return;
+        }
+
+        if (!updateCarrierConfig(subId, false /* ignoreSavedState */)) {
+            return;
+        }
+
+        logi("onCarrierConfigChanged cs_enabled=" + mCsEnabled);
+
+        if (mSyncPreference == CALL_WAITING_SYNC_FIRST_POWER_UP) {
+            if (!mCsEnabled) {
+                registerForNetworkAttached();
+            }
+        }
+    }
+
+    /**
+     * @param ignoreSavedState only used for test
+     * @return true when succeeded.
+     */
+    @VisibleForTesting
+    public boolean updateCarrierConfig(int subId, boolean ignoreSavedState) {
+        mValidSubscription = true;
+
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mContext,
+                        subId,
+                        KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY,
+                        KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT,
+                        KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL);
+        if (b.isEmpty()) return false;
+
+        boolean supportsTerminalBased = false;
+        int[] services = b.getIntArray(KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY);
+        if (services != null) {
+            for (int service : services) {
+                if (service == SUPPLEMENTARY_SERVICE_CW) {
+                    supportsTerminalBased = true;
+                }
+            }
+        }
+        int syncPreference = b.getInt(KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT,
+                CALL_WAITING_SYNC_FIRST_CHANGE);
+        boolean activated = b.getBoolean(KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL);
+        int defaultState = supportsTerminalBased
+                ? (activated ? TERMINAL_BASED_ACTIVATED : TERMINAL_BASED_NOT_ACTIVATED)
+                : TERMINAL_BASED_NOT_SUPPORTED;
+        int savedState = getSavedState(subId);
+
+        if (DBG) {
+            logd("updateCarrierConfig phoneId=" + mPhone.getPhoneId()
+                    + ", subId=" + subId + ", support=" + supportsTerminalBased
+                    + ", sync=" + syncPreference + ", default=" + defaultState
+                    + ", savedState=" + savedState);
+        }
+
+        int desiredState = savedState;
+
+        if (ignoreSavedState) {
+            desiredState = defaultState;
+        } else if ((mLastSubId != subId)
+                && (syncPreference == CALL_WAITING_SYNC_FIRST_POWER_UP
+                        || syncPreference == CALL_WAITING_SYNC_FIRST_CHANGE)) {
+            desiredState = defaultState;
+        } else {
+            if (defaultState == TERMINAL_BASED_NOT_SUPPORTED) {
+                desiredState = TERMINAL_BASED_NOT_SUPPORTED;
+            } else if (savedState == TERMINAL_BASED_NOT_SUPPORTED) {
+                desiredState = defaultState;
+            }
+        }
+
+        updateState(desiredState, syncPreference, ignoreSavedState);
+        return true;
+    }
+
+    private void updateState(int state) {
+        updateState(state, mSyncPreference, false);
+    }
+
+    private void updateState(int state, int syncPreference, boolean ignoreSavedState) {
+        int subId = mPhone.getSubId();
+
+        if (mLastSubId == subId
+                && mCallWaitingState == state
+                && mSyncPreference == syncPreference
+                && (!ignoreSavedState)) {
+            return;
+        }
+
+        int phoneId = mPhone.getPhoneId();
+
+        logi("updateState phoneId=" + phoneId
+                + ", subId=" + subId + ", state=" + state
+                + ", sync=" + syncPreference + ", ignoreSavedState=" + ignoreSavedState);
+
+        SharedPreferences sp =
+                mContext.getSharedPreferences(PREFERENCE_TBCW, Context.MODE_PRIVATE);
+
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putInt(KEY_SUB_ID + phoneId, subId);
+        editor.putInt(KEY_STATE + subId, state);
+        editor.putInt(KEY_CS_SYNC + phoneId, syncPreference);
+        editor.apply();
+
+        mCallWaitingState = state;
+        mLastSubId = subId;
+        mSyncPreference = syncPreference;
+        if (mLastSubId != subId) {
+            mCsEnabled = false;
+        }
+
+        mPhone.setTerminalBasedCallWaitingStatus(mCallWaitingState);
+    }
+
+    private int getSavedState(int subId) {
+        SharedPreferences sp =
+                mContext.getSharedPreferences(PREFERENCE_TBCW, Context.MODE_PRIVATE);
+        int state = sp.getInt(KEY_STATE + subId, TERMINAL_BASED_NOT_SUPPORTED);
+
+        logi("getSavedState subId=" + subId + ", state=" + state);
+
+        return state;
+    }
+
+    private void updateSyncState(boolean enabled) {
+        int phoneId = mPhone.getPhoneId();
+
+        logi("updateSyncState phoneId=" + phoneId + ", enabled=" + enabled);
+
+        mCsEnabled = enabled;
+    }
+
+    /**
+     * @return whether the service is enabled in the CS network
+     */
+    @VisibleForTesting
+    public boolean getSyncState() {
+        return mCsEnabled;
+    }
+
+    private boolean isCircuitSwitchedNetworkAvailable() {
+        logi("isCircuitSwitchedNetworkAvailable="
+                + (mSST.getServiceState().getState() == ServiceState.STATE_IN_SERVICE));
+        return mSST.getServiceState().getState() == ServiceState.STATE_IN_SERVICE;
+    }
+
+    private boolean isImsRegistered() {
+        logi("isImsRegistered " + mImsRegistered);
+        return mImsRegistered;
+    }
+
+    /**
+     * Sets the registration state of IMS service.
+     */
+    public synchronized void setImsRegistrationState(boolean registered) {
+        logi("setImsRegistrationState prev=" + mImsRegistered
+                + ", new=" + registered);
+        mImsRegistered = registered;
+    }
+
+    private void registerForNetworkAttached() {
+        logi("registerForNetworkAttached");
+        if (mRegisteredForNetworkAttach) return;
+
+        mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
+        mRegisteredForNetworkAttach = true;
+    }
+
+    private void unregisterForNetworkAttached() {
+        logi("unregisterForNetworkAttached");
+        if (!mRegisteredForNetworkAttach) return;
+
+        mSST.unregisterForNetworkAttached(this);
+        removeMessages(EVENT_REGISTERED_TO_NETWORK);
+        mRegisteredForNetworkAttach = false;
+    }
+
+    /**
+     * Sets whether the device supports the terminal-based call waiting.
+     * Only for test
+     */
+    @VisibleForTesting
+    public synchronized void setTerminalBasedCallWaitingSupported(boolean supported) {
+        if (mSupportedByImsService == supported) return;
+
+        logi("setTerminalBasedCallWaitingSupported " + supported);
+
+        mSupportedByImsService = supported;
+
+        if (supported) {
+            initialize();
+            onCarrierConfigurationChanged(mPhone.getPhoneId());
+        } else {
+            CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
+            if (ccm != null && mCarrierConfigChangeListener != null) {
+                ccm.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+            }
+            updateState(TERMINAL_BASED_NOT_SUPPORTED);
+        }
+    }
+
+    /**
+     * Notifies that the UE has attached to the network
+     * Only for test
+     */
+    @VisibleForTesting
+    public void notifyRegisteredToNetwork() {
+        sendEmptyMessage(EVENT_REGISTERED_TO_NETWORK);
+    }
+
+    private boolean isSyncImsOnly() {
+        return (mSyncPreference == CALL_WAITING_SYNC_IMS_ONLY && mImsRegistered);
+    }
+
+    /**
+     * Dump this instance into a readable format for dumpsys usage.
+     */
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.increaseIndent();
+        pw.println("CallWaitingController:");
+        pw.println(" mSupportedByImsService=" + mSupportedByImsService);
+        pw.println(" mValidSubscription=" + mValidSubscription);
+        pw.println(" mCallWaitingState=" + mCallWaitingState);
+        pw.println(" mSyncPreference=" + mSyncPreference);
+        pw.println(" mLastSubId=" + mLastSubId);
+        pw.println(" mCsEnabled=" + mCsEnabled);
+        pw.println(" mRegisteredForNetworkAttach=" + mRegisteredForNetworkAttach);
+        pw.println(" mImsRegistered=" + mImsRegistered);
+        pw.decreaseIndent();
+    }
+
+    private void loge(String msg) {
+        Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
+    }
+
+    private void logi(String msg) {
+        Rlog.i(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
+    }
+
+    private void logd(String msg) {
+        Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + msg);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/CarrierInfoManager.java b/src/java/com/android/internal/telephony/CarrierInfoManager.java
index 3e2baa5..863db93 100644
--- a/src/java/com/android/internal/telephony/CarrierInfoManager.java
+++ b/src/java/com/android/internal/telephony/CarrierInfoManager.java
@@ -287,16 +287,17 @@
             return;
         }
         mLastAccessResetCarrierKey = now;
-        int[] subIds = context.getSystemService(SubscriptionManager.class)
-                .getSubscriptionIds(mPhoneId);
-        if (subIds == null || subIds.length < 1) {
+
+        int subId = SubscriptionManager.getSubscriptionId(mPhoneId);
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             Log.e(LOG_TAG, "Could not reset carrier keys, subscription for mPhoneId=" + mPhoneId);
             return;
         }
+
         final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(subIds[0]);
+                .createForSubscriptionId(subId);
         int carrierId = telephonyManager.getSimCarrierId();
-        deleteCarrierInfoForImsiEncryption(context, subIds[0], carrierId);
+        deleteCarrierInfoForImsiEncryption(context, subId, carrierId);
         Intent resetIntent = new Intent(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
         SubscriptionManager.putPhoneIdAndSubIdExtra(resetIntent, mPhoneId);
         context.sendBroadcastAsUser(resetIntent, UserHandle.ALL);
diff --git a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
index edf3d5f..beb6b26 100644
--- a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
+++ b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.CarrierConfigManager.KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL;
-
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import android.app.AlarmManager;
@@ -32,7 +30,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;
@@ -122,13 +119,22 @@
         mPhone = phone;
         mContext = phone.getContext();
         IntentFilter filter = new IntentFilter();
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(INTENT_KEY_RENEWAL_ALARM_PREFIX);
         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());
+        CarrierConfigManager carrierConfigManager = mContext.getSystemService(
+                CarrierConfigManager.class);
+        // Callback which directly handle config change should be executed on handler thread
+        carrierConfigManager.registerCarrierConfigChangeListener(this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) -> {
+                    if (slotIndex == mPhone.getPhoneId()) {
+                        Log.d(LOG_TAG, "Carrier Config changed: slotIndex=" + slotIndex);
+                        handleAlarmOrConfigChange();
+                    }
+                });
     }
 
     private final BroadcastReceiver mDownloadReceiver = new BroadcastReceiver() {
@@ -161,12 +167,6 @@
                     Log.d(LOG_TAG, "Handling reset intent: " + action);
                     sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
                 }
-            } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                if (phoneId == intent.getIntExtra(PhoneConstants.PHONE_KEY,
-                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
-                    Log.d(LOG_TAG, "Carrier Config changed: " + action);
-                    sendEmptyMessage(EVENT_ALARM_OR_CONFIG_CHANGE);
-                }
             }
         }
     };
@@ -389,14 +389,23 @@
             return false;
         }
         int subId = mPhone.getSubId();
-        PersistableBundle b = carrierConfigManager.getConfigForSubId(subId);
-        if (b == null) {
+        PersistableBundle b = null;
+        try {
+            b = carrierConfigManager.getConfigForSubId(subId,
+                    CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT,
+                    CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING,
+                    CarrierConfigManager.KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL);
+        } catch (RuntimeException e) {
+            Log.e(LOG_TAG, "CarrierConfigLoader is not available.");
+        }
+        if (b == null || b.isEmpty()) {
             return false;
         }
+
         mKeyAvailability = b.getInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT);
         mURL = b.getString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING);
         mAllowedOverMeteredNetwork = b.getBoolean(
-                KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL);
+                CarrierConfigManager.KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL);
         if (mKeyAvailability == 0 || TextUtils.isEmpty(mURL)) {
             Log.d(LOG_TAG,
                     "Carrier not enabled or invalid values. mKeyAvailability=" + mKeyAvailability
diff --git a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index b394820..ab7ebc4 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -16,11 +16,8 @@
 
 package com.android.internal.telephony;
 
-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.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;
@@ -52,8 +49,6 @@
 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;
@@ -67,7 +62,6 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.IntArray;
 import android.util.LocalLog;
 import android.util.Pair;
 
@@ -84,6 +78,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -109,6 +104,7 @@
     private static final int PACKAGE_NOT_PRIVILEGED = 0;
     private static final int PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG = 1;
     private static final int PACKAGE_PRIVILEGED_FROM_SIM = 2;
+    private static final int PACKAGE_PRIVILEGED_FROM_CARRIER_SERVICE_TEST_OVERRIDE = 3;
 
     // TODO(b/232273884): Turn feature on when find solution to handle the inter-carriers switching
     /**
@@ -131,25 +127,6 @@
                     | 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.
-     */
-    private static final int ACTION_REGISTER_LISTENER = 1;
-
-    /**
-     * Action to unregister a Registrant with this Tracker.
-     * obj: Handler used by the Registrant that will be removed.
-     */
-    private static final int ACTION_UNREGISTER_LISTENER = 2;
-
-    /**
-     * Action for tracking when Carrier Configs are updated.
-     * arg1: Subscription Id for the Carrier Configs update being broadcast
-     * arg2: Slot Index for the Carrier Configs update being broadcast
-     */
-    private static final int ACTION_CARRIER_CONFIG_CERTS_UPDATED = 3;
-
-    /**
      * Action for tracking when the Phone's SIM state changes.
      * arg1: slotId that this Action applies to
      * arg2: simState reported by this Broadcast
@@ -190,6 +167,14 @@
      */
     private static final int ACTION_UICC_ACCESS_RULES_LOADED = 10;
 
+    /**
+     * Action to set the test override rule through {@link
+     * TelephonyManager#setCarrierServicePackageOverride}.
+     *
+     * <p>obj: String of the carrierServicePackage from method setCarrierServicePackageOverride.
+     */
+    private static final int ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE = 11;
+
     private final Context mContext;
     private final Phone mPhone;
     private final PackageManager mPackageManager;
@@ -199,7 +184,6 @@
     private final TelephonyRegistryManager mTelephonyRegistryManager;
 
     @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<>();
     // Stores rules for SIM-loaded rules.
@@ -209,6 +193,7 @@
     // - 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;
+    @Nullable private String mTestOverrideCarrierServicePackage = null;
     // Map of PackageName -> Certificate hashes for that Package
     @NonNull private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>();
     // Map of PackageName -> UIDs for that Package
@@ -298,19 +283,6 @@
                     if (action == null) return;
 
                     switch (action) {
-                        case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: {
-                            Bundle extras = intent.getExtras();
-                            int slotIndex = extras.getInt(EXTRA_SLOT_INDEX);
-                            int subId =
-                                    extras.getInt(
-                                            EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID);
-                            sendMessage(
-                                    obtainMessage(
-                                            ACTION_CARRIER_CONFIG_CERTS_UPDATED,
-                                            subId,
-                                            slotIndex));
-                            break;
-                        }
                         case TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED: // fall through
                         case TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED: {
                             Bundle extras = intent.getExtras();
@@ -373,13 +345,16 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mCarrierConfigManager =
                 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        // Callback is executed in handler thread and directly handles carrier config update
+        mCarrierConfigManager.registerCarrierConfigChangeListener(this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) -> handleCarrierConfigUpdated(
+                        subId, slotIndex));
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         mTelephonyRegistryManager =
                 (TelephonyRegistryManager)
                         mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
 
         IntentFilter certFilter = new IntentFilter();
-        certFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         certFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
         certFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
         mContext.registerReceiver(mIntentReceiver, certFilter);
@@ -401,20 +376,6 @@
     @Override
     public void handleMessage(Message msg) {
         switch (msg.what) {
-            case ACTION_REGISTER_LISTENER: {
-                handleRegisterListener((Registrant) msg.obj);
-                break;
-            }
-            case ACTION_UNREGISTER_LISTENER: {
-                handleUnregisterListener((Handler) msg.obj);
-                break;
-            }
-            case ACTION_CARRIER_CONFIG_CERTS_UPDATED: {
-                int subId = msg.arg1;
-                int slotIndex = msg.arg2;
-                handleCarrierConfigUpdated(subId, slotIndex);
-                break;
-            }
             case ACTION_SIM_STATE_UPDATED: {
                 handleSimStateChanged(msg.arg1, msg.arg2);
                 break;
@@ -446,6 +407,11 @@
                 handleUiccAccessRulesLoaded();
                 break;
             }
+            case ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE: {
+                String carrierServicePackage = (String) msg.obj;
+                handleSetTestOverrideCarrierServicePackage(carrierServicePackage);
+                break;
+            }
             default: {
                 Rlog.e(TAG, "Received unknown msg type: " + msg.what);
                 break;
@@ -453,23 +419,6 @@
         }
     }
 
-    private void handleRegisterListener(@NonNull 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();
-        }
-    }
-
-    private void handleUnregisterListener(@NonNull Handler handler) {
-        mRegistrantList.remove(handler);
-    }
-
     private void handleCarrierConfigUpdated(int subId, int slotIndex) {
         if (slotIndex != mPhone.getPhoneId()) return;
 
@@ -491,7 +440,10 @@
 
     @NonNull
     private List<UiccAccessRule> getCarrierConfigRules(int subId) {
-        PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
+        PersistableBundle carrierConfigs =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mContext, subId, KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
+        // CarrierConfigManager#isConfigForIdentifiedCarrier can handle null or empty bundle
         if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
             return Collections.EMPTY_LIST;
         }
@@ -612,10 +564,10 @@
         List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
         for (Signature signature : signatures) {
             byte[] sha1 = UiccAccessRule.getCertHash(signature, SHA_1);
-            certs.add(IccUtils.bytesToHexString(sha1).toUpperCase());
+            certs.add(IccUtils.bytesToHexString(sha1).toUpperCase(Locale.ROOT));
 
             byte[] sha256 = UiccAccessRule.getCertHash(signature, SHA_256);
-            certs.add(IccUtils.bytesToHexString(sha256).toUpperCase());
+            certs.add(IccUtils.bytesToHexString(sha256).toUpperCase(Locale.ROOT));
         }
 
         mInstalledPackageCerts.put(pkg.packageName, certs);
@@ -729,12 +681,6 @@
 
         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(),
@@ -766,6 +712,7 @@
             final int priv = getPackagePrivilegedStatus(e.getKey(), e.getValue());
             switch (priv) {
                 case PACKAGE_PRIVILEGED_FROM_SIM:
+                case PACKAGE_PRIVILEGED_FROM_CARRIER_SERVICE_TEST_OVERRIDE: // fallthrough
                     carrierServiceEligiblePackages.add(e.getKey());
                     // fallthrough
                 case PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG:
@@ -807,7 +754,9 @@
                 }
                 for (UiccAccessRule rule : mCarrierConfigRules) {
                     if (rule.matches(cert, pkgName)) {
-                        return PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG;
+                        return pkgName.equals(mTestOverrideCarrierServicePackage)
+                                ? PACKAGE_PRIVILEGED_FROM_CARRIER_SERVICE_TEST_OVERRIDE
+                                : PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG;
                     }
                 }
             }
@@ -880,33 +829,6 @@
     }
 
     /**
-     * Registers the given Registrant with this tracker.
-     *
-     * <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) {
-        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) {
-        sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler));
-    }
-
-    /**
      * Set test carrier privilege rules which will override the actual rules on both Carrier Config
      * and SIM.
      *
@@ -919,6 +841,30 @@
         sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
     }
 
+    /**
+     * Override the carrier provisioning package, if it exists.
+     *
+     * <p>This API is to be used ONLY for testing, and requires the provided package to be carrier
+     * privileged. While this override is set, ONLY the specified package will be considered
+     * eligible to be bound as the carrier provisioning package, and any existing bindings will be
+     * terminated.
+     *
+     * @param carrierServicePackage the package to be used as the overridden carrier service
+     *     package, or {@code null} to reset override
+     * @see TelephonyManager#setCarrierServicePackageOverride
+     */
+    public void setTestOverrideCarrierServicePackage(@Nullable String carrierServicePackage) {
+        sendMessage(obtainMessage(
+                ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE, carrierServicePackage));
+    }
+
+    private void handleSetTestOverrideCarrierServicePackage(
+            @Nullable String carrierServicePackage) {
+        mTestOverrideCarrierServicePackage = carrierServicePackage;
+        refreshInstalledPackageCache();
+        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
+    }
+
     private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) {
         if (carrierPrivilegeRules == null) {
             mTestOverrideRules = null;
@@ -1087,6 +1033,11 @@
         String carrierServicePackageName = null;
         for (ResolveInfo resolveInfo : carrierServiceResolveInfos) {
             String packageName = getPackageName(resolveInfo);
+            if (mTestOverrideCarrierServicePackage != null
+                    && !mTestOverrideCarrierServicePackage.equals(packageName)) {
+                continue;
+            }
+
             if (simPrivilegedPackages.contains(packageName)) {
                 carrierServicePackageName = packageName;
                 break;
@@ -1096,11 +1047,4 @@
                 ? 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 c80251e..8a9b3e3 100644
--- a/src/java/com/android/internal/telephony/CarrierResolver.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * CarrierResolver identifies the subscription carrier and returns a canonical carrier Id
@@ -192,14 +193,14 @@
     }
 
     /**
-     * This is triggered from SubscriptionInfoUpdater after sim state change.
+     * This is triggered from UiccController after sim state change.
      * The sequence of sim loading would be
      *  1. OnSubscriptionsChangedListener
      *  2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED
      *  /ACTION_SIM_APPLICATION_STATE_CHANGED
      *  3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED
      *
-     *  For SIM refresh either reset or init refresh type, SubscriptionInfoUpdater will re-trigger
+     *  For SIM refresh either reset or init refresh type, UiccController will re-trigger
      *  carrier identification with sim loaded state. Framework today silently handle single file
      *  refresh type.
      *  TODO: check fileId from single file refresh, if the refresh file is IMSI, gid1 or other
@@ -548,12 +549,7 @@
         // subscriptioninfo db to make sure we have correct carrier id set.
         if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId()) && !isSimOverride) {
             // only persist carrier id to simInfo db when subId is valid.
-            if (mPhone.isSubscriptionManagerServiceEnabled()) {
-                SubscriptionManagerService.getInstance().setCarrierId(mPhone.getSubId(),
-                        mCarrierId);
-            } else {
-                SubscriptionController.getInstance().setCarrierId(mCarrierId, mPhone.getSubId());
-            }
+            SubscriptionManagerService.getInstance().setCarrierId(mPhone.getSubId(), mCarrierId);
         }
     }
 
@@ -757,7 +753,8 @@
         // Ideally we should do full string match. However due to SIM manufacture issues
         // gid from some SIM might has garbage tail.
         private boolean gidMatch(String gidFromSim, String gid) {
-            return (gidFromSim != null) && gidFromSim.toLowerCase().startsWith(gid.toLowerCase());
+            return (gidFromSim != null) && gidFromSim.toLowerCase(Locale.ROOT)
+                    .startsWith(gid.toLowerCase(Locale.ROOT));
         }
 
         private boolean carrierPrivilegeRulesMatch(List<String> certsFromSubscription,
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
index 6c6db96..6b44998 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -19,10 +19,8 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.os.Handler;
 import android.os.HandlerExecutor;
@@ -102,8 +100,34 @@
         this.mSST = sst;
         mTelephonyManager = mPhone.getContext().getSystemService(
                 TelephonyManager.class).createForSubscriptionId(mPhone.getSubId());
-        phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
-                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        ccm.registerCarrierConfigChangeListener(
+                mPhone.getContext().getMainExecutor(),
+                (slotIndex, subId, carrierId, specificCarrierId) -> {
+                    if (slotIndex != mPhone.getPhoneId()) return;
+
+                    Rlog.d(LOG_TAG, "onCarrierConfigChanged: slotIndex=" + slotIndex
+                            + ", subId=" + subId + ", carrierId=" + carrierId);
+
+                    // Only get carrier configs used for EmergencyNetworkNotification
+                    // and PrefNetworkNotification
+                    PersistableBundle b =
+                            CarrierConfigManager.getCarrierConfigSubset(
+                                    mPhone.getContext(),
+                                    mPhone.getSubId(),
+                                    CarrierConfigManager.KEY_EMERGENCY_NOTIFICATION_DELAY_INT,
+                                    CarrierConfigManager
+                                            .KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
+                    if (b.isEmpty()) return;
+
+                    for (Map.Entry<Integer, NotificationType> entry :
+                            mNotificationTypeMap.entrySet()) {
+                        NotificationType notificationType = entry.getValue();
+                        notificationType.setDelay(b);
+                    }
+                    handleConfigChanges();
+                });
+
         // Listen for subscriber changes
         SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
                 new OnSubscriptionsChangedListener(this.getLooper()) {
@@ -246,7 +270,7 @@
         TelephonyManager tm = ((TelephonyManager) context.getSystemService(
                 Context.TELEPHONY_SERVICE)).createForSubscriptionId(mPhone.getSubId());
 
-        boolean isCarrierConfigEnabled = isCarrierConfigEnableNr(context);
+        boolean isCarrierConfigEnabled = isCarrierConfigEnableNr();
         boolean isRadioAccessFamilySupported = checkSupportedBitmask(
                 tm.getSupportedRadioAccessFamily(), TelephonyManager.NETWORK_TYPE_BITMASK_NR);
         boolean isNrNetworkTypeAllowed = checkSupportedBitmask(
@@ -261,15 +285,13 @@
         return (isCarrierConfigEnabled && isRadioAccessFamilySupported && isNrNetworkTypeAllowed);
     }
 
-    private boolean isCarrierConfigEnableNr(Context context) {
-        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
-                context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (carrierConfigManager == null) {
-            Rlog.e(LOG_TAG, "isCarrierConfigEnableNr: CarrierConfigManager is null");
-            return false;
-        }
-        PersistableBundle config = carrierConfigManager.getConfigForSubId(mPhone.getSubId());
-        if (config == null) {
+    private boolean isCarrierConfigEnableNr() {
+        PersistableBundle config =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(),
+                        mPhone.getSubId(),
+                        CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
+        if (config.isEmpty()) {
             Rlog.e(LOG_TAG, "isCarrierConfigEnableNr: Cannot get config " + mPhone.getSubId());
             return false;
         }
@@ -348,21 +370,6 @@
         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
     }
 
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
-                    context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = carrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-            for (Map.Entry<Integer, NotificationType> entry : mNotificationTypeMap.entrySet()) {
-                NotificationType notificationType = entry.getValue();
-                notificationType.setDelay(b);
-            }
-            handleConfigChanges();
-        }
-    };
-
     /**
      * Post a notification to the NotificationManager for changing network type.
      */
@@ -376,6 +383,7 @@
         Notification.Builder builder = getNotificationBuilder(notificationType);
         // set some common attributes
         builder.setWhen(System.currentTimeMillis())
+                .setShowWhen(true)
                 .setAutoCancel(true)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
                 .setColor(context.getResources().getColor(
diff --git a/src/java/com/android/internal/telephony/CarrierSignalAgent.java b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
index 8509c5e..3250cef 100644
--- a/src/java/com/android/internal/telephony/CarrierSignalAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
@@ -20,11 +20,8 @@
 
 import android.annotation.Nullable;
 import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.Network;
@@ -125,25 +122,21 @@
 
     private final LocalLog mErrorLocalLog = new LocalLog(16);
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (DBG) log("CarrierSignalAgent receiver action: " + action);
-            if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                loadCarrierConfig();
-            }
-        }
-    };
-
     private ConnectivityManager.NetworkCallback mNetworkCallback;
 
     /** Constructor */
     public CarrierSignalAgent(Phone phone) {
         mPhone = phone;
+        CarrierConfigManager carrierConfigManager = mPhone.getContext().getSystemService(
+                CarrierConfigManager.class);
         loadCarrierConfig();
-        // reload configurations on CARRIER_CONFIG_CHANGED
-        mPhone.getContext().registerReceiver(mReceiver,
-                new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        carrierConfigManager.registerCarrierConfigChangeListener(
+                mPhone.getContext().getMainExecutor(),
+                (slotIndex, subId, carrierId, specificCarrierId) -> {
+                    if (slotIndex == mPhone.getPhoneId()) {
+                        loadCarrierConfig();
+                    }
+                });
         mPhone.getCarrierActionAgent().registerForCarrierAction(
                 CarrierActionAgent.CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS, this,
                 EVENT_REGISTER_DEFAULT_NETWORK_AVAIL, null, false);
@@ -205,45 +198,47 @@
      * load carrier config and cached the results into a hashMap action -> array list of components.
      */
     private void loadCarrierConfig() {
-        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
-                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        PersistableBundle b = null;
-        if (configManager != null) {
-            b = configManager.getConfigForSubId(mPhone.getSubId());
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(),
+                        mPhone.getSubId(),
+                        KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
+                        KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY);
+        if (b.isEmpty()) {
+            return;
         }
-        if (b != null) {
-            synchronized (mCachedWakeSignalConfigs) {
-                log("Loading carrier config: " + KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY);
-                Map<String, Set<ComponentName>> config = parseAndCache(
-                        b.getStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY));
-                // In some rare cases, up-to-date config could be fetched with delay and all signals
-                // have already been delivered the receivers from the default carrier config.
-                // To handle this raciness, we should notify those receivers (from old configs)
-                // and reset carrier actions. This should be done before cached Config got purged
-                // and written with the up-to-date value, Otherwise those receivers from the
-                // old config might lingers without properly clean-up.
-                if (!mCachedWakeSignalConfigs.isEmpty()
-                        && !config.equals(mCachedWakeSignalConfigs)) {
-                    if (VDBG) log("carrier config changed, reset receivers from old config");
-                    mPhone.getCarrierActionAgent().sendEmptyMessage(
-                            CarrierActionAgent.CARRIER_ACTION_RESET);
-                }
-                mCachedWakeSignalConfigs = config;
-            }
 
-            synchronized (mCachedNoWakeSignalConfigs) {
-                log("Loading carrier config: "
-                        + KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY);
-                Map<String, Set<ComponentName>> config = parseAndCache(
-                        b.getStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY));
-                if (!mCachedNoWakeSignalConfigs.isEmpty()
-                        && !config.equals(mCachedNoWakeSignalConfigs)) {
-                    if (VDBG) log("carrier config changed, reset receivers from old config");
-                    mPhone.getCarrierActionAgent().sendEmptyMessage(
-                            CarrierActionAgent.CARRIER_ACTION_RESET);
-                }
-                mCachedNoWakeSignalConfigs = config;
+        synchronized (mCachedWakeSignalConfigs) {
+            log("Loading carrier config: " + KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY);
+            Map<String, Set<ComponentName>> config = parseAndCache(
+                    b.getStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY));
+            // In some rare cases, up-to-date config could be fetched with delay and all signals
+            // have already been delivered the receivers from the default carrier config.
+            // To handle this raciness, we should notify those receivers (from old configs)
+            // and reset carrier actions. This should be done before cached Config got purged
+            // and written with the up-to-date value, Otherwise those receivers from the
+            // old config might lingers without properly clean-up.
+            if (!mCachedWakeSignalConfigs.isEmpty()
+                    && !config.equals(mCachedWakeSignalConfigs)) {
+                if (VDBG) log("carrier config changed, reset receivers from old config");
+                mPhone.getCarrierActionAgent().sendEmptyMessage(
+                        CarrierActionAgent.CARRIER_ACTION_RESET);
             }
+            mCachedWakeSignalConfigs = config;
+        }
+
+        synchronized (mCachedNoWakeSignalConfigs) {
+            log("Loading carrier config: "
+                    + KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY);
+            Map<String, Set<ComponentName>> config = parseAndCache(
+                    b.getStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY));
+            if (!mCachedNoWakeSignalConfigs.isEmpty()
+                    && !config.equals(mCachedNoWakeSignalConfigs)) {
+                if (VDBG) log("carrier config changed, reset receivers from old config");
+                mPhone.getCarrierActionAgent().sendEmptyMessage(
+                        CarrierActionAgent.CARRIER_ACTION_RESET);
+            }
+            mCachedNoWakeSignalConfigs = config;
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/CellBroadcastConfigTracker.java b/src/java/com/android/internal/telephony/CellBroadcastConfigTracker.java
new file mode 100644
index 0000000..82d4409
--- /dev/null
+++ b/src/java/com/android/internal/telephony/CellBroadcastConfigTracker.java
@@ -0,0 +1,534 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.os.AsyncResult;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Message;
+import android.telephony.CellBroadcastIdRange;
+import android.telephony.SmsCbMessage;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+
+/**
+ * This class is to track the state to set cell broadcast config
+ */
+
+public final class CellBroadcastConfigTracker extends StateMachine {
+    private static final boolean DBG = Build.IS_DEBUGGABLE;
+
+    private static final int EVENT_REQUEST = 1;
+    private static final int EVENT_CONFIGURATION_DONE = 2;
+    private static final int EVENT_ACTIVATION_DONE = 3;
+    private static final int EVENT_RADIO_OFF = 4;
+    private static final int EVENT_SUBSCRIPTION_CHANGED = 5;
+
+    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
+    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
+
+    // Cache of current cell broadcast id ranges of 3gpp
+    private List<CellBroadcastIdRange> mCbRanges3gpp = new CopyOnWriteArrayList<>();
+    // Cache of current cell broadcast id ranges of 3gpp2
+    private List<CellBroadcastIdRange> mCbRanges3gpp2 = new CopyOnWriteArrayList<>();
+    private Phone mPhone;
+    @VisibleForTesting
+    public int mSubId;
+    @VisibleForTesting
+    public final SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
+            new SubscriptionManager.OnSubscriptionsChangedListener() {
+                @Override
+                public void onSubscriptionsChanged() {
+                    sendMessage(EVENT_SUBSCRIPTION_CHANGED);
+                }
+            };
+
+    /**
+     * The class is to present the request to set cell broadcast id ranges
+     */
+    private static class Request {
+        private final List<CellBroadcastIdRange> mCbRangesRequest3gpp =
+                new CopyOnWriteArrayList<>();
+        private final List<CellBroadcastIdRange> mCbRangesRequest3gpp2 =
+                new CopyOnWriteArrayList<>();
+        Consumer<Integer> mCallback;
+
+        Request(@NonNull List<CellBroadcastIdRange> ranges, @NonNull Consumer<Integer> callback) {
+            ranges.forEach(r -> {
+                if (r.getType() == SmsCbMessage.MESSAGE_FORMAT_3GPP) {
+                    mCbRangesRequest3gpp.add(r);
+                } else {
+                    mCbRangesRequest3gpp2.add(r);
+                }
+            });
+            mCallback = callback;
+        }
+
+        List<CellBroadcastIdRange> get3gppRanges() {
+            return mCbRangesRequest3gpp;
+        }
+
+        List<CellBroadcastIdRange> get3gpp2Ranges() {
+            return mCbRangesRequest3gpp2;
+        }
+
+        Consumer<Integer> getCallback() {
+            return mCallback;
+        }
+
+        @Override
+        public String toString() {
+            return "Request[mCbRangesRequest3gpp = " + mCbRangesRequest3gpp + ", "
+                    + "mCbRangesRequest3gpp2 = " + mCbRangesRequest3gpp2 + ", "
+                    + "mCallback = " + mCallback + "]";
+        }
+    }
+
+    /**
+     * The default state.
+     */
+    private class DefaultState extends State {
+        @Override
+        public void enter() {
+            mPhone.registerForRadioOffOrNotAvailable(getHandler(), EVENT_RADIO_OFF, null);
+            mPhone.getContext().getSystemService(SubscriptionManager.class)
+                    .addOnSubscriptionsChangedListener(new HandlerExecutor(getHandler()),
+                            mSubChangedListener);
+        }
+
+        @Override
+        public void exit() {
+            mPhone.unregisterForRadioOffOrNotAvailable(getHandler());
+            mPhone.getContext().getSystemService(SubscriptionManager.class)
+                    .removeOnSubscriptionsChangedListener(mSubChangedListener);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = HANDLED;
+            if (DBG) {
+                logd("DefaultState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_RADIO_OFF:
+                    resetConfig();
+                    break;
+                case EVENT_SUBSCRIPTION_CHANGED:
+                    int subId = mPhone.getSubId();
+                    if (mSubId != subId) {
+                        log("SubId changed from " + mSubId + " to " + subId);
+                        mSubId = subId;
+                        resetConfig();
+                    }
+                    break;
+                default:
+                    log("unexpected message!");
+                    break;
+
+            }
+
+            return retVal;
+        }
+    }
+
+    private DefaultState mDefaultState = new DefaultState();
+
+    /*
+     * The idle state which does not have ongoing radio request.
+     */
+    private class IdleState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = NOT_HANDLED;
+            if (DBG) {
+                logd("IdleState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_REQUEST:
+                    Request request = (Request) msg.obj;
+                    if (DBG) {
+                        logd("IdleState handle EVENT_REQUEST with request:" + request);
+                    }
+                    if (!mCbRanges3gpp.equals(request.get3gppRanges())) {
+                        // set gsm config if the config is changed
+                        setGsmConfig(request.get3gppRanges(), request);
+                        transitionTo(mGsmConfiguringState);
+                    } else if (!mCbRanges3gpp2.equals(request.get3gpp2Ranges())) {
+                        // set cdma config directly if no gsm config change but cdma config is
+                        // changed
+                        setCdmaConfig(request.get3gpp2Ranges(), request);
+                        transitionTo(mCdmaConfiguringState);
+                    } else {
+                        logd("Do nothing as the requested ranges are same as now");
+                        request.getCallback().accept(
+                                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS);
+                    }
+                    retVal = HANDLED;
+                    break;
+                default:
+                    break;
+            }
+            return retVal;
+        }
+    }
+    private IdleState mIdleState = new IdleState();
+
+    /*
+     * The state waiting for the result to set gsm config.
+     */
+    private class GsmConfiguringState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = NOT_HANDLED;
+            if (DBG) {
+                logd("GsmConfiguringState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_REQUEST:
+                    deferMessage(msg);
+                    retVal = HANDLED;
+                    break;
+                case EVENT_CONFIGURATION_DONE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Request request = (Request) ar.userObj;
+                    if (DBG) {
+                        logd("GsmConfiguringState handle EVENT_CONFIGURATION_DONE with request:"
+                                + request);
+                    }
+                    if (ar.exception == null) {
+                        // set gsm activation and transit to gsm activating state
+                        setActivation(SmsCbMessage.MESSAGE_FORMAT_3GPP,
+                                !request.get3gppRanges().isEmpty(), request);
+                        transitionTo(mGsmActivatingState);
+                    } else {
+                        logd("Failed to set gsm config");
+                        request.getCallback().accept(
+                                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG);
+                        // transit to idle state on the failure case
+                        transitionTo(mIdleState);
+                    }
+                    retVal = HANDLED;
+                    break;
+                default:
+                    break;
+            }
+            return retVal;
+        }
+    }
+    private GsmConfiguringState mGsmConfiguringState = new GsmConfiguringState();
+
+    /*
+     * The state waiting for the result to set gsm activation.
+     */
+    private class GsmActivatingState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = NOT_HANDLED;
+            if (DBG) {
+                logd("GsmActivatingState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_REQUEST:
+                    deferMessage(msg);
+                    retVal = HANDLED;
+                    break;
+                case EVENT_ACTIVATION_DONE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Request request = (Request) ar.userObj;
+                    if (DBG) {
+                        logd("GsmActivatingState handle EVENT_ACTIVATION_DONE with request:"
+                                + request);
+                    }
+                    if (ar.exception == null) {
+                        mCbRanges3gpp = request.get3gppRanges();
+                        if (!mCbRanges3gpp2.equals(request.get3gpp2Ranges())) {
+                            // set cdma config and transit to cdma configuring state if the config
+                            // is changed.
+                            setCdmaConfig(request.get3gpp2Ranges(), request);
+                            transitionTo(mCdmaConfiguringState);
+                        } else {
+                            logd("Done as no need to update ranges for 3gpp2");
+                            request.getCallback().accept(
+                                    TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS);
+                            // transit to idle state if there is no cdma config change
+                            transitionTo(mIdleState);
+                        }
+                    } else {
+                        logd("Failed to set gsm activation");
+                        request.getCallback().accept(
+                                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION);
+                        // transit to idle state on the failure case
+                        transitionTo(mIdleState);
+                    }
+                    retVal = HANDLED;
+                    break;
+                default:
+                    break;
+            }
+            return retVal;
+        }
+    }
+    private GsmActivatingState mGsmActivatingState = new GsmActivatingState();
+
+    /*
+     * The state waiting for the result to set cdma config.
+     */
+    private class CdmaConfiguringState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = NOT_HANDLED;
+            if (DBG) {
+                logd("CdmaConfiguringState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_REQUEST:
+                    deferMessage(msg);
+                    retVal = HANDLED;
+                    break;
+                case EVENT_CONFIGURATION_DONE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Request request = (Request) ar.userObj;
+                    if (DBG) {
+                        logd("CdmaConfiguringState handle EVENT_ACTIVATION_DONE with request:"
+                                + request);
+                    }
+                    if (ar.exception == null) {
+                        // set cdma activation and transit to cdma activating state
+                        setActivation(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
+                                !request.get3gpp2Ranges().isEmpty(), request);
+                        transitionTo(mCdmaActivatingState);
+                    } else {
+                        logd("Failed to set cdma config");
+                        request.getCallback().accept(
+                                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG);
+                        // transit to idle state on the failure case
+                        transitionTo(mIdleState);
+                    }
+                    retVal = HANDLED;
+                    break;
+                default:
+                    break;
+            }
+            return retVal;
+        }
+    }
+    private CdmaConfiguringState mCdmaConfiguringState = new CdmaConfiguringState();
+
+    /*
+     * The state waiting for the result to set cdma activation.
+     */
+    private class CdmaActivatingState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            boolean retVal = NOT_HANDLED;
+            if (DBG) {
+                logd("CdmaActivatingState message:" + msg.what);
+            }
+            switch (msg.what) {
+                case EVENT_REQUEST:
+                    deferMessage(msg);
+                    retVal = HANDLED;
+                    break;
+                case EVENT_ACTIVATION_DONE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Request request = (Request) ar.userObj;
+                    if (DBG) {
+                        logd("CdmaActivatingState handle EVENT_ACTIVATION_DONE with request:"
+                                + request);
+                    }
+                    if (ar.exception == null) {
+                        mCbRanges3gpp2 = request.get3gpp2Ranges();
+                        request.getCallback().accept(
+                                    TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS);
+                    } else {
+                        logd("Failed to set cdma activation");
+                        request.getCallback().accept(
+                                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION);
+                    }
+                    // transit to idle state anyway
+                    transitionTo(mIdleState);
+                    retVal = HANDLED;
+                    break;
+                default:
+                    break;
+            }
+            return retVal;
+        }
+    }
+    private CdmaActivatingState mCdmaActivatingState = new CdmaActivatingState();
+
+    private CellBroadcastConfigTracker(Phone phone) {
+        super("CellBroadcastConfigTracker-" + phone.getPhoneId());
+        init(phone);
+    }
+
+    private CellBroadcastConfigTracker(Phone phone, Handler handler) {
+        super("CellBroadcastConfigTracker-" + phone.getPhoneId(), handler);
+        init(phone);
+    }
+
+    private void init(Phone phone) {
+        logd("init");
+        mPhone = phone;
+        mSubId = mPhone.getSubId();
+
+        addState(mDefaultState);
+        addState(mIdleState, mDefaultState);
+        addState(mGsmConfiguringState, mDefaultState);
+        addState(mGsmActivatingState, mDefaultState);
+        addState(mCdmaConfiguringState, mDefaultState);
+        addState(mCdmaActivatingState, mDefaultState);
+        setInitialState(mIdleState);
+    }
+
+    /**
+     * create a CellBroadcastConfigTracker instance for the phone
+     */
+    public static CellBroadcastConfigTracker make(Phone phone, Handler handler,
+            boolean shouldStart) {
+        CellBroadcastConfigTracker tracker = handler == null
+                ? new CellBroadcastConfigTracker(phone)
+                : new CellBroadcastConfigTracker(phone, handler);
+        if (shouldStart) {
+            tracker.start();
+        }
+        return tracker;
+    }
+
+    /**
+     * Return current cell broadcast ranges.
+     */
+    @NonNull public List<CellBroadcastIdRange> getCellBroadcastIdRanges() {
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+        ranges.addAll(mCbRanges3gpp);
+        ranges.addAll(mCbRanges3gpp2);
+        return ranges;
+    }
+
+    /**
+     * Set reception of cell broadcast messages with the list of the given ranges.
+     */
+    public void setCellBroadcastIdRanges(
+            @NonNull List<CellBroadcastIdRange> ranges, @NonNull Consumer<Integer> callback) {
+        if (DBG) {
+            logd("setCellBroadcastIdRanges with ranges:" + ranges);
+        }
+        ranges = mergeRangesAsNeeded(ranges);
+        sendMessage(EVENT_REQUEST, new Request(ranges, callback));
+    }
+
+    /**
+     * Merge the overlapped CellBroadcastIdRanges in the list as needed
+     * @param ranges the list of CellBroadcastIdRanges
+     * @return the list of CellBroadcastIdRanges without overlapping
+     *
+     * @throws IllegalArgumentException if there is conflict of the ranges. For instance,
+     * the channel is enabled in some range, but disable in others.
+     */
+    @VisibleForTesting
+    public static @NonNull List<CellBroadcastIdRange> mergeRangesAsNeeded(
+            @NonNull List<CellBroadcastIdRange> ranges) throws IllegalArgumentException {
+        ranges.sort((r1, r2) -> r1.getType() != r2.getType() ? r1.getType() - r2.getType()
+                : (r1.getStartId() != r2.getStartId() ? r1.getStartId() - r2.getStartId()
+                : r2.getEndId() - r1.getEndId()));
+        final List<CellBroadcastIdRange> newRanges = new ArrayList<>();
+        ranges.forEach(r -> {
+            if (newRanges.isEmpty() || newRanges.get(newRanges.size() - 1).getType() != r.getType()
+                    || newRanges.get(newRanges.size() - 1).getEndId() + 1 < r.getStartId()
+                    || (newRanges.get(newRanges.size() - 1).getEndId() + 1 == r.getStartId()
+                    && newRanges.get(newRanges.size() - 1).isEnabled() != r.isEnabled())) {
+                newRanges.add(new CellBroadcastIdRange(r.getStartId(), r.getEndId(),
+                        r.getType(), r.isEnabled()));
+            } else {
+                if (newRanges.get(newRanges.size() - 1).isEnabled() != r.isEnabled()) {
+                    throw new IllegalArgumentException("range conflict " + r);
+                }
+                if (r.getEndId() > newRanges.get(newRanges.size() - 1).getEndId()) {
+                    CellBroadcastIdRange range = newRanges.get(newRanges.size() - 1);
+                    newRanges.set(newRanges.size() - 1, new CellBroadcastIdRange(
+                            range.getStartId(), r.getEndId(), range.getType(), range.isEnabled()));
+                }
+            }
+        });
+        return newRanges;
+    }
+
+    private void resetConfig() {
+        mCbRanges3gpp.clear();
+        mCbRanges3gpp2.clear();
+    }
+
+    private void setGsmConfig(List<CellBroadcastIdRange> ranges, Request request) {
+        if (DBG) {
+            logd("setGsmConfig with " + ranges);
+        }
+
+        SmsBroadcastConfigInfo[] configs = new SmsBroadcastConfigInfo[ranges.size()];
+        for (int i = 0; i < configs.length; i++) {
+            CellBroadcastIdRange r = ranges.get(i);
+            configs[i] = new SmsBroadcastConfigInfo(r.getStartId(), r.getEndId(),
+                    SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, r.isEnabled());
+        }
+
+        Message response = obtainMessage(EVENT_CONFIGURATION_DONE, request);
+        mPhone.mCi.setGsmBroadcastConfig(configs, response);
+    }
+
+    private void setCdmaConfig(List<CellBroadcastIdRange> ranges, Request request) {
+        if (DBG) {
+            logd("setCdmaConfig with " + ranges);
+        }
+
+        CdmaSmsBroadcastConfigInfo[] configs =
+                new CdmaSmsBroadcastConfigInfo[ranges.size()];
+        for (int i = 0; i < configs.length; i++) {
+            CellBroadcastIdRange r = ranges.get(i);
+            configs[i] = new CdmaSmsBroadcastConfigInfo(
+                    r.getStartId(), r.getEndId(), 1, r.isEnabled());
+        }
+
+        Message response = obtainMessage(EVENT_CONFIGURATION_DONE, request);
+        mPhone.mCi.setCdmaBroadcastConfig(configs, response);
+    }
+
+    private void setActivation(int type, boolean activate, Request request) {
+        if (DBG) {
+            logd("setActivation(" + type + "." + activate + ')');
+        }
+
+        Message response = obtainMessage(EVENT_ACTIVATION_DONE, request);
+
+        if (type == SmsCbMessage.MESSAGE_FORMAT_3GPP) {
+            mPhone.mCi.setGsmBroadcastActivation(activate, response);
+        } else if (type == SmsCbMessage.MESSAGE_FORMAT_3GPP2) {
+            mPhone.mCi.setCdmaBroadcastActivation(activate, response);
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index 4253905..9cbd7a6 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -18,9 +18,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.hardware.radio.V1_0.RegState;
 import android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator;
 import android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo;
+import android.hardware.radio.network.RegState;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
@@ -35,6 +35,7 @@
 import android.telephony.CellIdentityNr;
 import android.telephony.CellIdentityTdscdma;
 import android.telephony.CellIdentityWcdma;
+import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.NetworkService;
@@ -190,6 +191,8 @@
                     return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
                 case RegState.REG_ROAMING:
                     return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
+                case RegState.REG_EM:
+                    return NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY;
                 default:
                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
             }
@@ -201,6 +204,7 @@
                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
                 case RegState.REG_DENIED_EM:
                 case RegState.UNKNOWN_EM:
+                case RegState.REG_EM:
                     return true;
                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
                 case RegState.REG_HOME:
@@ -504,7 +508,7 @@
                     && reasonForDenial
                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
                 AnomalyReporter.reportAnomaly(
-                        UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f20"),
+                        UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f21"),
                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
             }
 
@@ -522,6 +526,8 @@
             boolean isNrAvailable = false;
             boolean isDcNrRestricted = false;
             VopsSupportInfo vopsInfo = null;
+            int lteAttachResultType = 0;
+            int lteAttachExtraInfo = 0;
 
             android.hardware.radio.network.AccessTechnologySpecificInfo info =
                     regResult.accessTechnologySpecificInfo;
@@ -540,6 +546,8 @@
                     vopsInfo = convertHalLteVopsSupportInfo(
                             info.getEutranInfo().lteVopsInfo.isVopsSupported,
                             info.getEutranInfo().lteVopsInfo.isEmcBearerSupported);
+                    lteAttachResultType = info.getEutranInfo().lteAttachResultType;
+                    lteAttachExtraInfo = info.getEutranInfo().extraInfo;
                     break;
                 case android.hardware.radio.network.AccessTechnologySpecificInfo.ngranNrVopsInfo:
                     vopsInfo = new NrVopsSupportInfo(info.getNgranNrVopsInfo().vopsSupported,
@@ -565,10 +573,26 @@
                     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);
+                    return new NetworkRegistrationInfo.Builder()
+                        .setDomain(domain)
+                        .setTransportType(transportType)
+                        .setRegistrationState(regState)
+                        .setAccessNetworkTechnology(networkType)
+                        .setRejectCause(reasonForDenial)
+                        .setEmergencyOnly(isEmergencyOnly)
+                        .setAvailableServices(availableServices)
+                        .setCellIdentity(cellIdentity)
+                        .setRegisteredPlmn(rplmn)
+                        .setDataSpecificInfo(
+                                new DataSpecificRegistrationInfo.Builder(MAX_DATA_CALLS)
+                                     .setDcNrRestricted(isDcNrRestricted)
+                                     .setNrAvailable(isNrAvailable)
+                                     .setEnDcAvailable(isEndcAvailable)
+                                     .setVopsSupportInfo(vopsInfo)
+                                     .setLteAttachResultType(lteAttachResultType)
+                                     .setLteAttachExtraInfo(lteAttachExtraInfo)
+                                     .build())
+                        .build();
             }
         }
 
@@ -594,7 +618,7 @@
                     && reasonForDenial
                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
                 AnomalyReporter.reportAnomaly(
-                        UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f20"),
+                        UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f21"),
                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
             }
 
diff --git a/src/java/com/android/internal/telephony/CommandException.java b/src/java/com/android/internal/telephony/CommandException.java
index 72bb6a3..e068c1c 100644
--- a/src/java/com/android/internal/telephony/CommandException.java
+++ b/src/java/com/android/internal/telephony/CommandException.java
@@ -341,7 +341,6 @@
                 return new CommandException(Error.RF_HARDWARE_ISSUE);
             case RILConstants.NO_RF_CALIBRATION_INFO:
                 return new CommandException(Error.NO_RF_CALIBRATION_INFO);
-
             default:
                 Rlog.e("GSM", "Unrecognized RIL errno " + ril_errno);
                 return new CommandException(Error.INVALID_RESPONSE);
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 27cedfe..971e051 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -25,22 +25,31 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.WorkSource;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.BarringInfo;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.ClientRequestStats;
+import android.telephony.DomainSelectionService;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.NetworkScanRequest;
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.SignalThresholdInfo;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.HalService;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataProfile;
 import android.telephony.data.NetworkSliceInfo;
 import android.telephony.data.TrafficDescriptor;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.emergency.EmergencyConstants;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.imsphone.ImsCallInfo;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 import com.android.internal.telephony.uicc.IccCardStatus;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
@@ -124,6 +133,15 @@
     static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM     = 39;
     static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM           = 96;
 
+    /** IMS voice capability */
+    int IMS_MMTEL_CAPABILITY_VOICE = 1 << 0;
+    /** IMS video capability */
+    int IMS_MMTEL_CAPABILITY_VIDEO = 1 << 1;
+    /** IMS SMS capability */
+    int IMS_MMTEL_CAPABILITY_SMS = 1 << 2;
+    /** IMS RCS capabilities */
+    int IMS_RCS_CAPABILITIES = 1 << 3;
+
     //***** Methods
 
     /**
@@ -1773,6 +1791,17 @@
     public void getDeviceIdentity(Message response);
 
     /**
+     * Request the device IMEI / IMEI type / IMEISV
+     * "response" is ImeiInfo object that contains
+     *  [0] ImeiType Indicates whether IMEI is of primary or secondary type
+     *  [1] IMEI if GSM subscription is available
+     *  [2] IMEISV if GSM subscription is available
+     *
+     * @param response Message
+     */
+    public void getImei(Message response);
+
+    /**
      * Request the device MDN / H_SID / H_NID / MIN.
      * "response" is const char **
      *   [0] is MDN if CDMA subscription is available
@@ -2086,10 +2115,15 @@
      *
      * Input parameters equivalent to TS 27.007 AT+CCHC command.
      *
+     * Per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A. In order
+     * to close proper logical channel, should pass information about whether the logical channel
+     * was opened for sending ES10 commands or not.
+     *
      * @param channel Channel id. Id of the channel to be closed.
+     * @param isEs10  Whether the logical channel is opened to perform ES10 operations.
      * @param response Callback message.
      */
-    public void iccCloseLogicalChannel(int channel, Message response);
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response);
 
     /**
      * Exchange APDUs with the SIM on a logical channel.
@@ -2105,11 +2139,12 @@
      * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
      *            is sent to the SIM.
      * @param data Data to be sent with the APDU.
+     * @param isEs10Command whether APDU command is an ES10 command or a regular APDU
      * @param response Callback message. response.obj.userObj will be
      *            an IccIoResult on success.
      */
-    public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
-            int p1, int p2, int p3, String data, Message response);
+    void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
+            int p1, int p2, int p3, String data, boolean isEs10Command, Message response);
 
     /**
      * Exchange APDUs with the SIM on a basic channel.
@@ -2186,11 +2221,21 @@
 
     /**
      * @return the radio hal version
+     * @deprecated use {@link #getHalVersion(int)}
      */
+    @Deprecated
     default HalVersion getHalVersion() {
         return HalVersion.UNKNOWN;
     }
 
+    /**
+     * @param service indicate the service id to query.
+     * @return the hal version of a specific service
+     */
+    default HalVersion getHalVersion(@HalService int service) {
+        return HalVersion.UNKNOWN;
+    }
+
    /**
      * Sets user selected subscription at Modem.
      *
@@ -2619,6 +2664,15 @@
     default void getBarringInfo(Message result) {};
 
     /**
+     * Returns the last barring information received.
+     *
+     * @return the last barring information.
+     */
+    default @Nullable BarringInfo getLastBarringInfo() {
+        return null;
+    };
+
+    /**
      * Allocates a pdu session id
      *
      * AsyncResult.result is the allocated pdu session id
@@ -2747,6 +2801,54 @@
      public void unregisterForSimPhonebookRecordsReceived(Handler h);
 
     /**
+     * Registers for notifications of connection setup failure.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForConnectionSetupFailure(Handler h, int what, Object obj) {}
+
+    /**
+     * Unregisters for notifications of connection setup failure.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForConnectionSetupFailure(Handler h) {}
+
+    /**
+     * Registers for notifications when ANBR is received form the network.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForNotifyAnbr(Handler h, int what, Object obj) {}
+
+    /**
+     * Unregisters for notifications when ANBR is received form the network.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForNotifyAnbr(Handler h) {}
+
+    /**
+     * Registers for IMS deregistration trigger from modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForTriggerImsDeregistration(Handler h, int what, Object obj) {}
+
+    /**
+     * Unregisters for IMS deregistration trigger from modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForTriggerImsDeregistration(Handler h) {}
+
+    /**
      * Set the UE's usage setting.
      *
      * @param result Callback message containing the success or failure status.
@@ -2761,4 +2863,417 @@
      * @param result Callback message containing the usage setting (or a failure status).
      */
     default void getUsageSetting(Message result) {}
+
+    /**
+     * Sets the emergency mode.
+     *
+     * @param emcMode Defines the radio emergency mode type.
+     * @param result Callback message containing the success or failure status.
+     */
+    default void setEmergencyMode(@EmergencyConstants.EmergencyMode int emcMode,
+            @Nullable Message result) {}
+
+    /**
+     * Triggers an emergency network scan.
+     *
+     * @param accessNetwork Contains the list of access network types to be prioritized
+     *        during emergency scan. The 1st entry has the highest priority.
+     * @param scanType Indicates the type of scans to be performed i.e. limited scan,
+     *        full service scan or both.
+     * @param result Callback message containing the success or failure status.
+     */
+    default void triggerEmergencyNetworkScan(
+            @NonNull @AccessNetworkConstants.RadioAccessNetworkType int[] accessNetwork,
+            @DomainSelectionService.EmergencyScanType int scanType, @Nullable Message result) {}
+
+    /**
+     * Cancels ongoing emergency network scan.
+     *
+     * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
+     *        If {@code true}, then the modem shall start the new scan from the beginning,
+     *        otherwise the modem shall resume from the last search.
+     * @param result Callback message containing the success or failure status.
+     */
+    default void cancelEmergencyNetworkScan(boolean resetScan, @Nullable Message result) {}
+
+    /**
+     * Exits ongoing emergency mode.
+     *
+     * @param result Callback message containing the success or failure status.
+     */
+    default void exitEmergencyMode(@Nullable Message result) {}
+
+    /**
+     * Registers for emergency network scan result.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForEmergencyNetworkScan(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for emergency network scan result.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForEmergencyNetworkScan(@NonNull Handler h) {}
+
+    /**
+     * Provides a list of SRVCC call information to radio
+     *
+     * @param srvccConnections the list of connections.
+     */
+    default void setSrvccCallInfo(SrvccConnection[] srvccConnections, Message result) {}
+
+    /**
+     * Updates the IMS registration information to the radio.
+     *
+     * @param state The current IMS registration state.
+     * @param imsRadioTech The type of underlying radio access network used.
+     * @param suggestedAction The suggested action for the radio to perform.
+     * @param capabilities IMS capabilities such as VOICE, VIDEO and SMS.
+     */
+    default void updateImsRegistrationInfo(int state,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
+            @RegistrationManager.SuggestedAction int suggestedAction,
+            int capabilities, Message result) {}
+
+    /**
+     * Notifies the NAS and RRC layers of the radio the type of upcoming IMS traffic.
+     *
+     * @param token A nonce to identify the request.
+     * @param trafficType IMS traffic type like registration, voice, video, SMS, emergency, and etc.
+     * @param accessNetworkType The type of underlying radio access network used.
+     * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+     *        mobile terminated use case eg. MO/MT call/SMS etc.
+     */
+    default void startImsTraffic(int token,
+            @MmTelFeature.ImsTrafficType int trafficType,
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+            @MmTelFeature.ImsTrafficDirection int trafficDirection,
+            Message result) {}
+
+    /**
+     * Notifies IMS traffic has been stopped.
+     *
+     * @param token The token assigned by startImsTraffic.
+     */
+    default void stopImsTraffic(int token, Message result) {}
+
+    /**
+     * Triggers the UE initiated EPS fallback procedure.
+     *
+     * @param reason Specifies the reason for EPS fallback.
+     */
+    default void triggerEpsFallback(int reason, Message result) {}
+
+    /**
+     * Triggers radio to send ANBRQ message to the network.
+     *
+     * @param mediaType Media type is used to identify media stream such as audio or video.
+     * @param direction Direction of this packet stream (e.g. uplink or downlink).
+     * @param bitsPerSecond The bit rate requested by the opponent UE.
+     * @param result Callback message to receive the result.
+     */
+    default void sendAnbrQuery(int mediaType, int direction, int bitsPerSecond, Message result) {}
+
+    /**
+     * Set the UE's ability to accept/reject null ciphered and/or null integrity-protected
+     * connections.
+     *
+     * @param enabled true to allow null ciphered and/or null integrity-protected connections,
+     * false to disallow.
+     * @param result Callback message containing the success or failure status.
+     */
+    default void setNullCipherAndIntegrityEnabled(boolean enabled, Message result) {}
+
+    /**
+     * Check whether null ciphering and/or null integrity-protected connections are allowed.
+     *
+     * @param result Callback message containing the success or failure status.
+     */
+    default void isNullCipherAndIntegrityEnabled(Message result) {}
+
+    /**
+     * Notifies the IMS call status to the modem.
+     *
+     * @param imsCallInfo The list of {@link ImsCallInfo}.
+     * @param result A callback to receive the response.
+     */
+    default void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message result) {}
+
+    /**
+     * Enables or disables N1 mode (access to 5G core network) in accordance with
+     * 3GPP TS 24.501 4.9.
+     * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode.
+     * @param result Callback message to receive the result.
+     */
+    default void setN1ModeEnabled(boolean enable, Message result) {}
+
+    /**
+     * Check whether N1 mode (access to 5G core network) is enabled or not.
+     * @param result Callback message to receive the result.
+     */
+    default void isN1ModeEnabled(Message result) {}
+
+    /**
+     * Get feature capabilities supported by satellite.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    default void getSatelliteCapabilities(Message result) {}
+
+    /**
+     * Turn satellite modem on/off.
+     *
+     * @param result Message that will be sent back to the requester
+     * @param on {@code true} for turning on.
+     *           {@code false} for turning off.
+     */
+    default void setSatellitePower(Message result, boolean on) {}
+
+    /**
+     * Get satellite modem state.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    default void getSatellitePowerState(Message result) {}
+
+    /**
+     * Get satellite provision state.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    default void getSatelliteProvisionState(Message result) {}
+
+    /**
+     * Check whether satellite modem is supported by the device.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    default void isSatelliteSupported(Message result) {}
+
+    /**
+     * Provision the subscription with a satellite provider. This is needed to register the
+     * subscription if the provider allows dynamic registration.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param imei IMEI of the SIM associated with the satellite modem.
+     * @param msisdn MSISDN of the SIM associated with the satellite modem.
+     * @param imsi IMSI of the SIM associated with the satellite modem.
+     * @param features List of features to be provisioned.
+     */
+    default void provisionSatelliteService(
+            Message result, String imei, String msisdn, String imsi, int[] features) {}
+
+    /**
+     * Add contacts that are allowed to be used for satellite communication. This is applicable for
+     * incoming messages as well.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param contacts List of allowed contacts to be added.
+     */
+    default void addAllowedSatelliteContacts(Message result, String[] contacts) {}
+
+    /**
+     * Remove contacts that are allowed to be used for satellite communication. This is applicable
+     * for incoming messages as well.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param contacts List of allowed contacts to be removed.
+     */
+    default void removeAllowedSatelliteContacts(Message result, String[] contacts) {}
+
+    /**
+     * Send text messages.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param messages List of messages in text format to be sent.
+     * @param destination The recipient of the message.
+     * @param latitude The current latitude of the device.
+     * @param longitude The current longitude of the device. The location (i.e., latitude and
+     *        longitude) of the device will be filled for emergency messages.
+     */
+    default void sendSatelliteMessages(Message result, String[] messages, String destination,
+            double latitude, double longitude) {}
+
+    /**
+     * Get pending messages.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void getPendingSatelliteMessages(Message result) {}
+
+    /**
+     * Get current satellite registration mode.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void getSatelliteMode(Message result) {}
+
+    /**
+     * Set the filter for what type of indication framework want to receive from modem.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param filterBitmask The filter bitmask identifying what type of indication Telephony
+     *                      framework wants to receive from modem.
+     */
+    default void setSatelliteIndicationFilter(Message result, int filterBitmask) {}
+
+    /**
+     * User started pointing to the satellite. Modem should continue to update the ponting input
+     * as user moves device.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void startSendingSatellitePointingInfo(Message result) {}
+
+    /**
+     * Stop sending satellite pointing info to the framework.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void stopSendingSatellitePointingInfo(Message result) {}
+
+    /**
+     * Get max number of characters per text message.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void getMaxCharactersPerSatelliteTextMessage(Message result) {}
+
+    /**
+     * Get whether satellite communication is allowed for the current location.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void isSatelliteCommunicationAllowedForCurrentLocation(Message result) {}
+
+    /**
+     * Get the time after which the satellite will be visible.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    default void getTimeForNextSatelliteVisibility(Message result) {}
+
+    /**
+     * Registers for pending message count from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForPendingSatelliteMessageCount(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for pending message count from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForPendingSatelliteMessageCount(@NonNull Handler h) {}
+
+    /**
+     * Registers for new messages from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForNewSatelliteMessages(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for new messages from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForNewSatelliteMessages(@NonNull Handler h) {}
+
+    /**
+     * Registers for messages transfer complete from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForSatelliteMessagesTransferComplete(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for messages transfer complete from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForSatelliteMessagesTransferComplete(@NonNull Handler h) {}
+
+    /**
+     * Registers for pointing info changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForSatellitePointingInfoChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for pointing info changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForSatellitePointingInfoChanged(@NonNull Handler h) {}
+
+    /**
+     * Registers for mode changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForSatelliteModeChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for mode changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForSatelliteModeChanged(@NonNull Handler h) {}
+
+    /**
+     * Registers for radio technology changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForSatelliteRadioTechnologyChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for radio technology changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForSatelliteRadioTechnologyChanged(@NonNull Handler h) {}
+
+    /**
+     * Registers for provision state changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    default void registerForSatelliteProvisionStateChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {}
+
+    /**
+     * Unregisters for provision state changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    default void unregisterForSatelliteProvisionStateChanged(@NonNull Handler h) {}
 }
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index c60e5df..68fd6ab 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -27,6 +27,8 @@
 import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.RtpHeaderExtension;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.MmTelFeature.ImsAudioHandler;
 import android.util.Log;
 
 import com.android.ims.internal.ConferenceParticipant;
@@ -139,6 +141,13 @@
          * @param extensionData The extension data.
          */
         public void onReceivedRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> extensionData);
+
+        /**
+         * Indicates that the audio handler for this connection is changed.
+         *
+         * @param imsAudioHandler {@link MmTelFeature#ImsAudioHandler}.
+         */
+        void onAudioModeIsVoipChanged(@ImsAudioHandler int imsAudioHandler);
     }
 
     /**
@@ -194,6 +203,8 @@
         public void onReceivedDtmfDigit(char digit) {}
         @Override
         public void onReceivedRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> extensionData) {}
+        @Override
+        public void onAudioModeIsVoipChanged(@ImsAudioHandler int imsAudioHandler) {}
     }
 
     public static final int AUDIO_QUALITY_STANDARD = 1;
@@ -328,6 +339,41 @@
     /* Instance Methods */
 
     /**
+     * PhoneFactory Dependencies for testing.
+     */
+    @VisibleForTesting
+    public interface PhoneFactoryProxy {
+        Phone getPhone(int index);
+        Phone getDefaultPhone();
+        Phone[] getPhones();
+    }
+
+    private PhoneFactoryProxy mPhoneFactoryProxy = new PhoneFactoryProxy() {
+        @Override
+        public Phone getPhone(int index) {
+            return PhoneFactory.getPhone(index);
+        }
+
+        @Override
+        public Phone getDefaultPhone() {
+            return PhoneFactory.getDefaultPhone();
+        }
+
+        @Override
+        public Phone[] getPhones() {
+            return PhoneFactory.getPhones();
+        }
+    };
+
+    /**
+     * Overrides PhoneFactory dependencies for testing.
+     */
+    @VisibleForTesting
+    public void setPhoneFactoryProxy(PhoneFactoryProxy proxy) {
+        mPhoneFactoryProxy = proxy;
+    }
+
+    /**
      * @return The telecom internal call ID associated with this connection.  Only to be used for
      * debugging purposes.
      */
@@ -590,14 +636,35 @@
      */
     public void setEmergencyCallInfo(CallTracker ct) {
         if (ct != null) {
-            Phone phone = ct.getPhone();
-            if (phone != null) {
-                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+            Phone currentPhone = ct.getPhone();
+            if (currentPhone != null) {
+                EmergencyNumberTracker tracker = currentPhone.getEmergencyNumberTracker();
                 if (tracker != null) {
                     EmergencyNumber num = tracker.getEmergencyNumber(mAddress);
+                    Phone[] allPhones = mPhoneFactoryProxy.getPhones();
                     if (num != null) {
                         mIsEmergencyCall = true;
                         mEmergencyNumberInfo = num;
+                    } else if (allPhones.length > 1) {
+                        // If there are multiple active SIMs, check all instances:
+                        boolean found = false;
+                        for (Phone phone : allPhones) {
+                            // If the current iteration was already checked, skip:
+                            if (phone.getPhoneId() == currentPhone.getPhoneId()){
+                                continue;
+                            }
+                            num = phone.getEmergencyNumberTracker()
+                                    .getEmergencyNumber(mAddress);
+                            if (num != null){
+                                found = true;
+                                mIsEmergencyCall = true;
+                                mEmergencyNumberInfo = num;
+                                break;
+                            }
+                        }
+                        if (!found){
+                            Rlog.e(TAG, "setEmergencyCallInfo: emergency number is null");
+                        }
                     } else {
                         Rlog.e(TAG, "setEmergencyCallInfo: emergency number is null");
                     }
@@ -1519,6 +1586,25 @@
     }
 
     /**
+     * Called to report audio mode changed for Voip.
+     * @param imsAudioHandler the received value to handle the audio for this IMS call.
+     */
+    public void onAudioModeIsVoipChanged(@ImsAudioHandler int imsAudioHandler) {
+        Rlog.i(TAG, "onAudioModeIsVoipChanged: conn imsAudioHandler " + imsAudioHandler);
+
+        boolean isVoip = imsAudioHandler == MmTelFeature.AUDIO_HANDLER_ANDROID;
+        if (isVoip == mAudioModeIsVoip) return;
+        mAudioModeIsVoip = isVoip;
+
+        Rlog.i(TAG, "onAudioModeIsVoipChanged: isVoip: " + isVoip
+                + "mAudioModeIsVoip:" + mAudioModeIsVoip);
+
+        for (Listener l : mListeners) {
+            l.onAudioModeIsVoipChanged(imsAudioHandler);
+        }
+    }
+
+    /**
      * Called to report RTP header extensions received from the network.
      * @param extensionData the received extension data.
      */
diff --git a/src/java/com/android/internal/telephony/DataIndication.java b/src/java/com/android/internal/telephony/DataIndication.java
index 3467955..205c4d8 100644
--- a/src/java/com/android/internal/telephony/DataIndication.java
+++ b/src/java/com/android/internal/telephony/DataIndication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+
 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;
@@ -53,7 +55,7 @@
      */
     public void dataCallListChanged(int indicationType,
             android.hardware.radio.data.SetupDataCallResult[] dcList) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_DATA, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, dcList);
         ArrayList<DataCallResponse> response = RILUtils.convertHalDataCallResultList(dcList);
@@ -68,7 +70,7 @@
      */
     public void keepaliveStatus(int indicationType,
             android.hardware.radio.data.KeepaliveStatus halStatus) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_DATA, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(
@@ -87,7 +89,7 @@
      * @param pco New PcoData
      */
     public void pcoData(int indicationType, android.hardware.radio.data.PcoDataInfo pco) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_DATA, indicationType);
 
         PcoData response = new PcoData(pco.cid, pco.bearerProto, pco.pcoId, pco.contents);
 
@@ -104,7 +106,7 @@
      */
     public void unthrottleApn(int indicationType, android.hardware.radio.data.DataProfileInfo dpi)
             throws RemoteException {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_DATA, indicationType);
         DataProfile response = RILUtils.convertToDataProfile(dpi);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_UNTHROTTLE_APN, response);
@@ -120,7 +122,7 @@
      */
     public void slicingConfigChanged(int indicationType,
             android.hardware.radio.data.SlicingConfig slicingConfig) throws RemoteException {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_DATA, indicationType);
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(RIL_UNSOL_SLICING_CONFIG_CHANGED, slicingConfig);
         }
diff --git a/src/java/com/android/internal/telephony/DataResponse.java b/src/java/com/android/internal/telephony/DataResponse.java
index 7cfe13b..bef1da7 100644
--- a/src/java/com/android/internal/telephony/DataResponse.java
+++ b/src/java/com/android/internal/telephony/DataResponse.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+
 import android.hardware.radio.RadioError;
 import android.hardware.radio.RadioResponseInfo;
 import android.hardware.radio.data.IRadioDataResponse;
@@ -51,7 +53,7 @@
      * @param id The pdu session id allocated
      */
     public void allocatePduSessionIdResponse(RadioResponseInfo responseInfo, int id) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
                 RadioResponse.sendMessageResponse(rr.mResult, id);
@@ -64,14 +66,14 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void cancelHandoverResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, mRil, responseInfo);
     }
 
     /**
@@ -80,7 +82,7 @@
      */
     public void getDataCallListResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.data.SetupDataCallResult[] dataCallResultList) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
 
         if (rr != null) {
             ArrayList<DataCallResponse> response =
@@ -98,7 +100,7 @@
      */
     public void getSlicingConfigResponse(RadioResponseInfo responseInfo,
                 android.hardware.radio.data.SlicingConfig slicingConfig) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
 
         if (rr != null) {
             NetworkSlicingConfig ret = RILUtils.convertHalSlicingConfig(slicingConfig);
@@ -113,35 +115,35 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void releasePduSessionIdResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, mRil, responseInfo);
     }
 
     /**
@@ -150,7 +152,7 @@
      */
     public void setupDataCallResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.data.SetupDataCallResult setupDataCallResult) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
 
         if (rr != null) {
             DataCallResponse response = RILUtils.convertHalDataCallResult(setupDataCallResult);
@@ -165,7 +167,7 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void startHandoverResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_DATA, mRil, responseInfo);
     }
 
     /**
@@ -175,7 +177,7 @@
     public void startKeepaliveResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.data.KeepaliveStatus keepaliveStatus) {
 
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
         if (rr == null) return;
 
         KeepaliveStatus ret = null;
@@ -214,7 +216,7 @@
      * @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);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_DATA, responseInfo);
         if (rr == null) return;
 
         try {
diff --git a/src/java/com/android/internal/telephony/DebugService.java b/src/java/com/android/internal/telephony/DebugService.java
index 5cc730c..3341577 100644
--- a/src/java/com/android/internal/telephony/DebugService.java
+++ b/src/java/com/android/internal/telephony/DebugService.java
@@ -52,13 +52,15 @@
                     TelephonyMetrics.getInstance().dump(fd, pw, args);
                     return;
                 case "--saveatoms":
-                    log("Saving atoms..");
-                    PhoneFactory.getMetricsCollector().getAtomsStorage().flushAtoms();
+                    if (Build.IS_DEBUGGABLE) {
+                        log("Saving atoms..");
+                        PhoneFactory.getMetricsCollector().flushAtomsStorage();
+                    }
                     return;
                 case "--clearatoms":
                     if (Build.IS_DEBUGGABLE) {
                         log("Clearing atoms..");
-                        PhoneFactory.getMetricsCollector().getAtomsStorage().clearAtoms();
+                        PhoneFactory.getMetricsCollector().clearAtomsStorage();
                     }
                     return;
             }
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index e4aff4c..e5a5c8f 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.telephony.Annotation;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.BarringInfo;
@@ -32,9 +33,13 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager.DataEnabledReason;
+import android.telephony.TelephonyManager.EmergencyCallbackModeStopReason;
+import android.telephony.TelephonyManager.EmergencyCallbackModeType;
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.MediaQualityStatus;
 
 import com.android.telephony.Rlog;
 
@@ -142,15 +147,28 @@
         mTelephonyRegistryMgr.notifyCellInfoChanged(subId, cellInfo);
     }
 
-    public void notifyPreciseCallState(Phone sender) {
+    /**
+     * Notify precise call state of foreground, background and ringing call states.
+     *
+     * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId} for
+     *                   ringing, foreground & background calls.
+     * @param imsCallServiceTypes Array of IMS call service type for ringing, foreground &
+     *                        background calls.
+     * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls.
+     */
+    public void notifyPreciseCallState(Phone sender, String[] imsCallIds,
+            @Annotation.ImsCallServiceType int[] imsCallServiceTypes,
+            @Annotation.ImsCallType int[] imsCallTypes) {
         Call ringingCall = sender.getRingingCall();
         Call foregroundCall = sender.getForegroundCall();
         Call backgroundCall = sender.getBackgroundCall();
+
         if (ringingCall != null && foregroundCall != null && backgroundCall != null) {
-            mTelephonyRegistryMgr.notifyPreciseCallState(sender.getPhoneId(), sender.getSubId(),
-                    convertPreciseCallState(ringingCall.getState()),
+            int[] callStates = {convertPreciseCallState(ringingCall.getState()),
                     convertPreciseCallState(foregroundCall.getState()),
-                    convertPreciseCallState(backgroundCall.getState()));
+                    convertPreciseCallState(backgroundCall.getState())};
+            mTelephonyRegistryMgr.notifyPreciseCallState(sender.getPhoneId(), sender.getSubId(),
+                    callStates, imsCallIds, imsCallServiceTypes, imsCallTypes);
         }
     }
 
@@ -223,6 +241,12 @@
     }
 
     @Override
+    public void notifyMediaQualityStatusChanged(Phone sender, MediaQualityStatus status) {
+        mTelephonyRegistryMgr.notifyMediaQualityStatusChanged(
+                sender.getPhoneId(), sender.getSubId(), status);
+    }
+
+    @Override
     public void notifyRegistrationFailed(Phone sender, @NonNull CellIdentity cellIdentity,
             @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) {
         mTelephonyRegistryMgr.notifyRegistrationFailed(sender.getPhoneId(), sender.getSubId(),
@@ -262,6 +286,18 @@
                 sender.getSubId(), linkCapacityEstimateList);
     }
 
+    @Override
+    public void notifyCallbackModeStarted(Phone sender, @EmergencyCallbackModeType int type) {
+        mTelephonyRegistryMgr.notifyCallBackModeStarted(sender.getPhoneId(),
+                sender.getSubId(), type);
+    }
+
+    @Override
+    public void notifyCallbackModeStopped(Phone sender, @EmergencyCallbackModeType int type,
+            @EmergencyCallbackModeStopReason int reason) {
+        mTelephonyRegistryMgr.notifyCallbackModeStopped(sender.getPhoneId(),
+                sender.getSubId(), type, reason);
+    }
     /**
      * 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..ecc6208 100644
--- a/src/java/com/android/internal/telephony/DeviceStateMonitor.java
+++ b/src/java/com/android/internal/telephony/DeviceStateMonitor.java
@@ -20,6 +20,7 @@
 import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE;
 import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED;
 import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
 
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
@@ -669,7 +670,7 @@
                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN);
         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000);
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+        if (mPhone.getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
             mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                     LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.NGRAN);
         }
diff --git a/src/java/com/android/internal/telephony/DisplayInfoController.java b/src/java/com/android/internal/telephony/DisplayInfoController.java
index f1e2608..567331d 100644
--- a/src/java/com/android/internal/telephony/DisplayInfoController.java
+++ b/src/java/com/android/internal/telephony/DisplayInfoController.java
@@ -21,9 +21,7 @@
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.telephony.AccessNetworkConstants;
 import android.telephony.AnomalyReporter;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
@@ -47,8 +45,6 @@
  * TelephonyDisplayInfo via {@link #getTelephonyDisplayInfo}.
  */
 public class DisplayInfoController extends Handler {
-    private static final String TAG = "DisplayInfoController";
-
     private final String mLogTag;
     private final LocalLog mLocalLog = new LocalLog(128);
 
@@ -106,12 +102,10 @@
      * 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,
-                mNetworkTypeController.getOverrideNetworkType(), mServiceState.getRoaming());
+        TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(
+                mNetworkTypeController.getDataNetworkType(),
+                mNetworkTypeController.getOverrideNetworkType(),
+                mServiceState.getRoaming());
         if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
             logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
                     + newDisplayInfo);
@@ -149,7 +143,7 @@
             }
         } catch (InvalidArgumentException e) {
             logel(e.getMessage());
-            AnomalyReporter.reportAnomaly(UUID.fromString("3aa92a2c-94ed-46a0-a744-d6b1dfec2a55"),
+            AnomalyReporter.reportAnomaly(UUID.fromString("3aa92a2c-94ed-46a0-a744-d6b1dfec2a56"),
                     e.getMessage(), mPhone.getCarrierId());
         }
     }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
old mode 100755
new mode 100644
index 7738b44..d76ee19
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -45,6 +45,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.telephony.Rlog;
 
@@ -480,16 +482,29 @@
             disableDataCallInEmergencyCall(dialString);
 
             // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
-            if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
+            if (!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
                 mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
                         mPendingMO.getEmergencyNumberInfo(),
-                        mPendingMO.hasKnownUserIntentEmergency(),
-                        clirMode, obtainCompleteMessage());
+                        mPendingMO.hasKnownUserIntentEmergency(), clirMode,
+                        obtainCompleteMessage());
+            } else if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                mPendingCallInEcm = true;
+                final int finalClirMode = clirMode;
+                Runnable onComplete = new Runnable() {
+                    @Override
+                    public void run() {
+                        mCi.dial(mPendingMO.getAddress(), mPendingMO.isEmergencyCall(),
+                        mPendingMO.getEmergencyNumberInfo(),
+                        mPendingMO.hasKnownUserIntentEmergency(), finalClirMode,
+                        obtainCompleteMessage());
+                    }
+                };
+                EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete);
             } else {
                 mPhone.exitEmergencyCallbackMode();
-                mPhone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
-                mPendingCallClirMode=clirMode;
-                mPendingCallInEcm=true;
+                mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
+                mPendingCallClirMode = clirMode;
+                mPendingCallInEcm = true;
             }
         }
 
@@ -959,6 +974,8 @@
                             } else {
                                 newUnknownConnectionCdma = mConnections[i];
                             }
+                        } else if (hangupWaitingCallSilently(i)) {
+                            return;
                         }
                     }
                 }
@@ -1010,6 +1027,9 @@
 
                 if (mConnections[i].getCall() == mRingingCall) {
                     newRinging = mConnections[i];
+                    if (hangupWaitingCallSilently(i)) {
+                        return;
+                    }
                 } // else something strange happened
                 hasNonHangupStateChanged = true;
             } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
@@ -1819,6 +1839,10 @@
     }
 
     private boolean isEmcRetryCause(int causeCode) {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            log("isEmcRetryCause AP based domain selection ignores the cause");
+            return false;
+        }
         if (causeCode == CallFailCause.EMC_REDIAL_ON_IMS ||
             causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI) {
             return true;
@@ -1898,4 +1922,22 @@
     public void cleanupCalls() {
         pollCallsWhenSafe();
     }
+
+    private boolean hangupWaitingCallSilently(int index) {
+        if (index < 0 || index >= mConnections.length) return false;
+
+        GsmCdmaConnection newRinging = mConnections[index];
+        if (newRinging == null) return false;
+
+        if ((mPhone.getTerminalBasedCallWaitingState(true)
+                        == CallWaitingController.TERMINAL_BASED_NOT_ACTIVATED)
+                && (newRinging.getState() == Call.State.WAITING)) {
+            Rlog.d(LOG_TAG, "hangupWaitingCallSilently");
+            newRinging.dispose();
+            mConnections[index] = null;
+            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index d9d6b3c..5eae061 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -16,6 +16,11 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS_PS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_UNKNOWN;
+
 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;
@@ -32,6 +37,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
@@ -40,6 +46,7 @@
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.database.SQLException;
+import android.hardware.radio.modem.ImeiInfo;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Build;
@@ -57,6 +64,7 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Telephony;
 import android.sysprop.TelephonyProperties;
@@ -64,10 +72,13 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.RadioPowerState;
+import android.telephony.AnomalyReporter;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierConfigManager;
+import android.telephony.CellBroadcastIdRange;
 import android.telephony.CellIdentity;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.LinkCapacityEstimate;
@@ -81,6 +92,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.telephony.UssdResponse;
+import android.telephony.ims.ImsCallProfile;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -92,7 +104,9 @@
 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.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.gsm.GsmMmiCode;
 import com.android.internal.telephony.gsm.SsData;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
@@ -129,6 +143,9 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -155,6 +172,8 @@
     // Key used to read/write the SIM IMSI used for storing the voice mail
     private static final String VM_SIM_IMSI = "vm_sim_imsi_key";
     /** List of Registrants to receive Supplementary Service Notifications. */
+    // Key used to read/write the current sub Id. Updated on SIM loaded.
+    public static final String CURR_SUBID = "curr_subid";
     private RegistrantList mSsnRegistrants = new RegistrantList();
 
     //CDMA
@@ -225,10 +244,17 @@
 
     private final RegistrantList mVolteSilentRedialRegistrants = new RegistrantList();
     private DialArgs mDialArgs = null;
-
+    private final RegistrantList mEmergencyDomainSelectedRegistrants = new RegistrantList();
     private String mImei;
     private String mImeiSv;
     private String mVmNumber;
+    private int mImeiType = IMEI_TYPE_UNKNOWN;
+
+    @VisibleForTesting
+    public CellBroadcastConfigTracker mCellBroadcastConfigTracker =
+            CellBroadcastConfigTracker.make(this, null, true);
+
+    private boolean mIsNullCipherAndIntegritySupported = false;
 
     // Create Cfu (Call forward unconditional) so that dialing number &
     // mOnComplete (Message object passed by client) can be packed &
@@ -273,6 +299,7 @@
     private final CarrierPrivilegesTracker mCarrierPrivilegesTracker;
 
     private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener;
+    private final CallWaitingController mCallWaitingController;
 
     // Constructors
 
@@ -342,24 +369,22 @@
 
         mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
         mSST.registerForVoiceRegStateOrRatChanged(this, EVENT_VRS_OR_RAT_CHANGED, null);
+        mSST.getServiceStateStats().registerDataNetworkControllerCallback();
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService.registerCallback(new SubscriptionManagerServiceCallback(
-                    this::post) {
-                @Override
-                public void onUiccApplicationsEnabled(int subId) {
-                    reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
-                }
-            });
-        } else {
-            SubscriptionController.getInstance().registerForUiccAppsEnabled(this,
-                    EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED, null, false);
-        }
+        mSubscriptionManagerService.registerCallback(new SubscriptionManagerServiceCallback(
+                this::post) {
+            @Override
+            public void onUiccApplicationsEnabledChanged(int subId) {
+                reapplyUiccAppsEnablementIfNeeded(ENABLE_UICC_APPS_MAX_RETRIES);
+            }
+        });
 
         mLinkBandwidthEstimator = mTelephonyComponentFactory
                 .inject(LinkBandwidthEstimator.class.getName())
                 .makeLinkBandwidthEstimator(this);
 
+        mCallWaitingController = new CallWaitingController(this);
+
         loadTtyMode();
 
         CallManager.getInstance().registerPhone(this);
@@ -397,6 +422,17 @@
                 int newPreferredTtyMode = intent.getIntExtra(
                         TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
                 updateUiTtyMode(newPreferredTtyMode);
+            } else if (TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED.equals(action)) {
+                if (mPhoneId == intent.getIntExtra(
+                        SubscriptionManager.EXTRA_SLOT_INDEX,
+                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
+                    int simState = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE,
+                            TelephonyManager.SIM_STATE_UNKNOWN);
+                    if (simState == TelephonyManager.SIM_STATE_LOADED
+                            && currentSlotSubIdChanged()) {
+                        setNetworkSelectionModeAutomatic(null);
+                    }
+                }
             }
         }
     };
@@ -453,15 +489,20 @@
         mCi.registerForLceInfo(this, EVENT_LINK_CAPACITY_CHANGED, null);
         mCi.registerForCarrierInfoForImsiEncryption(this,
                 EVENT_RESET_CARRIER_KEY_IMSI_ENCRYPTION, null);
+        mCi.registerForTriggerImsDeregistration(this, EVENT_IMS_DEREGISTRATION_TRIGGERED, null);
+        mCi.registerForNotifyAnbr(this, EVENT_TRIGGER_NOTIFY_ANBR, null);
         IntentFilter filter = new IntentFilter(
                 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
         filter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+        filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
         mContext.registerReceiver(mBroadcastReceiver, filter,
                 android.Manifest.permission.MODIFY_PHONE_STATE, null, Context.RECEIVER_EXPORTED);
 
         mCDM = new CarrierKeyDownloadManager(this);
         mCIM = new CarrierInfoManager();
+
+        initializeCarrierApps();
     }
 
     private void initRatSpecific(int precisePhoneType) {
@@ -484,8 +525,12 @@
             // This is needed to handle phone process crashes
             mIsPhoneInEcmState = getInEcmMode();
             if (mIsPhoneInEcmState) {
-                // Send a message which will invoke handleExitEmergencyCallbackMode
-                mCi.exitEmergencyCallbackMode(null);
+                if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                    EmergencyStateTracker.getInstance().exitEmergencyCallbackMode();
+                } else {
+                    // Send a message which will invoke handleExitEmergencyCallbackMode
+                    mCi.exitEmergencyCallbackMode(null);
+                }
             }
 
             mCi.setPhoneType(PhoneConstants.PHONE_TYPE_CDMA);
@@ -508,11 +553,7 @@
                 logd("update icc_operator_numeric=" + operatorNumeric);
                 tm.setSimOperatorNumericForPhone(mPhoneId, operatorNumeric);
 
-                if (isSubscriptionManagerServiceEnabled()) {
-                    mSubscriptionManagerService.setMccMnc(getSubId(), operatorNumeric);
-                } else {
-                    SubscriptionController.getInstance().setMccMnc(operatorNumeric, getSubId());
-                }
+                mSubscriptionManagerService.setMccMnc(getSubId(), operatorNumeric);
 
                 // Sets iso country property by retrieving from build-time system property
                 String iso = "";
@@ -524,11 +565,7 @@
 
                 logd("init: set 'gsm.sim.operator.iso-country' to iso=" + iso);
                 tm.setSimCountryIsoForPhone(mPhoneId, iso);
-                if (isSubscriptionManagerServiceEnabled()) {
-                    mSubscriptionManagerService.setCountryIso(getSubId(), iso);
-                } else {
-                    SubscriptionController.getInstance().setCountryIso(iso, getSubId());
-                }
+                mSubscriptionManagerService.setCountryIso(getSubId(), iso);
 
                 // Updates MCC MNC device configuration information
                 logd("update mccmnc=" + operatorNumeric);
@@ -540,6 +577,31 @@
         }
     }
 
+    /**
+     * Initialize the carrier apps.
+     */
+    private void initializeCarrierApps() {
+        // Only perform on the default phone. There is no need to do it twice on the DSDS device.
+        if (mPhoneId != 0) return;
+
+        logd("initializeCarrierApps");
+        mContext.registerReceiverForAllUsers(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                // Remove this line after testing
+                if (Intent.ACTION_USER_FOREGROUND.equals(intent.getAction())) {
+                    UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
+                    // If couldn't get current user ID, guess it's 0.
+                    CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
+                            TelephonyManager.getDefault(),
+                            userHandle != null ? userHandle.getIdentifier() : 0, mContext);
+                }
+            }
+        }, new IntentFilter(Intent.ACTION_USER_FOREGROUND), null, null);
+        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
+                TelephonyManager.getDefault(), ActivityManager.getCurrentUser(), mContext);
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean isPhoneTypeGsm() {
         return mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM;
@@ -737,7 +799,10 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public void notifyPreciseCallStateChanged() {
         /* we'd love it if this was package-scoped*/
-        super.notifyPreciseCallStateChangedP();
+        AsyncResult ar = new AsyncResult(null, this, null);
+        mPreciseCallStateRegistrants.notifyRegistrants(ar);
+
+        mNotifier.notifyPreciseCallState(this, null, null, null);
     }
 
     public void notifyNewRingingConnection(Connection c) {
@@ -1332,8 +1397,7 @@
         // 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 */);
+            isEmergency = getEmergencyNumberTracker().isEmergencyNumber(dialString);
             logi("dial; isEmergency=" + isEmergency
                     + " (based on this phone only); globalIsEmergency="
                     + tm.isEmergencyNumber(dialString));
@@ -1342,6 +1406,12 @@
             logi("dial; isEmergency=" + isEmergency + " (based on all phones)");
         }
 
+        // Undetectable emergeny number indicated by new domain selection service
+        if (dialArgs.isEmergency) {
+            logi("dial; isEmergency=" + isEmergency + " (domain selection module)");
+            isEmergency = true;
+        }
+
         /** Check if the call is Wireless Priority Service call */
         boolean isWpsCall = dialString != null ? (dialString.startsWith(PREFIX_WPS)
                 || dialString.startsWith(PREFIX_WPS_CLIR_ACTIVATE)
@@ -1367,6 +1437,55 @@
         boolean useImsForCall = useImsForCall(dialArgs)
                 && (isWpsCall ? allowWpsOverIms : true);
 
+        Bundle extras = dialArgs.intentExtras;
+        if (extras != null && extras.containsKey(PhoneConstants.EXTRA_COMPARE_DOMAIN)) {
+            int domain = extras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN);
+            if (!isEmergency && (!isMmiCode || isPotentialUssdCode)) {
+                if ((domain == DOMAIN_PS && !useImsForCall)
+                        || (domain == DOMAIN_CS && useImsForCall)
+                        || domain == DOMAIN_UNKNOWN || domain == DOMAIN_CS_PS) {
+                    loge("[Anomaly] legacy-useImsForCall:" + useImsForCall
+                            + ", NCDS-domain:" + domain);
+
+                    AnomalyReporter.reportAnomaly(
+                            UUID.fromString("bfae6c2e-ca2f-4121-b167-9cad26a3b353"),
+                            "Domain selection results don't match. useImsForCall:"
+                                    + useImsForCall + ", NCDS-domain:" + domain);
+                }
+            }
+            extras.remove(PhoneConstants.EXTRA_COMPARE_DOMAIN);
+        }
+
+        // Only when the domain selection service is supported, EXTRA_DIAL_DOMAIN extra shall exist.
+        if (extras != null && extras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN)) {
+            int domain = extras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN);
+            logi("dial domain=" + domain);
+            useImsForCall = false;
+            useImsForUt = false;
+            useImsForEmergency = false;
+            if (domain == DOMAIN_PS) {
+                if (isEmergency) {
+                    useImsForEmergency = true;
+                } else if (!isMmiCode || isPotentialUssdCode) {
+                    useImsForCall = true;
+                } else {
+                    // should not reach here
+                    loge("dial unexpected Ut domain selection, ignored");
+                }
+            } else if (domain == PhoneConstants.DOMAIN_NON_3GPP_PS) {
+                if (isEmergency) {
+                    useImsForEmergency = true;
+                    extras.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE,
+                            String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN));
+                } else {
+                    // should not reach here
+                    loge("dial DOMAIN_NON_3GPP_PS should be used only for emergency calls");
+                }
+            }
+
+            extras.remove(PhoneConstants.EXTRA_DIAL_DOMAIN);
+        }
+
         if (DBG) {
             logi("useImsForCall=" + useImsForCall
                     + ", useOnlyDialedSimEccList=" + useOnlyDialedSimEccList
@@ -1463,10 +1582,13 @@
         }
         if (DBG) logd("Trying (non-IMS) CS call");
         if (isDialedNumberSwapped && isEmergency) {
-            // Triggers ECM when CS call ends only for test emergency calls using
-            // ril.test.emergencynumber.
-            mIsTestingEmergencyCallbackMode = true;
-            mCi.testingEmergencyCall();
+            // If domain selection is enabled, ECM testing is handled in EmergencyStateTracker
+            if (!DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                // Triggers ECM when CS call ends only for test emergency calls using
+                // ril.test.emergencynumber.
+                mIsTestingEmergencyCallbackMode = true;
+                mCi.testingEmergencyCall();
+            }
         }
 
         chosenPhoneConsumer.accept(this);
@@ -1698,7 +1820,7 @@
     public void setRadioPower(boolean power, boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply) {
         setRadioPowerForReason(power, forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply,
-                Phone.RADIO_POWER_REASON_USER);
+                TelephonyManager.RADIO_POWER_REASON_USER);
     }
 
     @Override
@@ -1708,6 +1830,11 @@
                 forceApply, reason);
     }
 
+    @Override
+    public Set<Integer> getRadioPowerOffReasons() {
+        return mSST.getRadioPowerOffReasons();
+    }
+
     private void storeVoiceMailNumber(String number) {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
@@ -1857,6 +1984,11 @@
         return mImei;
     }
 
+    @Override
+    public int getImeiType() {
+        return mImeiType;
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public String getEsn() {
@@ -2452,6 +2584,7 @@
         }
 
         Phone imsPhone = mImsPhone;
+
         if (useSsOverIms(onComplete)) {
             imsPhone.getOutgoingCallerIdDisplay(onComplete);
             return;
@@ -2534,6 +2667,8 @@
             return;
         }
 
+        if (mCallWaitingController.getCallWaiting(onComplete)) return;
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.getCallWaiting(onComplete);
@@ -2585,6 +2720,8 @@
             return;
         }
 
+        if (mCallWaitingController.setCallWaiting(enable, serviceClass, onComplete)) return;
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.setCallWaiting(enable, onComplete);
@@ -2615,6 +2752,23 @@
     }
 
     @Override
+    public int getTerminalBasedCallWaitingState(boolean forCsOnly) {
+        return mCallWaitingController.getTerminalBasedCallWaitingState(forCsOnly);
+    }
+
+    @Override
+    public void setTerminalBasedCallWaitingStatus(int state) {
+        if (mImsPhone != null) {
+            mImsPhone.setTerminalBasedCallWaitingStatus(state);
+        }
+    }
+
+    @Override
+    public void setTerminalBasedCallWaitingSupported(boolean supported) {
+        mCallWaitingController.setTerminalBasedCallWaitingSupported(supported);
+    }
+
+    @Override
     public void getAvailableNetworks(Message response) {
         if (isPhoneTypeGsm() || isPhoneTypeCdmaLte()) {
             Message msg = obtainMessage(EVENT_GET_AVAILABLE_NETWORKS_DONE, response);
@@ -2884,11 +3038,12 @@
 
     private void handleRadioAvailable() {
         mCi.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
-
+        mCi.getImei(obtainMessage(EVENT_GET_DEVICE_IMEI_DONE));
         mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
         mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));
         mCi.areUiccApplicationsEnabled(obtainMessage(EVENT_GET_UICC_APPS_ENABLEMENT_DONE));
 
+        handleNullCipherEnabledChange();
         startLceAfterRadioIsAvailable();
     }
 
@@ -2934,7 +3089,21 @@
                 handleRadioAvailable();
             }
             break;
-
+            case EVENT_GET_DEVICE_IMEI_DONE :
+                ar = (AsyncResult)msg.obj;
+                if (ar.exception != null || ar.result == null) {
+                    loge("Exception received : " + ar.exception);
+                    break;
+                }
+                ImeiInfo imeiInfo = (ImeiInfo) ar.result;
+                if (!TextUtils.isEmpty(imeiInfo.imei)) {
+                    mImeiType = imeiInfo.type;
+                    mImei = imeiInfo.imei;
+                    mImeiSv = imeiInfo.svn;
+                } else {
+                    // TODO Report telephony anomaly
+                }
+                break;
             case EVENT_GET_DEVICE_IDENTITY_DONE:{
                 ar = (AsyncResult)msg.obj;
 
@@ -2942,8 +3111,10 @@
                     break;
                 }
                 String[] respId = (String[])ar.result;
-                mImei = respId[0];
-                mImeiSv = respId[1];
+                if (TextUtils.isEmpty(mImei)) {
+                    mImei = respId[0];
+                    mImeiSv = respId[1];
+                }
                 mEsn  =  respId[2];
                 mMeid =  respId[3];
                 // some modems return all 0's instead of null/empty string when MEID is unavailable
@@ -2968,12 +3139,16 @@
                 logd("Event EVENT_MODEM_RESET Received" + " isInEcm = " + isInEcm()
                         + " isPhoneTypeGsm = " + isPhoneTypeGsm() + " mImsPhone = " + mImsPhone);
                 if (isInEcm()) {
-                    if (isPhoneTypeGsm()) {
-                        if (mImsPhone != null) {
-                            mImsPhone.handleExitEmergencyCallbackMode();
-                        }
+                    if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                        EmergencyStateTracker.getInstance().exitEmergencyCallbackMode();
                     } else {
-                        handleExitEmergencyCallbackMode(msg);
+                        if (isPhoneTypeGsm()) {
+                            if (mImsPhone != null) {
+                                mImsPhone.handleExitEmergencyCallbackMode();
+                            }
+                        } else {
+                            handleExitEmergencyCallbackMode(msg);
+                        }
                     }
                 }
             }
@@ -3343,12 +3518,64 @@
                 logd("EVENT_SUBSCRIPTIONS_CHANGED");
                 updateUsageSetting();
                 break;
+            case EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE:
+                logd("EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE");
+                ar = (AsyncResult) msg.obj;
+                if (ar == null || ar.exception == null) {
+                    mIsNullCipherAndIntegritySupported = true;
+                    return;
+                }
+                CommandException.Error error = ((CommandException) ar.exception).getCommandError();
+                mIsNullCipherAndIntegritySupported = !error.equals(
+                        CommandException.Error.REQUEST_NOT_SUPPORTED);
+                break;
 
+            case EVENT_IMS_DEREGISTRATION_TRIGGERED:
+                logd("EVENT_IMS_DEREGISTRATION_TRIGGERED");
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception == null) {
+                    mImsPhone.triggerImsDeregistration(((int[]) ar.result)[0]);
+                } else {
+                    Rlog.e(LOG_TAG, "Unexpected unsol with exception", ar.exception);
+                }
+                break;
+
+            case EVENT_TRIGGER_NOTIFY_ANBR:
+                logd("EVENT_TRIGGER_NOTIFY_ANBR");
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception == null) {
+                    if (mImsPhone != null) {
+                        mImsPhone.triggerNotifyAnbr(((int[]) ar.result)[0], ((int[]) ar.result)[1],
+                                ((int[]) ar.result)[2]);
+                    }
+                }
+                break;
             default:
                 super.handleMessage(msg);
         }
     }
 
+    /**
+     * Check if a different SIM is inserted at this slot from the last time. Storing last subId
+     * in SharedPreference for now to detect SIM change.
+     *
+     * @return {@code true} if current slot mapping changed; {@code false} otherwise.
+     */
+    private boolean currentSlotSubIdChanged() {
+        SharedPreferences sp =
+                PreferenceManager.getDefaultSharedPreferences(mContext);
+        int storedSubId = sp.getInt(CURR_SUBID + mPhoneId, -1);
+        boolean changed = storedSubId != getSubId();
+        if (changed) {
+            // Update stored subId
+            SharedPreferences.Editor editor = sp.edit();
+            editor.putInt(CURR_SUBID + mPhoneId, getSubId());
+            editor.apply();
+        }
+        Rlog.d(LOG_TAG, "currentSlotSubIdChanged: changed=" + changed);
+        return changed;
+    }
+
     public UiccCardApplication getUiccCardApplication() {
         if (isPhoneTypeGsm()) {
             return mUiccController.getUiccCardApplication(mPhoneId, UiccController.APP_FAM_3GPP);
@@ -3715,6 +3942,10 @@
 
     //CDMA
     private void handleEnterEmergencyCallbackMode(Message msg) {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM enter event.");
+            return;
+        }
         if (DBG) {
             Rlog.d(LOG_TAG, "handleEnterEmergencyCallbackMode, isInEcm()="
                     + isInEcm());
@@ -3738,6 +3969,10 @@
 
     //CDMA
     private void handleExitEmergencyCallbackMode(Message msg) {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM exit event.");
+            return;
+        }
         AsyncResult ar = (AsyncResult)msg.obj;
         if (DBG) {
             Rlog.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , isInEcm="
@@ -3780,6 +4015,7 @@
      * otherwise, restart Ecm timer and notify apps the timer is restarted.
      */
     public void handleTimerInEmergencyCallbackMode(int action) {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) return;
         switch(action) {
             case CANCEL_ECM_TIMER:
                 removeCallbacks(mExitEcmRunnable);
@@ -4193,6 +4429,7 @@
     @Override
     public void setImsRegistrationState(boolean registered) {
         mSST.setImsRegistrationState(registered);
+        mCallWaitingController.setImsRegistrationState(registered);
     }
 
     @Override
@@ -4254,6 +4491,13 @@
                 " mTelecomVoiceServiceStateOverride=" + mTelecomVoiceServiceStateOverride + "("
                         + ServiceState.rilServiceStateToString(mTelecomVoiceServiceStateOverride)
                         + ")");
+        pw.println(" mUiccApplicationsEnabled=" + mUiccApplicationsEnabled);
+        pw.flush();
+        try {
+            mCallWaitingController.dump(pw);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
         pw.flush();
     }
 
@@ -4373,7 +4617,7 @@
         if (subInfo == null || TextUtils.isEmpty(subInfo.getCountryIso())) {
             return null;
         }
-        return subInfo.getCountryIso().toUpperCase();
+        return subInfo.getCountryIso().toUpperCase(Locale.ROOT);
     }
 
     public void notifyEcbmTimerReset(Boolean flag) {
@@ -4479,6 +4723,27 @@
         mVolteSilentRedialRegistrants.notifyRegistrants(ar);
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public void registerForEmergencyDomainSelected(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mEmergencyDomainSelectedRegistrants.addUnique(h, what, obj);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void unregisterForEmergencyDomainSelected(@NonNull Handler h) {
+        mEmergencyDomainSelectedRegistrants.remove(h);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void notifyEmergencyDomainSelected(@TransportType int transportType) {
+        logd("notifyEmergencyDomainSelected transportType=" + transportType);
+        mEmergencyDomainSelectedRegistrants.notifyRegistrants(
+                new AsyncResult(null, transportType, null));
+    }
+
     /**
      * Sets the SIM voice message waiting indicator records.
      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
@@ -4639,6 +4904,8 @@
         // If no card is present or we don't have mUiccApplicationsEnabled yet, do nothing.
         if (slot == null || slot.getCardState() != IccCardStatus.CardState.CARDSTATE_PRESENT
                 || mUiccApplicationsEnabled == null) {
+            loge("reapplyUiccAppsEnablementIfNeeded: slot state="
+                    + (slot != null ? slot.getCardState() : null));
             return;
         }
 
@@ -4651,18 +4918,12 @@
             return;
         }
 
-        SubscriptionInfo info;
-        if (isSubscriptionManagerServiceEnabled()) {
-            info = mSubscriptionManagerService
-                    .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag())
-                    .stream()
-                    .filter(subInfo -> subInfo.getIccId().equals(IccUtils.stripTrailingFs(iccId)))
-                    .findFirst()
-                    .orElse(null);
-        } else {
-            info = SubscriptionController.getInstance().getSubInfoForIccId(
-                    IccUtils.stripTrailingFs(iccId));
-        }
+        SubscriptionInfo info = mSubscriptionManagerService
+                .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag())
+                .stream()
+                .filter(subInfo -> subInfo.getIccId().equals(IccUtils.stripTrailingFs(iccId)))
+                .findFirst()
+                .orElse(null);
 
         logd("reapplyUiccAppsEnablementIfNeeded: retries=" + retries + ", subInfo=" + info);
 
@@ -4767,18 +5028,10 @@
                 config.getBoolean(CarrierConfigManager.KEY_VONR_ON_BY_DEFAULT_BOOL);
 
         int setting = -1;
-        if (isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(getSubId());
-            if (subInfo != null) {
-                setting = subInfo.getNrAdvancedCallingEnabled();
-            }
-        } else {
-            String result = SubscriptionController.getInstance().getSubscriptionProperty(
-                    getSubId(), SubscriptionManager.NR_ADVANCED_CALLING_ENABLED);
-            if (result != null) {
-                setting = Integer.parseInt(result);
-            }
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(getSubId());
+        if (subInfo != null) {
+            setting = subInfo.getNrAdvancedCallingEnabled();
         }
 
         logd("VoNR setting from telephony.db:"
@@ -4854,6 +5107,22 @@
     }
 
     /**
+     * Return current cell broadcast ranges.
+     */
+    public List<CellBroadcastIdRange> getCellBroadcastIdRanges() {
+        return mCellBroadcastConfigTracker.getCellBroadcastIdRanges();
+    }
+
+    /**
+     * Set reception of cell broadcast messages with the list of the given ranges.
+     */
+    @Override
+    public void setCellBroadcastIdRanges(
+            @NonNull List<CellBroadcastIdRange> ranges, Consumer<Integer> callback) {
+        mCellBroadcastConfigTracker.setCellBroadcastIdRanges(ranges, callback);
+    }
+
+    /**
      * The following function checks if supplementary service request is blocked due to FDN.
      * @param requestType request type associated with the supplementary service
      * @param serviceType supplementary service type
@@ -4864,4 +5133,21 @@
         ArrayList<String> controlStrings = GsmMmiCode.getControlStrings(requestType, serviceType);
         return FdnUtils.isSuppServiceRequestBlockedByFdn(mPhoneId, controlStrings, getCountryIso());
     }
-}
\ No newline at end of file
+
+    @Override
+    public void handleNullCipherEnabledChange() {
+        if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, true)) {
+            logi("Not handling null cipher update. Feature disabled by DeviceConfig.");
+            return;
+        }
+        mCi.setNullCipherAndIntegrityEnabled(
+                getNullCipherAndIntegrityEnabledPreference(),
+                obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE));
+    }
+
+    @Override
+    public boolean isNullCipherAndIntegritySupported() {
+        return mIsNullCipherAndIntegritySupported;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/HalVersion.java b/src/java/com/android/internal/telephony/HalVersion.java
index f83d790..c05111b 100644
--- a/src/java/com/android/internal/telephony/HalVersion.java
+++ b/src/java/com/android/internal/telephony/HalVersion.java
@@ -25,6 +25,9 @@
  */
 public class HalVersion implements Comparable<HalVersion> {
 
+    /** The HAL Version indicating that the version is unsupported */
+    public static final HalVersion UNSUPPORTED = new HalVersion(-2, -2);
+
     /** The HAL Version indicating that the version is unknown or invalid */
     public static final HalVersion UNKNOWN = new HalVersion(-1, -1);
 
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 742cc90..ab62aa4 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -39,6 +39,7 @@
 import com.android.telephony.Rlog;
 
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -337,7 +338,10 @@
         }
 
         efid = updateEfForIccType(efid);
-        if (DBG) logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid).toUpperCase());
+        if (DBG) {
+            logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid)
+                    .toUpperCase(Locale.ROOT));
+        }
 
         checkThread();
         Request loadRequest = new Request();
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index 7a128c0..b7c7e7b 100644
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -37,6 +37,7 @@
 import com.android.telephony.Rlog;
 
 import java.util.List;
+import java.util.Locale;
 
 /**
  * {@hide}
@@ -424,7 +425,7 @@
 
     private MatrixCursor loadFromEf(int efType, int subId) {
         if (DBG) log("loadFromEf: efType=0x" +
-                Integer.toHexString(efType).toUpperCase() + ", subscription=" + subId);
+                Integer.toHexString(efType).toUpperCase(Locale.ROOT) + ", subscription=" + subId);
 
         List<AdnRecord> adnRecords = null;
         try {
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index d3e6a0d..2d77631 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -176,6 +176,41 @@
         mSmsPermissions = smsPermissions;
     }
 
+    /**
+     * PhoneFactory Dependencies for testing.
+     */
+    @VisibleForTesting
+    public interface PhoneFactoryProxy {
+        Phone getPhone(int index);
+        Phone getDefaultPhone();
+        Phone[] getPhones();
+    }
+
+    private PhoneFactoryProxy mPhoneFactoryProxy = new PhoneFactoryProxy() {
+        @Override
+        public Phone getPhone(int index) {
+            return PhoneFactory.getPhone(index);
+        }
+
+        @Override
+        public Phone getDefaultPhone() {
+            return PhoneFactory.getDefaultPhone();
+        }
+
+        @Override
+        public Phone[] getPhones() {
+            return PhoneFactory.getPhones();
+        }
+    };
+
+    /**
+     * Overrides PhoneFactory dependencies for testing.
+     */
+    @VisibleForTesting
+    public void setPhoneFactoryProxy(PhoneFactoryProxy proxy) {
+        mPhoneFactoryProxy = proxy;
+    }
+
     private void enforceNotOnHandlerThread(String methodName) {
         if (Looper.myLooper() == mHandler.getLooper()) {
             throw new RuntimeException("This method " + methodName + " will deadlock if called from"
@@ -457,11 +492,11 @@
      */
     public void sendText(String callingPackage, String destAddr, String scAddr,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessageForNonDefaultSmsApp, long messageId) {
+            boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck) {
         sendTextInternal(callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent,
                 persistMessageForNonDefaultSmsApp, SMS_MESSAGE_PRIORITY_NOT_SPECIFIED,
                 false /* expectMore */, SMS_MESSAGE_PERIOD_NOT_SPECIFIED, false /* isForVvm */,
-                messageId);
+                messageId, skipShortCodeCheck);
     }
 
     /**
@@ -481,6 +516,16 @@
                 SMS_MESSAGE_PERIOD_NOT_SPECIFIED, isForVvm, 0L /* messageId */);
     }
 
+
+    private void sendTextInternal(String callingPackage, String destAddr, String scAddr,
+            String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
+            boolean persistMessageForNonDefaultSmsApp, int priority, boolean expectMore,
+            int validityPeriod, boolean isForVvm, long messageId) {
+        sendTextInternal(callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent,
+                persistMessageForNonDefaultSmsApp, priority, expectMore, validityPeriod, isForVvm,
+                messageId, false);
+    }
+
     /**
      * Send a text based SMS.
      *
@@ -527,12 +572,13 @@
      *  Any Other values including negative considered as Invalid Validity Period of the message.
      * @param messageId An id that uniquely identifies the message requested to be sent.
      *                 Used for logging and diagnostics purposes. The id may be 0.
+     * @param skipShortCodeCheck Skip check for short code type destination address.
      */
 
     private void sendTextInternal(String callingPackage, String destAddr, String scAddr,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
             boolean persistMessageForNonDefaultSmsApp, int priority, boolean expectMore,
-            int validityPeriod, boolean isForVvm, long messageId) {
+            int validityPeriod, boolean isForVvm, long messageId, boolean skipShortCodeCheck) {
         if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
             log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr
                     + " text='" + text + "' sentIntent=" + sentIntent + " deliveryIntent="
@@ -544,7 +590,7 @@
         destAddr = filterDestAddress(destAddr);
         mDispatchersController.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
                 null/*messageUri*/, callingPackage, persistMessageForNonDefaultSmsApp,
-                priority, expectMore, validityPeriod, isForVvm, messageId);
+                priority, expectMore, validityPeriod, isForVvm, messageId, skipShortCodeCheck);
     }
 
     /**
@@ -862,6 +908,7 @@
     public String getSmscAddressFromIccEf(String callingPackage) {
         if (!mSmsPermissions.checkCallingOrSelfCanGetSmscAddress(
                 callingPackage, "getSmscAddressFromIccEf")) {
+            loge("Caller do not have permission to call GetSmscAddress");
             return null;
         }
         enforceNotOnHandlerThread("getSmscAddressFromIccEf");
@@ -883,6 +930,7 @@
     public boolean setSmscAddressOnIccEf(String callingPackage, String smsc) {
         if (!mSmsPermissions.checkCallingOrSelfCanSetSmscAddress(
                 callingPackage, "setSmscAddressOnIccEf")) {
+            loge("Caller do not have permission to call SetSmscAddress");
             return false;
         }
         enforceNotOnHandlerThread("setSmscAddressOnIccEf");
@@ -1452,11 +1500,27 @@
         return null;
     }
 
-    private void notifyIfOutgoingEmergencySms(String destAddr) {
+    @VisibleForTesting
+    public void notifyIfOutgoingEmergencySms(String destAddr) {
+        Phone[] allPhones = mPhoneFactoryProxy.getPhones();
         EmergencyNumber emergencyNumber = mPhone.getEmergencyNumberTracker().getEmergencyNumber(
                 destAddr);
         if (emergencyNumber != null) {
             mPhone.notifyOutgoingEmergencySms(emergencyNumber);
+        } else if (allPhones.length > 1) {
+            // If there are multiple active SIMs, check all instances:
+            for (Phone phone : allPhones) {
+                // If the current iteration was already checked, skip:
+                if (phone.getPhoneId() == mPhone.getPhoneId()) {
+                    continue;
+                }
+                emergencyNumber = phone.getEmergencyNumberTracker()
+                        .getEmergencyNumber(destAddr);
+                if (emergencyNumber != null) {
+                    mPhone.notifyOutgoingEmergencySms(emergencyNumber);
+                    break;
+                }
+            }
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/ImsIndication.java b/src/java/com/android/internal/telephony/ImsIndication.java
new file mode 100644
index 0000000..00652f8
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ImsIndication.java
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import static android.telephony.TelephonyManager.HAL_SERVICE_IMS;
+
+import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CONNECTION_SETUP_FAILURE;
+import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NOTIFY_ANBR;
+import static com.android.internal.telephony.RILConstants.RIL_UNSOL_TRIGGER_IMS_DEREGISTRATION;
+
+import android.hardware.radio.ims.IRadioImsIndication;
+import android.os.AsyncResult;
+import android.telephony.ims.feature.ConnectionFailureInfo;
+
+/**
+ * Interface declaring unsolicited radio indications for IMS APIs.
+ */
+public class ImsIndication extends IRadioImsIndication.Stub {
+    private final RIL mRil;
+
+    public ImsIndication(RIL ril) {
+        mRil = ril;
+    }
+
+    @Override
+    public String getInterfaceHash() {
+        return IRadioImsIndication.HASH;
+    }
+
+    @Override
+    public int getInterfaceVersion() {
+        return IRadioImsIndication.VERSION;
+    }
+
+    /**
+     * Fired by radio when any IMS traffic is not sent to network due to any failure
+     * on cellular networks.
+     *
+     * @param indicationType Type of radio indication.
+     * @param token The token provided by {@link #startImsTraffic}.
+     * @param failureInfo Connection failure information.
+     */
+    public void onConnectionSetupFailure(int indicationType, int token,
+            android.hardware.radio.ims.ConnectionFailureInfo failureInfo) {
+        mRil.processIndication(HAL_SERVICE_IMS, indicationType);
+
+        Object[] response = new Object[2];
+        response[0] = token;
+        response[1] = new ConnectionFailureInfo(
+                RILUtils.convertHalConnectionFailureReason(failureInfo.failureReason),
+                failureInfo.causeCode, failureInfo.waitTimeMillis);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CONNECTION_SETUP_FAILURE, response);
+
+        mRil.mConnectionSetupFailureRegistrants.notifyRegistrants(
+                new AsyncResult(null, response, null));
+    }
+
+    /**
+     * Fired by radio when ANBR is received form the network.
+     *
+     * @param indicationType Type of radio indication.
+     * @param qosSessionId QoS session ID is used to identify media stream such as audio or video.
+     * @param imsdirection Direction of this packet stream (e.g. uplink or downlink).
+     * @param bitsPerSecond The recommended bit rate for the UE
+     *        for a specific logical channel and a specific direction by the network.
+     */
+    public void notifyAnbr(int indicationType, int qosSessionId, int imsdirection,
+            int bitsPerSecond) {
+        mRil.processIndication(HAL_SERVICE_IMS, indicationType);
+
+        int[] response = new int[3];
+        response[0] = qosSessionId;
+        response[1] = imsdirection;
+        response[2] = bitsPerSecond;
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NOTIFY_ANBR, response);
+
+        mRil.mNotifyAnbrRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
+    }
+
+    /**
+     * Requests IMS stack to perform graceful IMS deregistration before radio performing
+     * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+     * the IMS deregistration, which will be notified by telephony via
+     * {@link IRadioIms#updateImsRegistrationInfo()}, or a certain timeout interval to start
+     * the network detach procedure.
+     *
+     * @param indicationType Type of radio indication.
+     * @param reason the reason why the deregistration is triggered.
+     */
+    public void triggerImsDeregistration(int indicationType, int reason) {
+        mRil.processIndication(HAL_SERVICE_IMS, indicationType);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_TRIGGER_IMS_DEREGISTRATION, reason);
+
+        int[] response = new int[1];
+        response[0] = RILUtils.convertHalDeregistrationReason(reason);
+
+        mRil.mTriggerImsDeregistrationRegistrants.notifyRegistrants(
+                new AsyncResult(null, response, null));
+    }
+}
diff --git a/src/java/com/android/internal/telephony/ImsResponse.java b/src/java/com/android/internal/telephony/ImsResponse.java
new file mode 100644
index 0000000..1adc000
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ImsResponse.java
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import static android.telephony.TelephonyManager.HAL_SERVICE_IMS;
+import static android.telephony.ims.feature.MmTelFeature.ImsTrafficSessionCallbackWrapper.INVALID_TOKEN;
+
+import android.hardware.radio.RadioError;
+import android.hardware.radio.RadioResponseInfo;
+import android.hardware.radio.ims.IRadioImsResponse;
+import android.telephony.ims.feature.ConnectionFailureInfo;
+
+/**
+ * Interface declaring response functions to solicited radio requests for IMS APIs.
+ */
+public class ImsResponse extends IRadioImsResponse.Stub {
+    private final RIL mRil;
+
+    public ImsResponse(RIL ril) {
+        mRil = ril;
+    }
+
+    @Override
+    public String getInterfaceHash() {
+        return IRadioImsResponse.HASH;
+    }
+
+    @Override
+    public int getInterfaceVersion() {
+        return IRadioImsResponse.VERSION;
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void setSrvccCallInfoResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void updateImsRegistrationInfoResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error.
+     * @param failureInfo Failure information.
+     */
+    public void startImsTrafficResponse(RadioResponseInfo responseInfo,
+            android.hardware.radio.ims.ConnectionFailureInfo failureInfo) {
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_IMS, responseInfo);
+
+        if (rr != null) {
+            Object[] response = { new Integer(INVALID_TOKEN), null };
+            if (responseInfo.error == RadioError.NONE) {
+                if (failureInfo != null) {
+                    response[1] = new ConnectionFailureInfo(
+                            RILUtils.convertHalConnectionFailureReason(failureInfo.failureReason),
+                            failureInfo.causeCode, failureInfo.waitTimeMillis);
+                }
+                RadioResponse.sendMessageResponse(rr.mResult, response);
+            }
+            mRil.processResponseDone(rr, responseInfo, response);
+        }
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void stopImsTrafficResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void triggerEpsFallbackResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void sendAnbrQueryResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     */
+    public void updateImsCallStatusResponse(RadioResponseInfo info) {
+        RadioResponse.responseVoid(HAL_SERVICE_IMS, mRil, info);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index b9f896c..90885fe 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.app.Activity;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Message;
@@ -43,7 +44,9 @@
 import com.android.internal.telephony.util.SMSDispatcherUtil;
 import com.android.telephony.Rlog;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
@@ -58,6 +61,7 @@
 
     private static final String TAG = "ImsSmsDispatcher";
     private static final int CONNECT_DELAY_MS = 5000; // 5 seconds;
+    public static final int MAX_SEND_RETRIES_OVER_IMS = MAX_SEND_RETRIES;
 
     /**
      * Creates FeatureConnector instances for ImsManager, used during testing to inject mock
@@ -72,6 +76,7 @@
                 FeatureConnector.Listener<ImsManager> listener, Executor executor);
     }
 
+    public List<Integer> mMemoryAvailableNotifierList = new ArrayList<Integer>();
     @VisibleForTesting
     public Map<Integer, SmsTracker> mTrackers = new ConcurrentHashMap<>();
     @VisibleForTesting
@@ -140,6 +145,37 @@
 
     private final IImsSmsListener mImsSmsListener = new IImsSmsListener.Stub() {
         @Override
+        public void onMemoryAvailableResult(int token, @SendStatusResult int status,
+                int networkReasonCode) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                logd("onMemoryAvailableResult token=" + token + " status=" + status
+                        + " networkReasonCode=" + networkReasonCode);
+                if (!mMemoryAvailableNotifierList.contains(token)) {
+                    loge("onMemoryAvailableResult Invalid token");
+                    return;
+                }
+                mMemoryAvailableNotifierList.remove(Integer.valueOf(token));
+
+                /**
+                 * The Retrans flag is set and reset As per section 6.3.3.1.2 in TS 124011
+                 * Note: Assuming that SEND_STATUS_ERROR_RETRY is sent in case of temporary failure
+                 */
+                if (status ==  ImsSmsImplBase.SEND_STATUS_ERROR_RETRY) {
+                    if (!mRPSmmaRetried) {
+                        sendMessageDelayed(obtainMessage(EVENT_RETRY_SMMA), SEND_RETRY_DELAY);
+                        mRPSmmaRetried = true;
+                    } else {
+                        mRPSmmaRetried = false;
+                    }
+                } else {
+                    mRPSmmaRetried = false;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+        @Override
         public void onSendSmsResult(int token, int messageRef, @SendStatusResult int status,
                 @SmsManager.Result int reason, int networkReasonCode) {
             final long identity = Binder.clearCallingIdentity();
@@ -170,10 +206,19 @@
                         mTrackers.remove(token);
                         break;
                     case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY:
-                        if (tracker.mRetryCount < MAX_SEND_RETRIES) {
+                        int maxRetryCountOverIms = getMaxRetryCountOverIms();
+                        if (tracker.mRetryCount < getMaxSmsRetryCount()) {
+                            if (maxRetryCountOverIms < getMaxSmsRetryCount()
+                                    && tracker.mRetryCount >= maxRetryCountOverIms) {
+                                tracker.mRetryCount += 1;
+                                mTrackers.remove(token);
+                                fallbackToPstn(tracker);
+                                break;
+                            }
                             tracker.mRetryCount += 1;
                             sendMessageDelayed(
-                                    obtainMessage(EVENT_SEND_RETRY, tracker), SEND_RETRY_DELAY);
+                                    obtainMessage(EVENT_SEND_RETRY, tracker),
+                                    getSmsRetryDelayValue());
                         } else {
                             tracker.onFailed(mContext, reason, networkReasonCode);
                             mTrackers.remove(token);
@@ -193,6 +238,7 @@
                         SmsConstants.FORMAT_3GPP2.equals(getFormat()),
                         status == ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK,
                         reason,
+                        networkReasonCode,
                         tracker.mMessageId,
                         tracker.isFromDefaultSmsApplication(mContext),
                         tracker.getInterval());
@@ -248,6 +294,10 @@
                             mappedResult =
                                     ImsSmsImplBase.DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED;
                             break;
+                        case Activity.RESULT_OK:
+                            // class2 message saving to SIM operation is in progress, defer ack
+                            // until saving to SIM is success/failure
+                            return;
                         default:
                             mappedResult = ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC;
                             break;
@@ -263,7 +313,7 @@
                     } catch (ImsException e) {
                         loge("Failed to acknowledgeSms(). Error: " + e.getMessage());
                     }
-                }, true /* ignoreClass */, true /* isOverIms */);
+                }, true /* ignoreClass */, true /* isOverIms */, token);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -277,6 +327,10 @@
                 logd("SMS retry..");
                 sendSms((SmsTracker) msg.obj);
                 break;
+            case EVENT_RETRY_SMMA:
+                logd("SMMA Notification retry..");
+                onMemoryAvailable();
+                break;
             default:
                 super.handleMessage(msg);
         }
@@ -295,6 +349,9 @@
                             mImsManager = manager;
                             setListeners();
                             mIsImsServiceUp = true;
+
+                            /* set ImsManager */
+                            mSmsDispatchersController.setImsManager(mImsManager);
                         }
                     }
 
@@ -309,6 +366,9 @@
                         synchronized (mLock) {
                             mImsManager = null;
                             mIsImsServiceUp = false;
+
+                            /* unset ImsManager */
+                            mSmsDispatchersController.setImsManager(null);
                         }
                     }
                 }, this::post);
@@ -394,6 +454,81 @@
     }
 
     @Override
+    public int getMaxSmsRetryCount() {
+        int retryCount = MAX_SEND_RETRIES;
+        CarrierConfigManager mConfigManager;
+
+        mConfigManager = (CarrierConfigManager)  mContext.getSystemService(
+                Context.CARRIER_CONFIG_SERVICE);
+
+        if (mConfigManager != null) {
+            PersistableBundle carrierConfig = mConfigManager.getConfigForSubId(
+                    getSubId());
+
+            if (carrierConfig != null) {
+                retryCount = carrierConfig.getInt(
+                        CarrierConfigManager.ImsSms.KEY_SMS_MAX_RETRY_COUNT_INT);
+            }
+        }
+
+        Rlog.d(TAG, "Retry Count: " + retryCount);
+
+        return retryCount;
+    }
+
+    /**
+     * Returns the number of times SMS can be sent over IMS
+     *
+     * @return  retry count over Ims from  carrier configuration
+     */
+    @VisibleForTesting
+    public int getMaxRetryCountOverIms() {
+        int retryCountOverIms = MAX_SEND_RETRIES_OVER_IMS;
+        CarrierConfigManager mConfigManager;
+
+        mConfigManager = (CarrierConfigManager) mContext.getSystemService(Context
+                                                        .CARRIER_CONFIG_SERVICE);
+
+        if (mConfigManager != null) {
+            PersistableBundle carrierConfig = mConfigManager.getConfigForSubId(
+                    getSubId());
+
+
+            if (carrierConfig != null) {
+                retryCountOverIms = carrierConfig.getInt(
+                        CarrierConfigManager.ImsSms.KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT);
+            }
+        }
+
+        Rlog.d(TAG, "Retry Count Over Ims: " + retryCountOverIms);
+
+        return retryCountOverIms;
+    }
+
+    @Override
+    public int getSmsRetryDelayValue() {
+        int retryDelay = SEND_RETRY_DELAY;
+        CarrierConfigManager mConfigManager;
+
+        mConfigManager = (CarrierConfigManager)  mContext.getSystemService(
+                Context.CARRIER_CONFIG_SERVICE);
+
+        if (mConfigManager != null) {
+            PersistableBundle carrierConfig = mConfigManager.getConfigForSubId(
+                    getSubId());
+
+            if (carrierConfig != null) {
+                retryDelay = carrierConfig.getInt(
+                        CarrierConfigManager.ImsSms.KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT);
+            }
+        }
+
+        Rlog.d(TAG, "Retry delay: " + retryDelay);
+
+        return retryDelay;
+    }
+
+    @Override
     protected boolean shouldBlockSmsForEcbm() {
         // We should not block outgoing SMS during ECM on IMS. It only applies to outgoing CDMA
         // SMS.
@@ -435,6 +570,24 @@
         return SMSDispatcherUtil.calculateLength(isCdmaMo(), messageBody, use7bitOnly);
     }
 
+    /**
+     * Send the Memory Available Event to the ImsService
+     */
+    public void onMemoryAvailable() {
+        logd("onMemoryAvailable ");
+        int token = mNextToken.incrementAndGet();
+        try {
+            logd("onMemoryAvailable: token = " + token);
+            mMemoryAvailableNotifierList.add(token);
+            getImsManager().onMemoryAvailable(token);
+        } catch (ImsException e) {
+            loge("onMemoryAvailable failed: " + e.getMessage());
+            if (mMemoryAvailableNotifierList.contains(token)) {
+                mMemoryAvailableNotifierList.remove(Integer.valueOf(token));
+            }
+        }
+    }
+
     @Override
     public void sendSms(SmsTracker tracker) {
         logd("sendSms: "
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 8f43dce..9166719 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -45,7 +45,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.database.SQLException;
@@ -53,11 +52,10 @@
 import android.os.AsyncResult;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.PowerWhitelistManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
@@ -185,6 +183,7 @@
     /** BroadcastReceiver timed out waiting for an intent */
     public static final int EVENT_RECEIVER_TIMEOUT = 9;
 
+
     /** Wakelock release delay when returning to idle state. */
     private static final int WAKELOCK_TIMEOUT = 3000;
 
@@ -289,8 +288,8 @@
      * @param storageMonitor the SmsStorageMonitor to check for storage availability
      */
     protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor,
-            Phone phone) {
-        super(name);
+            Phone phone, Looper looper) {
+        super(name, looper);
 
         mContext = context;
         mStorageMonitor = storageMonitor;
@@ -501,7 +500,6 @@
                 case EVENT_RETURN_TO_IDLE:
                     // already in idle state; ignore
                     return HANDLED;
-
                 case EVENT_BROADCAST_COMPLETE:
                 case EVENT_START_ACCEPTING_SMS:
                 default:
@@ -540,7 +538,8 @@
 
                 case EVENT_INJECT_SMS:
                     // handle new injected SMS
-                    handleInjectSms((AsyncResult) msg.obj, msg.arg1 == 1 /* isOverIms */);
+                    handleInjectSms((AsyncResult) msg.obj, msg.arg1 == 1 /* isOverIms */,
+                            msg.arg2 /* token */);
                     sendMessage(EVENT_RETURN_TO_IDLE);
                     return HANDLED;
 
@@ -663,7 +662,6 @@
             }
         }
     }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void handleNewSms(AsyncResult ar) {
         if (ar.exception != null) {
@@ -674,7 +672,7 @@
         int result;
         try {
             SmsMessage sms = (SmsMessage) ar.result;
-            result = dispatchMessage(sms.mWrappedSmsMessage, SOURCE_NOT_INJECTED);
+            result = dispatchMessage(sms.mWrappedSmsMessage, SOURCE_NOT_INJECTED, 0 /*unused*/);
         } catch (RuntimeException ex) {
             loge("Exception dispatching message", ex);
             result = RESULT_SMS_DISPATCH_FAILURE;
@@ -693,7 +691,7 @@
      * @param ar is the AsyncResult that has the SMS PDU to be injected.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void handleInjectSms(AsyncResult ar, boolean isOverIms) {
+    private void handleInjectSms(AsyncResult ar, boolean isOverIms, int token) {
         int result;
         SmsDispatchersController.SmsInjectionCallback callback = null;
         try {
@@ -705,7 +703,7 @@
             } else {
                 @SmsSource int smsSource =
                         isOverIms ? SOURCE_INJECTED_FROM_IMS : SOURCE_INJECTED_FROM_UNKNOWN;
-                result = dispatchMessage(sms.mWrappedSmsMessage, smsSource);
+                result = dispatchMessage(sms.mWrappedSmsMessage, smsSource, token);
             }
         } catch (RuntimeException ex) {
             loge("Exception dispatching message", ex);
@@ -726,7 +724,7 @@
      * @return a result code from {@link android.provider.Telephony.Sms.Intents},
      *  or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC
      */
-    private int dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource) {
+    private int dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource, int token) {
         // If sms is null, there was a parsing error.
         if (smsb == null) {
             loge("dispatchSmsMessage: message is null");
@@ -740,20 +738,7 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
-        // onlyCore indicates if the device is in cryptkeeper
-        boolean onlyCore = false;
-        try {
-            onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService("package"))
-                    .isOnlyCoreApps();
-        } catch (RemoteException e) {
-        }
-        if (onlyCore) {
-            // Device is unable to receive SMS in encrypted state
-            log("Received a short message in encrypted state. Rejecting.");
-            return Intents.RESULT_SMS_RECEIVED_WHILE_ENCRYPTED;
-        }
-
-        int result = dispatchMessageRadioSpecific(smsb, smsSource);
+        int result = dispatchMessageRadioSpecific(smsb, smsSource, token);
 
         // In case of error, add to metrics. This is not required in case of success, as the
         // data will be tracked when the message is processed (processMessagePart).
@@ -775,7 +760,7 @@
      *  or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC
      */
     protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb,
-            @SmsSource int smsSource);
+            @SmsSource int smsSource, int token);
 
     /**
      * Send an acknowledge message to the SMSC.
@@ -875,7 +860,6 @@
      * <code>RESULT_SMS_DISPATCH_FAILURE</code><br>
      * <code>RESULT_SMS_NULL_PDU</code><br>
      * <code>RESULT_SMS_NULL_MESSAGE</code><br>
-     * <code>RESULT_SMS_RECEIVED_WHILE_ENCRYPTED</code><br>
      * <code>RESULT_SMS_DATABASE_ERROR</code><br>
      * <code>RESULT_SMS_INVALID_URI</code><br>
      */
@@ -1159,7 +1143,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void showNewMessageNotification() {
         // Do not show the notification on non-FBE devices.
-        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
+        if (!StorageManager.isFileEncrypted()) {
             return;
         }
         log("Show new message notification.");
@@ -1453,12 +1437,14 @@
             intent.putExtra("messageId", messageId);
         }
 
+        UserHandle userHandle = null;
         if (destPort == -1) {
             intent.setAction(Intents.SMS_DELIVER_ACTION);
             // Direct the intent to only the default SMS app. If we can't find a default SMS app
             // then sent it to all broadcast receivers.
-            // We are deliberately delivering to the primary user's default SMS App.
-            ComponentName componentName = SmsApplication.getDefaultSmsApplication(mContext, true);
+            userHandle = TelephonyUtils.getSubscriptionUserHandle(mContext, subId);
+            ComponentName componentName = SmsApplication.getDefaultSmsApplicationAsUser(mContext,
+                    true, userHandle);
             if (componentName != null) {
                 // Deliver SMS message only to this receiver.
                 intent.setComponent(componentName);
@@ -1482,9 +1468,12 @@
             intent.setComponent(null);
         }
 
+        if (userHandle == null) {
+            userHandle = UserHandle.SYSTEM;
+        }
         Bundle options = handleSmsWhitelisting(intent.getComponent(), isClass0);
         dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS,
-                AppOpsManager.OPSTR_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM, subId);
+                AppOpsManager.OPSTR_RECEIVE_SMS, options, resultReceiver, userHandle, subId);
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
old mode 100755
new mode 100644
index 31d6686..de854fa
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -30,6 +30,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserHandle;
 import android.sysprop.TelephonyProperties;
 import android.telephony.CellInfo;
 import android.telephony.ServiceState;
@@ -558,7 +559,7 @@
             intent.putExtra(TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY,
                     getLastKnownCountryIso());
             SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
-            mPhone.getContext().sendBroadcast(intent);
+            mPhone.getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
         }
 
         // Pass the geographical country information to the telephony time zone detection code.
diff --git a/src/java/com/android/internal/telephony/MessagingIndication.java b/src/java/com/android/internal/telephony/MessagingIndication.java
index 96e74cc..5814e3d 100644
--- a/src/java/com/android/internal/telephony/MessagingIndication.java
+++ b/src/java/com/android/internal/telephony/MessagingIndication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_MESSAGING;
+
 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;
@@ -47,7 +49,7 @@
      */
     public void cdmaNewSms(int indicationType,
             android.hardware.radio.messaging.CdmaSmsMessage msg) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);
 
@@ -63,7 +65,7 @@
      * @param indicationType Type of radio indication
      */
     public void cdmaRuimSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL);
 
@@ -82,7 +84,7 @@
      *        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);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogvRet(
@@ -101,7 +103,7 @@
      *        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);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
 
         SmsMessageBase smsb = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
@@ -117,7 +119,7 @@
      * @param recordNumber Record number on the SIM
      */
     public void newSmsOnSim(int indicationType, int recordNumber) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM);
 
@@ -133,7 +135,7 @@
      *        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);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT);
 
@@ -149,7 +151,7 @@
      * @param indicationType Type of radio indication
      */
     public void simSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MESSAGING, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_SIM_SMS_STORAGE_FULL);
 
diff --git a/src/java/com/android/internal/telephony/MessagingResponse.java b/src/java/com/android/internal/telephony/MessagingResponse.java
index 3dc1d1a..19211e1 100644
--- a/src/java/com/android/internal/telephony/MessagingResponse.java
+++ b/src/java/com/android/internal/telephony/MessagingResponse.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_MESSAGING;
+
 import android.hardware.radio.RadioError;
 import android.hardware.radio.RadioResponseInfo;
 import android.hardware.radio.messaging.IRadioMessagingResponse;
@@ -36,7 +38,7 @@
 
     private void responseSms(RadioResponseInfo responseInfo,
             android.hardware.radio.messaging.SendSmsResult sms) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MESSAGING, responseInfo);
 
         if (rr != null) {
             long messageId = RIL.getOutgoingSmsMessageId(rr.mResult);
@@ -62,35 +64,35 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void acknowledgeIncomingGsmSmsWithPduResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, mRil, responseInfo);
     }
 
     /**
@@ -99,7 +101,7 @@
      */
     public void getCdmaBroadcastConfigResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MESSAGING, responseInfo);
 
         if (rr != null) {
             int[] ret;
@@ -148,7 +150,7 @@
      */
     public void getGsmBroadcastConfigResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MESSAGING, responseInfo);
 
         if (rr != null) {
             ArrayList<SmsBroadcastConfigInfo> ret = new ArrayList<>();
@@ -168,14 +170,14 @@
      * @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);
+        RadioResponse.responseString(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, mRil, responseInfo);
     }
 
     /**
@@ -227,35 +229,35 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void setCdmaBroadcastActivationResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MESSAGING, mRil, responseInfo);
     }
 
     /**
@@ -263,7 +265,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_MESSAGING, mRil, responseInfo, index);
     }
 
     /**
@@ -271,7 +273,7 @@
      * @param index record index where the message is stored
      */
     public void writeSmsToSimResponse(RadioResponseInfo responseInfo, int index) {
-        RadioResponse.responseInts(RIL.MESSAGING_SERVICE, mRil, responseInfo, index);
+        RadioResponse.responseInts(HAL_SERVICE_MESSAGING, mRil, responseInfo, index);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/MissedIncomingCallSmsFilter.java b/src/java/com/android/internal/telephony/MissedIncomingCallSmsFilter.java
index 97495d6..dce65af 100644
--- a/src/java/com/android/internal/telephony/MissedIncomingCallSmsFilter.java
+++ b/src/java/com/android/internal/telephony/MissedIncomingCallSmsFilter.java
@@ -240,7 +240,7 @@
     private String[] splitCalls(String messageBody) {
         String[] messages = null;
         if (messageBody != null) {
-            messages = messageBody.split("\\n" + "\\n");
+            messages = messageBody.split("(\\n|\\s\\n)" + "(\\n|\\s\\n)");
             Rlog.d(TAG,
                     "splitTheMultipleCalls no of calls = " + ((messages != null) ? messages.length
                             : 0));
@@ -248,20 +248,6 @@
         return messages;
     }
 
-    // Create phone account. The logic is copied from PhoneUtils.makePstnPhoneAccountHandle.
-    private PhoneAccountHandle makePstnPhoneAccountHandle(Phone phone) {
-        SubscriptionManager subscriptionManager =
-                (SubscriptionManager) phone.getContext().getSystemService(
-                        Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        UserHandle userHandle = subscriptionManager.getSubscriptionUserHandle(phone.getSubId());
-        if (userHandle != null) {
-            return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
-                    String.valueOf(phone.getSubId()), userHandle);
-        }
-        return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
-                String.valueOf(phone.getSubId()));
-    }
-
     /**
      * Create the missed incoming call through TelecomManager.
      *
@@ -288,4 +274,18 @@
             tm.addNewIncomingCall(makePstnPhoneAccountHandle(mPhone), bundle);
         }
     }
-}
+
+    // Create phone account. The logic is copied from PhoneUtils.makePstnPhoneAccountHandle.
+    private PhoneAccountHandle makePstnPhoneAccountHandle(Phone phone) {
+        SubscriptionManager subscriptionManager =
+                (SubscriptionManager) phone.getContext().getSystemService(
+                        Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        UserHandle userHandle = subscriptionManager.getSubscriptionUserHandle(phone.getSubId());
+        if (userHandle != null) {
+            return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
+                    String.valueOf(phone.getSubId()), userHandle);
+        }
+        return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
+                String.valueOf(phone.getSubId()));
+    }
+}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/MockModem.java b/src/java/com/android/internal/telephony/MockModem.java
index 4266a75..a20e748 100644
--- a/src/java/com/android/internal/telephony/MockModem.java
+++ b/src/java/com/android/internal/telephony/MockModem.java
@@ -16,6 +16,14 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+import static android.telephony.TelephonyManager.HAL_SERVICE_IMS;
+import static android.telephony.TelephonyManager.HAL_SERVICE_MESSAGING;
+import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
+import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +42,7 @@
     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_IRADIOIMS = "android.telephony.mockmodem.iradioims";
     private static final String BIND_IRADIOCONFIG = "android.telephony.mockmodem.iradioconfig";
     private static final String PHONE_ID = "phone_id";
 
@@ -42,7 +51,7 @@
     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;
+    static final int BINDER_MAX_RETRY = 10;
 
     private Context mContext;
     private String mServiceName;
@@ -54,6 +63,7 @@
     private IBinder mDataBinder;
     private IBinder mNetworkBinder;
     private IBinder mVoiceBinder;
+    private IBinder mImsBinder;
     private IBinder mConfigBinder;
     private ServiceConnection mModemServiceConnection;
     private ServiceConnection mSimServiceConnection;
@@ -61,9 +71,11 @@
     private ServiceConnection mDataServiceConnection;
     private ServiceConnection mNetworkServiceConnection;
     private ServiceConnection mVoiceServiceConnection;
+    private ServiceConnection mImsServiceConnection;
     private ServiceConnection mConfigServiceConnection;
 
     private byte mPhoneId;
+    private String mTag;
 
     MockModem(Context context, String serviceName) {
         this(context, serviceName, 0);
@@ -71,6 +83,7 @@
 
     MockModem(Context context, String serviceName, int phoneId) {
         mPhoneId = (byte) phoneId;
+        mTag = TAG + "-" + mPhoneId;
         mContext = context;
         String[] componentInfo = serviceName.split("/", 2);
         mPackageName = componentInfo[0];
@@ -86,20 +99,22 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder binder) {
-            Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceConnected");
+            Rlog.d(mTag, "IRadio " + getModuleName(mService) + "  - onServiceConnected");
 
-            if (mService == RIL.MODEM_SERVICE) {
+            if (mService == HAL_SERVICE_MODEM) {
                 mModemBinder = binder;
-            } else if (mService == RIL.SIM_SERVICE) {
+            } else if (mService == HAL_SERVICE_SIM) {
                 mSimBinder = binder;
-            } else if (mService == RIL.MESSAGING_SERVICE) {
+            } else if (mService == HAL_SERVICE_MESSAGING) {
                 mMessagingBinder = binder;
-            } else if (mService == RIL.DATA_SERVICE) {
+            } else if (mService == HAL_SERVICE_DATA) {
                 mDataBinder = binder;
-            } else if (mService == RIL.NETWORK_SERVICE) {
+            } else if (mService == HAL_SERVICE_NETWORK) {
                 mNetworkBinder = binder;
-            } else if (mService == RIL.VOICE_SERVICE) {
+            } else if (mService == HAL_SERVICE_VOICE) {
                 mVoiceBinder = binder;
+            } else if (mService == HAL_SERVICE_IMS) {
+                mImsBinder = binder;
             } else if (mService == RADIOCONFIG_SERVICE) {
                 mConfigBinder = binder;
             }
@@ -107,20 +122,22 @@
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceDisconnected");
+            Rlog.d(mTag, "IRadio " + getModuleName(mService) + "  - onServiceDisconnected");
 
-            if (mService == RIL.MODEM_SERVICE) {
+            if (mService == HAL_SERVICE_MODEM) {
                 mModemBinder = null;
-            } else if (mService == RIL.SIM_SERVICE) {
+            } else if (mService == HAL_SERVICE_SIM) {
                 mSimBinder = null;
-            } else if (mService == RIL.MESSAGING_SERVICE) {
+            } else if (mService == HAL_SERVICE_MESSAGING) {
                 mMessagingBinder = null;
-            } else if (mService == RIL.DATA_SERVICE) {
+            } else if (mService == HAL_SERVICE_DATA) {
                 mDataBinder = null;
-            } else if (mService == RIL.NETWORK_SERVICE) {
+            } else if (mService == HAL_SERVICE_NETWORK) {
                 mNetworkBinder = null;
-            } else if (mService == RIL.VOICE_SERVICE) {
+            } else if (mService == HAL_SERVICE_VOICE) {
                 mVoiceBinder = null;
+            } else if (mService == HAL_SERVICE_IMS) {
+                mImsBinder = null;
             } else if (mService == RADIOCONFIG_SERVICE) {
                 mConfigBinder = null;
             }
@@ -138,7 +155,7 @@
 
         Intent intent = new Intent();
         intent.setComponent(new ComponentName(mPackageName, mServiceName));
-        intent.setAction(actionName);
+        intent.setAction(actionName + phoneId);
         intent.putExtra(PHONE_ID, phoneId);
 
         status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
@@ -148,18 +165,20 @@
     /** waitForBinder */
     public IBinder getServiceBinder(int service) {
         switch (service) {
-            case RIL.MODEM_SERVICE:
+            case HAL_SERVICE_MODEM:
                 return mModemBinder;
-            case RIL.SIM_SERVICE:
+            case HAL_SERVICE_SIM:
                 return mSimBinder;
-            case RIL.MESSAGING_SERVICE:
+            case HAL_SERVICE_MESSAGING:
                 return mMessagingBinder;
-            case RIL.DATA_SERVICE:
+            case HAL_SERVICE_DATA:
                 return mDataBinder;
-            case RIL.NETWORK_SERVICE:
+            case HAL_SERVICE_NETWORK:
                 return mNetworkBinder;
-            case RIL.VOICE_SERVICE:
+            case HAL_SERVICE_VOICE:
                 return mVoiceBinder;
+            case HAL_SERVICE_IMS:
+                return mImsBinder;
             case RADIOCONFIG_SERVICE:
                 return mConfigBinder;
             default:
@@ -183,95 +202,109 @@
                 boolean status =
                         bindModuleToMockModemService(BIND_IRADIOCONFIG, mConfigServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Config bind fail");
+                    Rlog.d(mTag, "IRadio Config bind fail");
                     mConfigServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Config is bound");
+                Rlog.d(mTag, "IRadio Config is bound");
             }
-        } else if (service == RIL.MODEM_SERVICE) {
+        } else if (service == HAL_SERVICE_MODEM) {
             if (mModemBinder == null) {
-                mModemServiceConnection = new MockModemConnection(RIL.MODEM_SERVICE);
+                mModemServiceConnection = new MockModemConnection(HAL_SERVICE_MODEM);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIOMODEM, mModemServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Modem bind fail");
+                    Rlog.d(mTag, "IRadio Modem bind fail");
                     mModemServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Modem is bound");
+                Rlog.d(mTag, "IRadio Modem is bound");
             }
-        } else if (service == RIL.SIM_SERVICE) {
+        } else if (service == HAL_SERVICE_SIM) {
             if (mSimBinder == null) {
-                mSimServiceConnection = new MockModemConnection(RIL.SIM_SERVICE);
+                mSimServiceConnection = new MockModemConnection(HAL_SERVICE_SIM);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIOSIM, mSimServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Sim bind fail");
+                    Rlog.d(mTag, "IRadio Sim bind fail");
                     mSimServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Sim is bound");
+                Rlog.d(mTag, "IRadio Sim is bound");
             }
-        } else if (service == RIL.MESSAGING_SERVICE) {
+        } else if (service == HAL_SERVICE_MESSAGING) {
             if (mMessagingBinder == null) {
-                mMessagingServiceConnection = new MockModemConnection(RIL.MESSAGING_SERVICE);
+                mMessagingServiceConnection = new MockModemConnection(HAL_SERVICE_MESSAGING);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIOMESSAGING, mMessagingServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Messaging bind fail");
+                    Rlog.d(mTag, "IRadio Messaging bind fail");
                     mMessagingServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Messaging is bound");
+                Rlog.d(mTag, "IRadio Messaging is bound");
             }
-        } else if (service == RIL.DATA_SERVICE) {
+        } else if (service == HAL_SERVICE_DATA) {
             if (mDataBinder == null) {
-                mDataServiceConnection = new MockModemConnection(RIL.DATA_SERVICE);
+                mDataServiceConnection = new MockModemConnection(HAL_SERVICE_DATA);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIODATA, mDataServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Data bind fail");
+                    Rlog.d(mTag, "IRadio Data bind fail");
                     mDataServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Data is bound");
+                Rlog.d(mTag, "IRadio Data is bound");
             }
-        } else if (service == RIL.NETWORK_SERVICE) {
+        } else if (service == HAL_SERVICE_NETWORK) {
             if (mNetworkBinder == null) {
-                mNetworkServiceConnection = new MockModemConnection(RIL.NETWORK_SERVICE);
+                mNetworkServiceConnection = new MockModemConnection(HAL_SERVICE_NETWORK);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIONETWORK, mNetworkServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Network bind fail");
+                    Rlog.d(mTag, "IRadio Network bind fail");
                     mNetworkServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Network is bound");
+                Rlog.d(mTag, "IRadio Network is bound");
             }
-        } else if (service == RIL.VOICE_SERVICE) {
+        } else if (service == HAL_SERVICE_VOICE) {
             if (mVoiceBinder == null) {
-                mVoiceServiceConnection = new MockModemConnection(RIL.VOICE_SERVICE);
+                mVoiceServiceConnection = new MockModemConnection(HAL_SERVICE_VOICE);
 
                 boolean status =
                         bindModuleToMockModemService(
                                 mPhoneId, BIND_IRADIOVOICE, mVoiceServiceConnection);
                 if (!status) {
-                    Rlog.d(TAG, "IRadio Voice bind fail");
+                    Rlog.d(mTag, "IRadio Voice bind fail");
                     mVoiceServiceConnection = null;
                 }
             } else {
-                Rlog.d(TAG, "IRadio Voice is bound");
+                Rlog.d(mTag, "IRadio Voice is bound");
+            }
+        } else if (service == HAL_SERVICE_IMS) {
+            if (mImsBinder == null) {
+                mImsServiceConnection = new MockModemConnection(HAL_SERVICE_IMS);
+
+                boolean status =
+                        bindModuleToMockModemService(
+                                mPhoneId, BIND_IRADIOIMS, mImsServiceConnection);
+                if (!status) {
+                    Rlog.d(TAG, "IRadio Ims bind fail");
+                    mImsServiceConnection = null;
+                }
+            } else {
+                Rlog.d(TAG, "IRadio Ims is bound");
             }
         }
     }
@@ -284,49 +317,56 @@
                 mContext.unbindService(mConfigServiceConnection);
                 mConfigServiceConnection = null;
                 mConfigBinder = null;
-                Rlog.d(TAG, "unbind IRadio Config");
+                Rlog.d(mTag, "unbind IRadio Config");
             }
-        } else if (service == RIL.MODEM_SERVICE) {
+        } else if (service == HAL_SERVICE_MODEM) {
             if (mModemServiceConnection != null) {
                 mContext.unbindService(mModemServiceConnection);
                 mModemServiceConnection = null;
                 mModemBinder = null;
-                Rlog.d(TAG, "unbind IRadio Modem");
+                Rlog.d(mTag, "unbind IRadio Modem");
             }
-        } else if (service == RIL.SIM_SERVICE) {
+        } else if (service == HAL_SERVICE_SIM) {
             if (mSimServiceConnection != null) {
                 mContext.unbindService(mSimServiceConnection);
                 mSimServiceConnection = null;
                 mSimBinder = null;
-                Rlog.d(TAG, "unbind IRadio Sim");
+                Rlog.d(mTag, "unbind IRadio Sim");
             }
-        } else if (service == RIL.MESSAGING_SERVICE) {
+        } else if (service == HAL_SERVICE_MESSAGING) {
             if (mMessagingServiceConnection != null) {
                 mContext.unbindService(mMessagingServiceConnection);
                 mMessagingServiceConnection = null;
                 mMessagingBinder = null;
-                Rlog.d(TAG, "unbind IRadio Messaging");
+                Rlog.d(mTag, "unbind IRadio Messaging");
             }
-        } else if (service == RIL.DATA_SERVICE) {
+        } else if (service == HAL_SERVICE_DATA) {
             if (mDataServiceConnection != null) {
                 mContext.unbindService(mDataServiceConnection);
                 mDataServiceConnection = null;
                 mDataBinder = null;
-                Rlog.d(TAG, "unbind IRadio Data");
+                Rlog.d(mTag, "unbind IRadio Data");
             }
-        } else if (service == RIL.NETWORK_SERVICE) {
+        } else if (service == HAL_SERVICE_NETWORK) {
             if (mNetworkServiceConnection != null) {
                 mContext.unbindService(mNetworkServiceConnection);
                 mNetworkServiceConnection = null;
                 mNetworkBinder = null;
-                Rlog.d(TAG, "unbind IRadio Network");
+                Rlog.d(mTag, "unbind IRadio Network");
             }
-        } else if (service == RIL.VOICE_SERVICE) {
+        } else if (service == HAL_SERVICE_VOICE) {
             if (mVoiceServiceConnection != null) {
                 mContext.unbindService(mVoiceServiceConnection);
                 mVoiceServiceConnection = null;
                 mVoiceBinder = null;
-                Rlog.d(TAG, "unbind IRadio Voice");
+                Rlog.d(mTag, "unbind IRadio Voice");
+            }
+        } else if (service == HAL_SERVICE_IMS) {
+            if (mImsServiceConnection != null) {
+                mContext.unbindService(mImsServiceConnection);
+                mImsServiceConnection = null;
+                mImsBinder = null;
+                Rlog.d(TAG, "unbind IRadio Ims");
             }
         }
     }
@@ -337,18 +377,20 @@
 
     private String getModuleName(int service) {
         switch (service) {
-            case RIL.MODEM_SERVICE:
+            case HAL_SERVICE_MODEM:
                 return "modem";
-            case RIL.SIM_SERVICE:
+            case HAL_SERVICE_SIM:
                 return "sim";
-            case RIL.MESSAGING_SERVICE:
+            case HAL_SERVICE_MESSAGING:
                 return "messaging";
-            case RIL.DATA_SERVICE:
+            case HAL_SERVICE_DATA:
                 return "data";
-            case RIL.NETWORK_SERVICE:
+            case HAL_SERVICE_NETWORK:
                 return "network";
-            case RIL.VOICE_SERVICE:
+            case HAL_SERVICE_VOICE:
                 return "voice";
+            case HAL_SERVICE_IMS:
+                return "ims";
             case RADIOCONFIG_SERVICE:
                 return "config";
             default:
diff --git a/src/java/com/android/internal/telephony/ModemIndication.java b/src/java/com/android/internal/telephony/ModemIndication.java
index d05e0f6..0ee40bb 100644
--- a/src/java/com/android/internal/telephony/ModemIndication.java
+++ b/src/java/com/android/internal/telephony/ModemIndication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
+
 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;
@@ -44,7 +46,7 @@
      */
     public void hardwareConfigChanged(int indicationType,
             android.hardware.radio.modem.HardwareConfig[] configs) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MODEM, indicationType);
 
         ArrayList<HardwareConfig> response = RILUtils.convertHalHardwareConfigList(configs);
 
@@ -62,7 +64,7 @@
      *        restart" that explains the cause of the modem restart
      */
     public void modemReset(int indicationType, String reason) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MODEM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_MODEM_RESTART, reason);
 
@@ -78,7 +80,7 @@
      */
     public void radioCapabilityIndication(int indicationType,
             android.hardware.radio.modem.RadioCapability radioCapability) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MODEM, indicationType);
 
         RadioCapability response = RILUtils.convertHalRadioCapability(radioCapability, mRil);
 
@@ -94,7 +96,7 @@
      * @param radioState Current radio state
      */
     public void radioStateChanged(int indicationType, int radioState) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MODEM, indicationType);
 
         int state = RILUtils.convertHalRadioState(radioState);
         if (mRil.isLogOrTrace()) {
@@ -110,7 +112,7 @@
      * @param indicationType Type of radio indication
      */
     public void rilConnected(int indicationType) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_MODEM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RIL_CONNECTED);
 
diff --git a/src/java/com/android/internal/telephony/ModemResponse.java b/src/java/com/android/internal/telephony/ModemResponse.java
index 6e44ddc..bd04d16 100644
--- a/src/java/com/android/internal/telephony/ModemResponse.java
+++ b/src/java/com/android/internal/telephony/ModemResponse.java
@@ -16,9 +16,12 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
+
 import android.hardware.radio.RadioError;
 import android.hardware.radio.RadioResponseInfo;
 import android.hardware.radio.modem.IRadioModemResponse;
+import android.hardware.radio.modem.ImeiInfo;
 import android.os.SystemClock;
 import android.telephony.ActivityStatsTechSpecificInfo;
 import android.telephony.AnomalyReporter;
@@ -51,7 +54,7 @@
      * @param responseInfo Response info struct containing response type, serial number and error.
      */
     public void enableModemResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo);
     }
 
     /**
@@ -59,7 +62,7 @@
      * @param version String containing version string for log reporting
      */
     public void getBasebandVersionResponse(RadioResponseInfo responseInfo, String version) {
-        RadioResponse.responseString(RIL.MODEM_SERVICE, mRil, responseInfo, version);
+        RadioResponse.responseString(HAL_SERVICE_MODEM, mRil, responseInfo, version);
     }
 
     /**
@@ -72,7 +75,21 @@
     public void getDeviceIdentityResponse(RadioResponseInfo responseInfo, String imei,
             String imeisv, String esn, String meid) {
         RadioResponse.responseStrings(
-                RIL.MODEM_SERVICE, mRil, responseInfo, imei, imeisv, esn, meid);
+                HAL_SERVICE_MODEM, mRil, responseInfo, imei, imeisv, esn, meid);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     * @param imeiInfo object containing ImeiType, device IMEI and IMEISV
+     */
+    public void getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo) {
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
+        if (rr != null) {
+            if (responseInfo.error == RadioError.NONE) {
+                RadioResponse.sendMessageResponse(rr.mResult, imeiInfo);
+            }
+            mRil.processResponseDone(rr, responseInfo, imeiInfo);
+        }
     }
 
     /**
@@ -81,7 +98,7 @@
      */
     public void getHardwareConfigResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.modem.HardwareConfig[] config) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
 
         if (rr != null) {
             ArrayList<HardwareConfig> ret = RILUtils.convertHalHardwareConfigList(config);
@@ -98,7 +115,7 @@
      */
     public void getModemActivityInfoResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.modem.ActivityStatsInfo activityInfo) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
 
         if (rr != null) {
             ModemActivityInfo ret = null;
@@ -141,7 +158,7 @@
      * @param isEnabled whether the modem stack is enabled.
      */
     public void getModemStackStatusResponse(RadioResponseInfo responseInfo, boolean isEnabled) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
 
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
@@ -157,7 +174,7 @@
      */
     public void getRadioCapabilityResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.modem.RadioCapability radioCapability) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
 
         if (rr != null) {
             RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil);
@@ -179,42 +196,42 @@
      * @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);
+        RadioResponse.responseString(HAL_SERVICE_MODEM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo);
     }
 
     /**
@@ -223,7 +240,7 @@
      */
     public void setRadioCapabilityResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.modem.RadioCapability radioCapability) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo);
 
         if (rr != null) {
             RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil);
@@ -238,7 +255,7 @@
      * @param responseInfo Response info struct containing response type, serial no. and error.
      */
     public void setRadioPowerResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo);
         mRil.mLastRadioPowerResult = responseInfo.error;
         if (responseInfo.error == RadioError.RF_HARDWARE_ISSUE) {
             AnomalyReporter.reportAnomaly(
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 45ea8bc..0acae4b 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -33,10 +33,8 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.app.PendingIntent;
-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.Looper;
@@ -85,7 +83,6 @@
     private static final int EVENT_SUBSCRIPTION_INFO_CHANGED         = 4;
     private static final int EVENT_SUBSCRIPTION_GROUP_CHANGED        = 5;
     private static final int EVENT_DEFAULT_DATA_SUBSCRIPTION_CHANGED = 6;
-    private static final int EVENT_CARRIER_CONFIG_CHANGED            = 7;
     private static final int EVENT_MULTI_SIM_CONFIG_CHANGED          = 8;
     @VisibleForTesting
     public static final int EVENT_RADIO_STATE_CHANGED                = 9;
@@ -123,7 +120,6 @@
     private static final int PRIMARY_SUB_REMOVED_IN_GROUP       = 7;
 
     protected final Context mContext;
-    protected final SubscriptionController mSubController;
     private final SubscriptionManagerService mSubscriptionManagerService;
 
     // Keep a record of active primary (non-opportunistic) subscription list.
@@ -132,12 +128,7 @@
     /** The singleton instance. */
     protected static MultiSimSettingController sInstance = null;
 
-    // This will be set true when handling EVENT_ALL_SUBSCRIPTIONS_LOADED. The reason of keeping
-    // a local variable instead of calling SubscriptionInfoUpdater#isSubInfoInitialized is, there
-    // might be a race condition that we receive EVENT_SUBSCRIPTION_INFO_CHANGED first, then
-    // EVENT_ALL_SUBSCRIPTIONS_LOADED. And calling SubscriptionInfoUpdater#isSubInfoInitialized
-    // will make us handle EVENT_SUBSCRIPTION_INFO_CHANGED unexpectedly and causing us to believe
-    // the SIMs are newly inserted instead of being initialized.
+    // This will be set true when handling EVENT_ALL_SUBSCRIPTIONS_LOADED.
     private boolean mSubInfoInitialized = false;
 
     // mInitialHandling is to make sure we don't always ask user to re-select data SIM after reboot.
@@ -162,19 +153,6 @@
 
     private static final String SETTING_USER_PREF_DATA_SUB = "user_preferred_data_sub";
 
-    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
-                int phoneId = intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
-                        SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-                int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                notifyCarrierConfigChanged(phoneId, subId);
-            }
-        }
-    };
-
     private static class DataSettingsControllerCallback extends DataSettingsManagerCallback {
         private final Phone mPhone;
 
@@ -222,10 +200,10 @@
     /**
      * Init instance of MultiSimSettingController.
      */
-    public static MultiSimSettingController init(Context context, SubscriptionController sc) {
+    public static MultiSimSettingController init(Context context) {
         synchronized (MultiSimSettingController.class) {
             if (sInstance == null) {
-                sInstance = new MultiSimSettingController(context, sc);
+                sInstance = new MultiSimSettingController(context);
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -234,9 +212,8 @@
     }
 
     @VisibleForTesting
-    public MultiSimSettingController(Context context, SubscriptionController sc) {
+    public MultiSimSettingController(Context context) {
         mContext = context;
-        mSubController = sc;
         mSubscriptionManagerService = SubscriptionManagerService.getInstance();
 
         // Initialize mCarrierConfigLoadedSubIds and register to listen to carrier config change.
@@ -250,8 +227,12 @@
 
         mIsAskEverytimeSupportedForSms = mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support);
-        context.registerReceiver(mIntentReceiver, new IntentFilter(
-                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+
+        CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
+        // Listener callback is executed on handler thread to directly handle config change
+        ccm.registerCarrierConfigChangeListener(this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) ->
+                        onCarrierConfigChanged(slotIndex, subId));
     }
 
     /**
@@ -330,11 +311,6 @@
             case EVENT_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
                 onDefaultDataSettingChanged();
                 break;
-            case EVENT_CARRIER_CONFIG_CHANGED:
-                int phoneId = msg.arg1;
-                int subId = msg.arg2;
-                onCarrierConfigChanged(phoneId, subId);
-                break;
             case EVENT_MULTI_SIM_CONFIG_CHANGED:
                 int activeModems = (int) ((AsyncResult) msg.obj).result;
                 onMultiSimConfigChanged(activeModems);
@@ -363,26 +339,15 @@
         // Make sure MOBILE_DATA of subscriptions in same group are synced.
         setUserDataEnabledForGroup(subId, enable);
 
-        SubscriptionInfo subInfo = null;
-        int defaultDataSubId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            subInfo = mSubscriptionManagerService.getSubscriptionInfo(subId);
-            defaultDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
-        } else {
-            subInfo = mSubController.getSubscriptionInfo(subId);
-            defaultDataSubId = mSubController.getDefaultDataSubId();
-        }
+        SubscriptionInfo subInfo = mSubscriptionManagerService.getSubscriptionInfo(subId);
+        int defaultDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
 
         // If user is enabling a non-default non-opportunistic subscription, make it default.
         if (defaultDataSubId != subId && subInfo != null && !subInfo.isOpportunistic() && enable
                 && subInfo.isActive() && setDefaultData) {
             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
                     SETTING_USER_PREF_DATA_SUB, subId);
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                mSubscriptionManagerService.setDefaultDataSubId(subId);
-            } else {
-                mSubController.setDefaultDataSubId(subId);
-            }
+            mSubscriptionManagerService.setDefaultDataSubId(subId);
         }
     }
 
@@ -393,13 +358,8 @@
         if (DBG) log("onRoamingDataEnabled");
         setRoamingDataEnabledForGroup(subId, enable);
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            // Also inform SubscriptionController as it keeps another copy of user setting.
-            mSubscriptionManagerService.setDataRoaming(enable ? 1 : 0, subId);
-        } else {
-            // Also inform SubscriptionController as it keeps another copy of user setting.
-            mSubController.setDataRoaming(enable ? 1 : 0, subId);
-        }
+        // Also inform SubscriptionManagerService as it keeps another copy of user setting.
+        mSubscriptionManagerService.setDataRoaming(enable ? 1 : 0, subId);
     }
 
     /**
@@ -444,14 +404,6 @@
         reEvaluateAll();
     }
 
-    /**
-     * Called when carrier config changes on any phone.
-     */
-    @VisibleForTesting
-    public void notifyCarrierConfigChanged(int phoneId, int subId) {
-        obtainMessage(EVENT_CARRIER_CONFIG_CHANGED, phoneId, subId).sendToTarget();
-    }
-
     private void onCarrierConfigChanged(int phoneId, int subId) {
         log("onCarrierConfigChanged phoneId " + phoneId + " subId " + subId);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
@@ -482,12 +434,7 @@
      */
     @VisibleForTesting
     public boolean isCarrierConfigLoadedForAllSub() {
-        int[] activeSubIds;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            activeSubIds = mSubscriptionManagerService.getActiveSubIdList(false);
-        } else {
-            activeSubIds = mSubController.getActiveSubIdList(false);
-        }
+        int[] activeSubIds = mSubscriptionManagerService.getActiveSubIdList(false);
         for (int activeSubId : activeSubIds) {
             boolean isLoaded = false;
             for (int configLoadedSub : mCarrierConfigLoadedSubIds) {
@@ -554,17 +501,9 @@
     private void onSubscriptionGroupChanged(ParcelUuid groupUuid) {
         if (DBG) log("onSubscriptionGroupChanged");
 
-        List<SubscriptionInfo> infoList;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            infoList = mSubscriptionManagerService.getSubscriptionsInGroup(
-                    groupUuid, mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (infoList == null || infoList.isEmpty()) return;
-
-        } else {
-            infoList = mSubController.getSubscriptionsInGroup(
-                    groupUuid, mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (infoList == null || infoList.isEmpty()) return;
-        }
+        List<SubscriptionInfo> infoList = mSubscriptionManagerService.getSubscriptionsInGroup(
+                groupUuid, mContext.getOpPackageName(), mContext.getAttributionTag());
+        if (infoList == null || infoList.isEmpty()) return;
 
         // Get a reference subscription to copy settings from.
         // TODO: the reference sub should be passed in from external caller.
@@ -589,14 +528,9 @@
                     mContext, Settings.Global.MOBILE_DATA, INVALID_SUBSCRIPTION_ID, enable);
         }
         boolean setDefaultData = true;
-        List<SubscriptionInfo> activeSubList;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            activeSubList = mSubscriptionManagerService.getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } else {
-            activeSubList = mSubController.getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        }
+        List<SubscriptionInfo> activeSubList = mSubscriptionManagerService
+                .getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getAttributionTag());
         for (SubscriptionInfo activeInfo : activeSubList) {
             if (!(groupUuid.equals(activeInfo.getGroupUuid()))) {
                 // Do not set refSubId as defaultDataSubId if there are other active
@@ -619,12 +553,7 @@
             onRoamingDataEnabled(refSubId, enable);
         }
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService.syncGroupedSetting(refSubId);
-        } else {
-            // Sync settings in subscription database..
-            mSubController.syncGroupedSetting(refSubId);
-        }
+        mSubscriptionManagerService.syncGroupedSetting(refSubId);
     }
 
     /**
@@ -646,34 +575,20 @@
 
         if (!isReadyToReevaluate()) return;
 
-        List<SubscriptionInfo> activeSubInfos;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            activeSubInfos = mSubscriptionManagerService.getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
+        List<SubscriptionInfo> activeSubInfos = mSubscriptionManagerService
+                .getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getAttributionTag());
 
-            if (ArrayUtils.isEmpty(activeSubInfos)) {
-                mPrimarySubList.clear();
-                if (DBG) log("updateDefaults: No active sub. Setting default to INVALID sub.");
-                mSubscriptionManagerService.setDefaultDataSubId(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                mSubscriptionManagerService.setDefaultVoiceSubId(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                mSubscriptionManagerService.setDefaultSmsSubId(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                return;
-            }
-        } else {
-            activeSubInfos = mSubController.getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-
-            if (ArrayUtils.isEmpty(activeSubInfos)) {
-                mPrimarySubList.clear();
-                if (DBG) log("updateDefaultValues: No active sub. Setting default to INVALID sub.");
-                mSubController.setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                mSubController.setDefaultVoiceSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                mSubController.setDefaultSmsSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                return;
-            }
+        if (ArrayUtils.isEmpty(activeSubInfos)) {
+            mPrimarySubList.clear();
+            if (DBG) log("updateDefaults: No active sub. Setting default to INVALID sub.");
+            mSubscriptionManagerService.setDefaultDataSubId(
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            mSubscriptionManagerService.setDefaultVoiceSubId(
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            mSubscriptionManagerService.setDefaultSmsSubId(
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            return;
         }
 
         int change = updatePrimarySubListAndGetChangeType(activeSubInfos);
@@ -690,15 +605,9 @@
                 .getActiveModemCount() == 1)) {
             int subId = mPrimarySubList.get(0);
             if (DBG) log("updateDefaultValues: to only primary sub " + subId);
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                mSubscriptionManagerService.setDefaultDataSubId(subId);
-                mSubscriptionManagerService.setDefaultVoiceSubId(subId);
-                mSubscriptionManagerService.setDefaultSmsSubId(subId);
-            } else {
-                mSubController.setDefaultDataSubId(subId);
-                mSubController.setDefaultVoiceSubId(subId);
-                mSubController.setDefaultSmsSubId(subId);
-            }
+            mSubscriptionManagerService.setDefaultDataSubId(subId);
+            mSubscriptionManagerService.setDefaultVoiceSubId(subId);
+            mSubscriptionManagerService.setDefaultSmsSubId(subId);
             sendDefaultSubConfirmedNotification(subId);
             return;
         }
@@ -707,45 +616,24 @@
 
         boolean dataSelected, voiceSelected, smsSelected;
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            // Update default data subscription.
-            if (DBG) log("updateDefaultValues: Update default data subscription");
-            dataSelected = updateDefaultValue(mPrimarySubList,
-                    mSubscriptionManagerService.getDefaultDataSubId(),
-                    mSubscriptionManagerService::setDefaultDataSubId);
+        // Update default data subscription.
+        if (DBG) log("updateDefaultValues: Update default data subscription");
+        dataSelected = updateDefaultValue(mPrimarySubList,
+                mSubscriptionManagerService.getDefaultDataSubId(),
+                mSubscriptionManagerService::setDefaultDataSubId);
 
-            // Update default voice subscription.
-            if (DBG) log("updateDefaultValues: Update default voice subscription");
-            voiceSelected = updateDefaultValue(mPrimarySubList,
-                    mSubscriptionManagerService.getDefaultVoiceSubId(),
-                    mSubscriptionManagerService::setDefaultVoiceSubId);
+        // Update default voice subscription.
+        if (DBG) log("updateDefaultValues: Update default voice subscription");
+        voiceSelected = updateDefaultValue(mPrimarySubList,
+                mSubscriptionManagerService.getDefaultVoiceSubId(),
+                mSubscriptionManagerService::setDefaultVoiceSubId);
 
-            // Update default sms subscription.
-            if (DBG) log("updateDefaultValues: Update default sms subscription");
-            smsSelected = updateDefaultValue(mPrimarySubList,
-                    mSubscriptionManagerService.getDefaultSmsSubId(),
-                    mSubscriptionManagerService::setDefaultSmsSubId,
-                    mIsAskEverytimeSupportedForSms);
-        } else {
-            // Update default data subscription.
-            if (DBG) log("updateDefaultValues: Update default data subscription");
-            dataSelected = updateDefaultValue(mPrimarySubList,
-                    mSubController.getDefaultDataSubId(),
-                    mSubController::setDefaultDataSubId);
-
-            // Update default voice subscription.
-            if (DBG) log("updateDefaultValues: Update default voice subscription");
-            voiceSelected = updateDefaultValue(mPrimarySubList,
-                    mSubController.getDefaultVoiceSubId(),
-                    mSubController::setDefaultVoiceSubId);
-
-            // Update default sms subscription.
-            if (DBG) log("updateDefaultValues: Update default sms subscription");
-            smsSelected = updateDefaultValue(mPrimarySubList,
-                    mSubController.getDefaultSmsSubId(),
-                    mSubController::setDefaultSmsSubId,
-                    mIsAskEverytimeSupportedForSms);
-        }
+        // Update default sms subscription.
+        if (DBG) log("updateDefaultValues: Update default sms subscription");
+        smsSelected = updateDefaultValue(mPrimarySubList,
+                mSubscriptionManagerService.getDefaultSmsSubId(),
+                mSubscriptionManagerService::setDefaultSmsSubId,
+                mIsAskEverytimeSupportedForSms);
 
         boolean autoFallbackEnabled = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_data_sms_auto_fallback);
@@ -796,12 +684,7 @@
             // any previous primary subscription becomes inactive, we consider it
             for (int subId : prevPrimarySubList) {
                 if (mPrimarySubList.contains(subId)) continue;
-                SubscriptionInfo subInfo = null;
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    subInfo = mSubscriptionManagerService.getSubscriptionInfo(subId);
-                } else {
-                    subInfo = mSubController.getSubscriptionInfo(subId);
-                }
+                SubscriptionInfo subInfo = mSubscriptionManagerService.getSubscriptionInfo(subId);
 
                 if (subInfo == null || !subInfo.isActive()) {
                     for (int currentSubId : mPrimarySubList) {
@@ -839,6 +722,7 @@
         @TelephonyManager.DefaultSubscriptionSelectType
         int simSelectDialogType = getSimSelectDialogType(
                 change, dataSelected, voiceSelected, smsSelected);
+        log("sendSubChangeNotificationIfNeeded: simSelectDialogType=" + simSelectDialogType);
         SimCombinationWarningParams simCombinationParams = getSimCombinationWarningParams(change);
 
         if (simSelectDialogType != EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE
@@ -914,16 +798,10 @@
             if (phone != null && phone.isCdmaSubscriptionAppPresent()) {
                 cdmaPhoneCount++;
                 String simName = null;
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                            .getSubscriptionInfoInternal(subId);
-                    if (subInfo != null) {
-                        simName = subInfo.getDisplayName();
-                    }
-                } else {
-                    simName = mSubController.getActiveSubscriptionInfo(
-                            subId, mContext.getOpPackageName(), mContext.getAttributionTag())
-                            .getDisplayName().toString();
+                SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                        .getSubscriptionInfoInternal(subId);
+                if (subInfo != null) {
+                    simName = subInfo.getDisplayName();
                 }
                 if (TextUtils.isEmpty(simName)) {
                     // Fall back to carrier name.
@@ -949,22 +827,12 @@
     protected void disableDataForNonDefaultNonOpportunisticSubscriptions() {
         if (!isReadyToReevaluate()) return;
 
-        int defaultDataSub;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            defaultDataSub = mSubscriptionManagerService.getDefaultDataSubId();
-        } else {
-            defaultDataSub = mSubController.getDefaultDataSubId();
-        }
+        int defaultDataSub = mSubscriptionManagerService.getDefaultDataSubId();
 
         for (Phone phone : PhoneFactory.getPhones()) {
-            boolean isOpportunistic;
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                        .getSubscriptionInfoInternal(phone.getSubId());
-                isOpportunistic = subInfo != null && subInfo.isOpportunistic();
-            } else {
-                isOpportunistic = mSubController.isOpportunistic(phone.getSubId());
-            }
+            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                    .getSubscriptionInfoInternal(phone.getSubId());
+            boolean isOpportunistic = subInfo != null && subInfo.isOpportunistic();
             if (phone.getSubId() != defaultDataSub
                     && SubscriptionManager.isValidSubscriptionId(phone.getSubId())
                     && !isOpportunistic
@@ -983,19 +851,13 @@
                 || !SubscriptionManager.isUsableSubscriptionId(subId2)) return false;
         if (subId1 == subId2) return true;
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo1 =
-                    mSubscriptionManagerService.getSubscriptionInfoInternal(subId1);
-            SubscriptionInfoInternal subInfo2 =
-                    mSubscriptionManagerService.getSubscriptionInfoInternal(subId2);
-            return subInfo1 != null && subInfo2 != null
-                    && !TextUtils.isEmpty(subInfo1.getGroupUuid())
-                    && subInfo1.getGroupUuid().equals(subInfo2.getGroupUuid());
-        } else {
-            ParcelUuid groupUuid1 = mSubController.getGroupUuid(subId1);
-            ParcelUuid groupUuid2 = mSubController.getGroupUuid(subId2);
-            return groupUuid1 != null && groupUuid1.equals(groupUuid2);
-        }
+        SubscriptionInfoInternal subInfo1 =
+                mSubscriptionManagerService.getSubscriptionInfoInternal(subId1);
+        SubscriptionInfoInternal subInfo2 =
+                mSubscriptionManagerService.getSubscriptionInfoInternal(subId2);
+        return subInfo1 != null && subInfo2 != null
+                && !TextUtils.isEmpty(subInfo1.getGroupUuid())
+                && subInfo1.getGroupUuid().equals(subInfo2.getGroupUuid());
     }
 
     /**
@@ -1005,17 +867,11 @@
     protected void setUserDataEnabledForGroup(int subId, boolean enable) {
         log("setUserDataEnabledForGroup subId " + subId + " enable " + enable);
         List<SubscriptionInfo> infoList = null;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo != null && !subInfo.getGroupUuid().isEmpty()) {
-                infoList = mSubscriptionManagerService.getSubscriptionsInGroup(
-                        ParcelUuid.fromString(subInfo.getGroupUuid()), mContext.getOpPackageName(),
-                        mContext.getAttributionTag());
-            }
-        } else {
-            infoList = mSubController.getSubscriptionsInGroup(
-                    mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo != null && !subInfo.getGroupUuid().isEmpty()) {
+            infoList = mSubscriptionManagerService.getSubscriptionsInGroup(
+                    ParcelUuid.fromString(subInfo.getGroupUuid()), mContext.getOpPackageName(),
                     mContext.getAttributionTag());
         }
 
@@ -1026,13 +882,8 @@
             // TODO: simplify when setUserDataEnabled becomes singleton
             if (info.isActive()) {
                 // For active subscription, call setUserDataEnabled through DataSettingsManager.
-                Phone phone;
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    phone = PhoneFactory.getPhone(mSubscriptionManagerService
-                            .getPhoneId(currentSubId));
-                } else {
-                    phone = PhoneFactory.getPhone(mSubController.getPhoneId(currentSubId));
-                }
+                Phone phone = PhoneFactory.getPhone(mSubscriptionManagerService
+                        .getPhoneId(currentSubId));
                 // If enable is true and it's not opportunistic subscription, we don't enable it,
                 // as there can't be two
                 if (phone != null) {
@@ -1053,19 +904,12 @@
      * are synced.
      */
     private void setRoamingDataEnabledForGroup(int subId, boolean enable) {
-        List<SubscriptionInfo> infoList;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo == null || subInfo.getGroupUuid().isEmpty()) return;
-            infoList = SubscriptionManagerService.getInstance().getSubscriptionsInGroup(
-                    ParcelUuid.fromString(subInfo.getGroupUuid()), mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        } else {
-            infoList = SubscriptionController.getInstance().getSubscriptionsInGroup(
-                    mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
-                    mContext.getAttributionTag());
-        }
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo == null || subInfo.getGroupUuid().isEmpty()) return;
+        List<SubscriptionInfo> infoList = SubscriptionManagerService.getInstance()
+                .getSubscriptionsInGroup(ParcelUuid.fromString(subInfo.getGroupUuid()),
+                        mContext.getOpPackageName(), mContext.getAttributionTag());
         if (infoList == null) return;
 
         for (SubscriptionInfo info : infoList) {
@@ -1118,19 +962,10 @@
     // subscription gets deactivated or removed, we need to automatically disable the grouped
     // opportunistic subscription, which will be marked isGroupDisabled as true by SubController.
     private void deactivateGroupedOpportunisticSubscriptionIfNeeded() {
-        if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return;
-
-        List<SubscriptionInfo> opptSubList;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            opptSubList = mSubscriptionManagerService.getAllSubInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag()).stream()
-                    .filter(SubscriptionInfo::isOpportunistic)
-                    .collect(Collectors.toList());
-
-        } else {
-            opptSubList = mSubController.getOpportunisticSubscriptions(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        }
+        List<SubscriptionInfo> opptSubList = mSubscriptionManagerService.getAllSubInfoList(
+                mContext.getOpPackageName(), mContext.getAttributionTag()).stream()
+                .filter(SubscriptionInfo::isOpportunistic)
+                .collect(Collectors.toList());
 
         if (ArrayUtils.isEmpty(opptSubList)) return;
 
@@ -1166,101 +1001,54 @@
     // would be selected as preferred voice/data/sms SIM.
     private void updateUserPreferences(List<Integer> primarySubList, boolean dataSelected,
             boolean voiceSelected, boolean smsSelected) {
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-
-            // In Single SIM case or if there are no activated subs available, no need to update.
-            // EXIT.
-            if ((primarySubList.isEmpty()) || (mSubscriptionManagerService
-                    .getActiveSubInfoCountMax() == 1)) {
-                return;
-            }
-
-            if (!isRadioAvailableOnAllSubs()) {
-                log("Radio is in Invalid state, Ignore Updating User Preference!!!");
-                return;
-            }
-            final int defaultDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
-
-            if (DBG) {
-                log("updateUserPreferences:  dds = " + defaultDataSubId + " voice = "
-                        + mSubscriptionManagerService.getDefaultVoiceSubId()
-                        + " sms = " + mSubscriptionManagerService.getDefaultSmsSubId());
-            }
-
-            int autoDefaultSubId = primarySubList.get(0);
-
-            if ((primarySubList.size() == 1) && !smsSelected) {
-                mSubscriptionManagerService.setDefaultSmsSubId(autoDefaultSubId);
-            }
-
-            if ((primarySubList.size() == 1) && !voiceSelected) {
-                mSubscriptionManagerService.setDefaultVoiceSubId(autoDefaultSubId);
-            }
-
-            int userPrefDataSubId = getUserPrefDataSubIdFromDB();
-
-            log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId
-                    + " next active subId " + autoDefaultSubId);
-
-            // If earlier user selected DDS is now available, set that as DDS subId.
-            if (primarySubList.contains(userPrefDataSubId)
-                    && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId)
-                    && (defaultDataSubId != userPrefDataSubId)) {
-                mSubscriptionManagerService.setDefaultDataSubId(userPrefDataSubId);
-            } else if (!dataSelected) {
-                mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId);
-            }
-
-            if (DBG) {
-                log("updateUserPreferences: after dds = "
-                        + mSubscriptionManagerService.getDefaultDataSubId() + " voice = "
-                        + mSubscriptionManagerService.getDefaultVoiceSubId() + " sms = "
-                        + mSubscriptionManagerService.getDefaultSmsSubId());
-            }
+        // In Single SIM case or if there are no activated subs available, no need to update.
+        // EXIT.
+        if ((primarySubList.isEmpty()) || (mSubscriptionManagerService
+                .getActiveSubInfoCountMax() == 1)) {
             return;
         }
-        // In Single SIM case or if there are no activated subs available, no need to update. EXIT.
-        if ((primarySubList.isEmpty()) || (mSubController.getActiveSubInfoCountMax() == 1)) return;
 
         if (!isRadioAvailableOnAllSubs()) {
             log("Radio is in Invalid state, Ignore Updating User Preference!!!");
             return;
         }
-        final int defaultDataSubId = mSubController.getDefaultDataSubId();
+        final int defaultDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
 
-        if (DBG) log("updateUserPreferences:  dds = " + defaultDataSubId + " voice = "
-                + mSubController.getDefaultVoiceSubId() +
-                " sms = " + mSubController.getDefaultSmsSubId());
+        if (DBG) {
+            log("updateUserPreferences:  dds = " + defaultDataSubId + " voice = "
+                    + mSubscriptionManagerService.getDefaultVoiceSubId()
+                    + " sms = " + mSubscriptionManagerService.getDefaultSmsSubId());
+        }
 
         int autoDefaultSubId = primarySubList.get(0);
 
         if ((primarySubList.size() == 1) && !smsSelected) {
-            mSubController.setDefaultSmsSubId(autoDefaultSubId);
+            mSubscriptionManagerService.setDefaultSmsSubId(autoDefaultSubId);
         }
 
         if ((primarySubList.size() == 1) && !voiceSelected) {
-            mSubController.setDefaultVoiceSubId(autoDefaultSubId);
+            mSubscriptionManagerService.setDefaultVoiceSubId(autoDefaultSubId);
         }
 
         int userPrefDataSubId = getUserPrefDataSubIdFromDB();
 
-        if (DBG) log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId
-                 + " next active subId " + autoDefaultSubId);
+        log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId
+                + " next active subId " + autoDefaultSubId);
 
         // If earlier user selected DDS is now available, set that as DDS subId.
-        if (primarySubList.contains(userPrefDataSubId) &&
-                SubscriptionManager.isValidSubscriptionId(userPrefDataSubId) &&
-                (defaultDataSubId != userPrefDataSubId)) {
-            mSubController.setDefaultDataSubId(userPrefDataSubId);
+        if (primarySubList.contains(userPrefDataSubId)
+                && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId)
+                && (defaultDataSubId != userPrefDataSubId)) {
+            mSubscriptionManagerService.setDefaultDataSubId(userPrefDataSubId);
         } else if (!dataSelected) {
-            mSubController.setDefaultDataSubId(autoDefaultSubId);
+            mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId);
         }
 
-
         if (DBG) {
-            log("updateUserPreferences: after dds = " + mSubController.getDefaultDataSubId()
-                    + " voice = " + mSubController.getDefaultVoiceSubId() + " sms = "
-                    + mSubController.getDefaultSmsSubId());
+            log("updateUserPreferences: after dds = "
+                    + mSubscriptionManagerService.getDefaultDataSubId() + " voice = "
+                    + mSubscriptionManagerService.getDefaultVoiceSubId() + " sms = "
+                    + mSubscriptionManagerService.getDefaultSmsSubId());
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/NetworkIndication.java b/src/java/com/android/internal/telephony/NetworkIndication.java
index c9ebfd5..7f9ff79 100644
--- a/src/java/com/android/internal/telephony/NetworkIndication.java
+++ b/src/java/com/android/internal/telephony/NetworkIndication.java
@@ -16,14 +16,17 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
 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_EMERGENCY_NETWORK_SCAN_RESULT;
 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_REGISTRATION_FAILED;
 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;
@@ -39,6 +42,7 @@
 import android.telephony.BarringInfo;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
+import android.telephony.EmergencyRegResult;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhysicalChannelConfig;
@@ -72,7 +76,7 @@
     public void barringInfoChanged(int indicationType,
             android.hardware.radio.network.CellIdentity cellIdentity,
             android.hardware.radio.network.BarringInfo[] barringInfos) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         if (cellIdentity == null || barringInfos == null) {
             reportAnomaly(UUID.fromString("645b16bb-c930-4c1c-9c5d-568696542e05"),
@@ -84,7 +88,7 @@
         BarringInfo cbi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
                 RILUtils.convertHalBarringInfoList(barringInfos));
 
-        mRil.mBarringInfoChangedRegistrants.notifyRegistrants(new AsyncResult(null, cbi, null));
+        mRil.notifyBarringInfoChanged(cbi);
     }
 
     /**
@@ -93,7 +97,7 @@
      * @param version PRL version after PRL changes
      */
     public void cdmaPrlChanged(int indicationType, int version) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         int[] response = new int[]{version};
 
@@ -109,7 +113,7 @@
      */
     public void cellInfoList(int indicationType,
             android.hardware.radio.network.CellInfo[] records) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
         ArrayList<CellInfo> response = RILUtils.convertHalCellInfoList(records);
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
         mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
@@ -122,7 +126,7 @@
      */
     public void currentLinkCapacityEstimate(int indicationType,
             android.hardware.radio.network.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
 
@@ -140,27 +144,34 @@
      */
     public void currentPhysicalChannelConfigs(int indicationType,
             android.hardware.radio.network.PhysicalChannelConfig[] configs) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
         List<PhysicalChannelConfig> response = new ArrayList<>(configs.length);
         try {
             for (android.hardware.radio.network.PhysicalChannelConfig config : configs) {
                 PhysicalChannelConfig.Builder builder = new PhysicalChannelConfig.Builder();
+                int band = PhysicalChannelConfig.BAND_UNKNOWN;
                 switch (config.band.getTag()) {
                     case android.hardware.radio.network.PhysicalChannelConfigBand.geranBand:
-                        builder.setBand(config.band.getGeranBand());
+                        band = config.band.getGeranBand();
                         break;
                     case android.hardware.radio.network.PhysicalChannelConfigBand.utranBand:
-                        builder.setBand(config.band.getUtranBand());
+                        band = config.band.getUtranBand();
                         break;
                     case android.hardware.radio.network.PhysicalChannelConfigBand.eutranBand:
-                        builder.setBand(config.band.getEutranBand());
+                        band = config.band.getEutranBand();
                         break;
                     case android.hardware.radio.network.PhysicalChannelConfigBand.ngranBand:
-                        builder.setBand(config.band.getNgranBand());
+                        band = config.band.getNgranBand();
                         break;
                     default:
                         mRil.riljLoge("Unsupported band type " + config.band.getTag());
                 }
+                if (band == PhysicalChannelConfig.BAND_UNKNOWN) {
+                    mRil.riljLoge("Unsupported unknown band.");
+                    return;
+                } else {
+                    builder.setBand(band);
+                }
                 response.add(builder.setCellConnectionStatus(
                         RILUtils.convertHalCellConnectionStatus(config.status))
                         .setDownlinkChannelNumber(config.downlinkChannelNumber)
@@ -191,7 +202,7 @@
      */
     public void currentSignalStrength(int indicationType,
             android.hardware.radio.network.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         SignalStrength ssInitial = RILUtils.convertHalSignalStrength(signalStrength);
 
@@ -209,7 +220,7 @@
      * @param indicationType Type of radio indication
      */
     public void imsNetworkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED);
 
@@ -223,7 +234,7 @@
      */
     public void networkScanResult(int indicationType,
             android.hardware.radio.network.NetworkScanResult result) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         ArrayList<CellInfo> cellInfos = RILUtils.convertHalCellInfoList(result.networkInfos);
         NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
@@ -236,7 +247,7 @@
      * @param indicationType Type of radio indication
      */
     public void networkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED);
 
@@ -256,7 +267,7 @@
      */
     public void nitzTimeReceived(int indicationType, String nitzTime,
         @ElapsedRealtimeLong long receivedTimeMs, long ageMs) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
 
@@ -303,23 +314,32 @@
     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);
+        mRil.processIndication(HAL_SERVICE_NETWORK, 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"),
+            reportAnomaly(UUID.fromString("f16e5703-6105-4341-9eb3-e68189156eb5"),
                     "Invalid registrationFailed indication");
 
-            mRil.riljLoge("Invalid registrationFailed indication");
+            mRil.riljLoge("Invalid registrationFailed indication (ci is null)=" + (ci == null)
+                    + " (chosenPlmn is empty)=" + TextUtils.isEmpty(chosenPlmn)
+                    + " (is CS/PS)=" + ((domain & NetworkRegistrationInfo.DOMAIN_CS_PS) == 0)
+                    + " (only CS/PS)=" + ((domain & ~NetworkRegistrationInfo.DOMAIN_CS_PS) != 0)
+                    + " (causeCode)=" + causeCode
+                    + " (additionalCauseCode)=" + additionalCauseCode);
             return;
         }
 
+        RegistrationFailedEvent registrationFailedEvent = new RegistrationFailedEvent(
+                ci, chosenPlmn, domain, causeCode, additionalCauseCode);
+        if (mRil.isLogOrTrace()) {
+            mRil.unsljLogMore(RIL_UNSOL_REGISTRATION_FAILED, registrationFailedEvent.toString());
+        }
         mRil.mRegistrationFailedRegistrant.notifyRegistrant(
-                new AsyncResult(null, new RegistrationFailedEvent(
-                        ci, chosenPlmn, domain, causeCode, additionalCauseCode), null));
+                new AsyncResult(null, registrationFailedEvent, null));
     }
 
     /**
@@ -328,7 +348,7 @@
      * @param state Bitmask of restricted state as defined by PhoneRestrictedState
      */
     public void restrictedStateChanged(int indicationType, int state) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogvRet(RIL_UNSOL_RESTRICTED_STATE_CHANGED, state);
 
@@ -344,7 +364,7 @@
      */
     public void suppSvcNotify(int indicationType,
             android.hardware.radio.network.SuppSvcNotification suppSvcNotification) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         SuppServiceNotification notification = new SuppServiceNotification();
         notification.notificationType = suppSvcNotification.isMT ? 1 : 0;
@@ -368,7 +388,7 @@
      * @param rat Current new voice rat
      */
     public void voiceRadioTechChanged(int indicationType, int rat) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
 
         int[] response = new int[] {rat};
 
@@ -380,6 +400,25 @@
                 new AsyncResult(null, response, null));
     }
 
+    /**
+     * Emergency Scan Results.
+     * @param indicationType Type of radio indication
+     * @param result the result of the Emergency Network Scan
+     */
+    public void emergencyNetworkScanResult(int indicationType,
+            android.hardware.radio.network.EmergencyRegResult result) {
+        mRil.processIndication(HAL_SERVICE_NETWORK, indicationType);
+
+        EmergencyRegResult response = RILUtils.convertHalEmergencyRegResult(result);
+
+        if (mRil.isLogOrTrace()) {
+            mRil.unsljLogRet(RIL_UNSOL_EMERGENCY_NETWORK_SCAN_RESULT, response);
+        }
+
+        mRil.mEmergencyNetworkScanRegistrants.notifyRegistrants(
+                new AsyncResult(null, response, null));
+    }
+
     @Override
     public String getInterfaceHash() {
         return IRadioNetworkIndication.HASH;
diff --git a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
index 3535678..91cd4ec 100644
--- a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
+++ b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
@@ -16,13 +16,10 @@
 
 package com.android.internal.telephony;
 
-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.AsyncResult;
 import android.os.Handler;
 import android.os.IBinder;
@@ -30,7 +27,6 @@
 import android.os.PersistableBundle;
 import android.os.RegistrantList;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.CarrierConfigManager;
@@ -58,9 +54,6 @@
     private final int mTransportType;
 
     private final Phone mPhone;
-
-    private final CarrierConfigManager mCarrierConfigManager;
-
     // Registrants who listens registration state change callback from this class.
     private final RegistrantList mRegStateChangeRegistrants = new RegistrantList();
 
@@ -72,22 +65,6 @@
 
     private NetworkServiceConnection mServiceConnection;
 
-    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.
-                logd("Carrier config changed. Try to bind network service.");
-                sendEmptyMessage(EVENT_BIND_NETWORK_SERVICE);
-            }
-        }
-    };
-
     public NetworkRegistrationManager(@TransportType int transportType, Phone phone) {
         mTransportType = transportType;
         mPhone = phone;
@@ -96,19 +73,20 @@
                 ? "C" : "I") + "-" + mPhone.getPhoneId();
         mTag = "NRM" + tagSuffix;
 
-        mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
-                Context.CARRIER_CONFIG_SERVICE);
+        CarrierConfigManager ccm = phone.getContext().getSystemService(CarrierConfigManager.class);
+        // Callback directly calls rebindService and should be executed in handler thread
+        ccm.registerCarrierConfigChangeListener(
+                this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) -> {
+                    if (slotIndex == phone.getPhoneId()) {
+                        // 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.
+                        logd("Carrier config changed. Try to bind network service.");
+                        rebindService();
+                    }
+                });
 
-        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_NETWORK_SERVICE, null);
 
@@ -333,9 +311,10 @@
         // 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))) {
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(), mPhone.getSubId(), carrierConfig);
+        if (!b.isEmpty() && !TextUtils.isEmpty(b.getString(carrierConfig))) {
             // If carrier config overrides it, use the one from carrier config
             packageName = b.getString(carrierConfig, packageName);
         }
@@ -367,15 +346,17 @@
         // Read class name from resource overlay
         className = mPhone.getContext().getResources().getString(resourceId);
 
-        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-        if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) {
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(), mPhone.getSubId(), carrierConfig);
+        if (!b.isEmpty() && !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 logd(String msg) {
         Rlog.d(mTag, msg);
     }
diff --git a/src/java/com/android/internal/telephony/NetworkResponse.java b/src/java/com/android/internal/telephony/NetworkResponse.java
index d9f70fd..b1eb926 100644
--- a/src/java/com/android/internal/telephony/NetworkResponse.java
+++ b/src/java/com/android/internal/telephony/NetworkResponse.java
@@ -16,12 +16,15 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+
 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.EmergencyRegResult;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.SignalStrength;
@@ -57,7 +60,7 @@
             int halRadioAccessFamilyBitmap) {
         int networkTypeBitmask = RILUtils.convertHalNetworkTypeBitMask(halRadioAccessFamilyBitmap);
         mRil.mAllowedNetworkTypesBitmask = networkTypeBitmask;
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, networkTypeBitmask);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, networkTypeBitmask);
     }
 
     /**
@@ -65,7 +68,7 @@
      * @param bandModes List of RadioBandMode listing supported modes
      */
     public void getAvailableBandModesResponse(RadioResponseInfo responseInfo, int[] bandModes) {
-        RadioResponse.responseIntArrayList(RIL.NETWORK_SERVICE, mRil, responseInfo,
+        RadioResponse.responseIntArrayList(HAL_SERVICE_NETWORK, mRil, responseInfo,
                 RILUtils.primitiveArrayToArrayList(bandModes));
     }
 
@@ -75,7 +78,7 @@
      */
     public void getAvailableNetworksResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.OperatorInfo[] networkInfos) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             ArrayList<OperatorInfo> ret = new ArrayList<>();
@@ -98,7 +101,7 @@
     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);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             BarringInfo bi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
@@ -118,7 +121,7 @@
      * @param type CdmaRoamingType defined in types.hal
      */
     public void getCdmaRoamingPreferenceResponse(RadioResponseInfo responseInfo, int type) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, type);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, type);
     }
 
     /**
@@ -127,7 +130,7 @@
      */
     public void getCellInfoListResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.CellInfo[] cellInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(cellInfo);
@@ -144,7 +147,7 @@
      */
     public void getDataRegistrationStateResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.RegStateResult dataRegResponse) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
@@ -161,7 +164,7 @@
      */
     public void getImsRegistrationStateResponse(RadioResponseInfo responseInfo,
             boolean isRegistered, int ratFamily) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, isRegistered ? 1 : 0,
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, isRegistered ? 1 : 0,
                 ratFamily == android.hardware.radio.RadioTechnologyFamily.THREE_GPP
                         ? PhoneConstants.PHONE_TYPE_GSM : PhoneConstants.PHONE_TYPE_CDMA);
     }
@@ -171,7 +174,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, selection ? 1 : 0);
     }
 
     /**
@@ -183,7 +186,7 @@
     public void getOperatorResponse(RadioResponseInfo responseInfo, String longName,
             String shortName, String numeric) {
         RadioResponse.responseStrings(
-                RIL.NETWORK_SERVICE, mRil, responseInfo, longName, shortName, numeric);
+                HAL_SERVICE_NETWORK, mRil, responseInfo, longName, shortName, numeric);
     }
 
     /**
@@ -192,7 +195,7 @@
      */
     public void getSignalStrengthResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.SignalStrength signalStrength) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
@@ -209,7 +212,7 @@
      */
     public void getSystemSelectionChannelsResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.RadioAccessSpecifier[] halSpecifiers) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             ArrayList<RadioAccessSpecifier> specifiers = new ArrayList<>();
@@ -229,7 +232,7 @@
      * @param rat Current voice RAT
      */
     public void getVoiceRadioTechnologyResponse(RadioResponseInfo responseInfo, int rat) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, rat);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, rat);
     }
 
     /**
@@ -238,7 +241,7 @@
      */
     public void getVoiceRegistrationStateResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.RegStateResult voiceRegResponse) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
                 RadioResponse.sendMessageResponse(rr.mResult, voiceRegResponse);
@@ -254,7 +257,7 @@
      */
     public void isNrDualConnectivityEnabledResponse(RadioResponseInfo responseInfo,
             boolean isEnabled) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
@@ -270,7 +273,7 @@
      */
     public void pullLceDataResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.network.LceDataInfo lceInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
 
         if (rr != null) {
             List<LinkCapacityEstimate> ret = RILUtils.convertHalLceData(lceInfo);
@@ -285,105 +288,105 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void setAllowedNetworkTypesBitmapResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, 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);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
         if (rr != null) {
             NetworkScanResult nsr = null;
             if (responseInfo.error == RadioError.NONE) {
@@ -399,7 +402,7 @@
      * @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);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
         if (rr != null) {
             NetworkScanResult nsr = null;
             if (responseInfo.error == RadioError.NONE) {
@@ -417,14 +420,14 @@
      */
     public void supplyNetworkDepersonalizationResponse(RadioResponseInfo responseInfo,
             int retriesRemaining) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, retriesRemaining);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
     }
 
     /**
@@ -433,7 +436,91 @@
      */
     public void getUsageSettingResponse(RadioResponseInfo responseInfo,
             /* @TelephonyManager.UsageSetting */ int usageSetting) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, usageSetting);
+        RadioResponse.responseInts(HAL_SERVICE_NETWORK, mRil, responseInfo, usageSetting);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     * @param regState the current registration state of the modem.
+     */
+    public void setEmergencyModeResponse(RadioResponseInfo responseInfo,
+            android.hardware.radio.network.EmergencyRegResult regState) {
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
+
+        if (rr != null) {
+            EmergencyRegResult response = RILUtils.convertHalEmergencyRegResult(regState);
+            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 triggerEmergencyNetworkScanResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     */
+    public void exitEmergencyModeResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     */
+    public void cancelEmergencyNetworkScanResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     */
+    public void setNullCipherAndIntegrityEnabledResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error.
+     * @param isEnabled Indicates whether null cipher and integrity is enabled, indicating
+     *                  potentially unencrypted communication
+     */
+    public void isNullCipherAndIntegrityEnabledResponse(RadioResponseInfo responseInfo,
+                    boolean isEnabled) {
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, 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 isEnabled Indicates whether N1 mode is enabled or not.
+     */
+    public void isN1ModeEnabledResponse(RadioResponseInfo responseInfo, boolean isEnabled) {
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, 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.
+     */
+    public void setN1ModeEnabledResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_NETWORK, mRil, responseInfo);
     }
 
     @Override
@@ -445,4 +532,5 @@
     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 b15dc59..7567566 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -197,14 +197,7 @@
     public static Set<String> getAllowedMccMncsForLocationRestrictedScan(Context context) {
         final long token = Binder.clearCallingIdentity();
         try {
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                return SubscriptionManagerService.getInstance()
-                        .getAvailableSubscriptionInfoList(context.getOpPackageName(),
-                                context.getAttributionTag()).stream()
-                        .flatMap(NetworkScanRequestTracker::getAllowableMccMncsFromSubscriptionInfo)
-                        .collect(Collectors.toSet());
-            }
-            return SubscriptionController.getInstance()
+            return SubscriptionManagerService.getInstance()
                     .getAvailableSubscriptionInfoList(context.getOpPackageName(),
                             context.getAttributionTag()).stream()
                     .flatMap(NetworkScanRequestTracker::getAllowableMccMncsFromSubscriptionInfo)
@@ -481,21 +474,21 @@
                     notifyMessenger(nsri, notifyMsg,
                             rilErrorToScanError(nsr.scanError), nsr.networkInfos);
                     if (nsr.scanStatus == NetworkScanResult.SCAN_STATUS_COMPLETE) {
-                        deleteScanAndMayNotify(nsri, NetworkScan.SUCCESS, true);
                         nsri.mPhone.mCi.unregisterForNetworkScanResult(mHandler);
+                        deleteScanAndMayNotify(nsri, NetworkScan.SUCCESS, true);
                     }
                 } else {
                     if (nsr.networkInfos != null) {
                         notifyMessenger(nsri, notifyMsg,
                                 rilErrorToScanError(nsr.scanError), nsr.networkInfos);
                     }
-                    deleteScanAndMayNotify(nsri, rilErrorToScanError(nsr.scanError), true);
                     nsri.mPhone.mCi.unregisterForNetworkScanResult(mHandler);
+                    deleteScanAndMayNotify(nsri, rilErrorToScanError(nsr.scanError), true);
                 }
             } else {
                 logEmptyResultOrException(ar);
-                deleteScanAndMayNotify(nsri, NetworkScan.ERROR_RADIO_INTERFACE_ERROR, true);
                 nsri.mPhone.mCi.unregisterForNetworkScanResult(mHandler);
+                deleteScanAndMayNotify(nsri, NetworkScan.ERROR_RADIO_INTERFACE_ERROR, true);
             }
         }
 
@@ -523,6 +516,7 @@
                 Log.e(TAG, "EVENT_STOP_NETWORK_SCAN_DONE: nsri is null");
                 return;
             }
+            nsri.mPhone.mCi.unregisterForNetworkScanResult(mHandler);
             if (ar.exception == null && ar.result != null) {
                 deleteScanAndMayNotify(nsri, NetworkScan.SUCCESS, true);
             } else {
@@ -535,7 +529,6 @@
                     Log.wtf(TAG, "EVENT_STOP_NETWORK_SCAN_DONE: ar.exception can not be null!");
                 }
             }
-            nsri.mPhone.mCi.unregisterForNetworkScanResult(mHandler);
         }
 
         // Interrupts the live scan is the scanId matches the mScanId of the mLiveRequestInfo.
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index f39c79b..f94ff26 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -31,7 +32,6 @@
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.data.DataCallResponse;
@@ -39,6 +39,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
+import com.android.internal.telephony.data.DataUtils;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.IState;
 import com.android.internal.util.IndentingPrintWriter;
@@ -52,6 +53,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -83,30 +85,35 @@
     /** Stop all timers and go to current state. */
     public static final int EVENT_UPDATE = 0;
     /** Quit after processing all existing messages. */
-    public static final int EVENT_QUIT = 1;
-    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_CHANNEL_CONFIG_NOTIF_CHANGED = 6;
-    private static final int EVENT_CARRIER_CONFIG_CHANGED = 7;
-    private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8;
-    private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9;
-    private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10;
-    private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
-    private static final int EVENT_INITIALIZE = 12;
-    private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
-    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 int EVENT_QUIT = 1;
+    /** Initialize all events. */
+    private static final int EVENT_INITIALIZE = 2;
+    /** Event for service state changed (data rat, bandwidth, NR state, NR frequency, etc). */
+    private static final int EVENT_SERVICE_STATE_CHANGED = 3;
+    /** Event for physical link status changed. */
+    private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 4;
+    /** Event for physical channel config indications turned on/off. */
+    private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 5;
+    /** Event for carrier configs changed. */
+    private static final int EVENT_CARRIER_CONFIG_CHANGED = 6;
+    /** Event for primary timer expired. If a secondary timer exists, it will begin afterwards. */
+    private static final int EVENT_PRIMARY_TIMER_EXPIRED = 7;
+    /** Event for secondary timer expired. */
+    private static final int EVENT_SECONDARY_TIMER_EXPIRED = 8;
+    /** Event for radio off or unavailable. */
+    private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 9;
+    /** Event for preferred network mode changed. */
+    private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 10;
+    /** Event for physical channel configs changed. */
+    private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 11;
+    /** Event for device idle mode changed, when device goes to deep sleep and pauses all timers. */
+    private static final int EVENT_DEVICE_IDLE_MODE_CHANGED = 12;
 
     private static final String[] sEvents = new String[EVENT_DEVICE_IDLE_MODE_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_SERVICE_STATE_CHANGED] = "EVENT_SERVICE_STATE_CHANGED";
         sEvents[EVENT_PHYSICAL_LINK_STATUS_CHANGED] = "EVENT_PHYSICAL_LINK_STATUS_CHANGED";
         sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED] =
                 "EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED";
@@ -117,25 +124,15 @@
         sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED";
         sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE";
         sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIG_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;
-    private final DisplayInfoController mDisplayInfoController;
-    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+    private final @NonNull Phone mPhone;
+    private final @NonNull DisplayInfoController mDisplayInfoController;
+    private final @NonNull 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;
@@ -143,20 +140,32 @@
         }
     };
 
-    private Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>();
-    private String mLteEnhancedPattern = "";
-    private int mOverrideNetworkType;
+    private final @NonNull CarrierConfigManager.CarrierConfigChangeListener
+            mCarrierConfigChangeListener =
+            new CarrierConfigManager.CarrierConfigChangeListener() {
+                @Override
+                public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
+                        int specificCarrierId) {
+                    // CarrierConfigChangeListener wouldn't send notification on device unlock
+                    if (slotIndex == mPhone.getPhoneId()) {
+                        sendMessage(EVENT_CARRIER_CONFIG_CHANGED);
+                    }
+                }
+            };
+
+    private @NonNull Map<String, OverrideTimerRule> mOverrideTimerRules = new HashMap<>();
+    private @NonNull String mLteEnhancedPattern = "";
+    private @Annotation.OverrideNetworkType int mOverrideNetworkType;
     private boolean mIsPhysicalChannelConfigOn;
     private boolean mIsPrimaryTimerActive;
     private boolean mIsSecondaryTimerActive;
-    private boolean mIsTimerResetEnabledForLegacyStateRRCIdle;
+    private boolean mIsTimerResetEnabledForLegacyStateRrcIdle;
     private int mLtePlusThresholdBandwidth;
     private int mNrAdvancedThresholdBandwidth;
-    private boolean mIncludeLteForNrAdvancedThresholdBandwidth;
-    private int[] mAdditionalNrAdvancedBandsList;
-    private String mPrimaryTimerState;
-    private String mSecondaryTimerState;
-    private String mPreviousState;
+    private @NonNull int[] mAdditionalNrAdvancedBandsList;
+    private @NonNull String mPrimaryTimerState;
+    private @NonNull String mSecondaryTimerState;
+    private @NonNull String mPreviousState;
     private @LinkStatus int mPhysicalLinkStatus;
     private boolean mIsPhysicalChannelConfig16Supported;
     private boolean mIsNrAdvancedAllowedByPco = false;
@@ -168,6 +177,10 @@
     private @Nullable DataNetworkControllerCallback mNrAdvancedCapableByPcoChangedCallback = null;
     private @Nullable DataNetworkControllerCallback mNrPhysicalLinkStatusChangedCallback = null;
 
+    // Cached copies below to prevent race conditions
+    private @NonNull ServiceState mServiceState;
+    private @Nullable List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+
     /**
      * NetworkTypeController constructor.
      *
@@ -180,13 +193,22 @@
         mDisplayInfoController = displayInfoController;
         mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
         mIsPhysicalChannelConfigOn = true;
-        addState(mDefaultState);
-        addState(mLegacyState, mDefaultState);
-        addState(mIdleState, mDefaultState);
-        addState(mLteConnectedState, mDefaultState);
-        addState(mNrConnectedState, mDefaultState);
-        setInitialState(mDefaultState);
+        mPrimaryTimerState = "";
+        mSecondaryTimerState = "";
+        mPreviousState = "";
+        DefaultState defaultState = new DefaultState();
+        addState(defaultState);
+        addState(mLegacyState, defaultState);
+        addState(mIdleState, defaultState);
+        addState(mLteConnectedState, defaultState);
+        addState(mNrConnectedState, defaultState);
+        addState(mNrConnectedAdvancedState, defaultState);
+        setInitialState(defaultState);
         start();
+
+        mServiceState = mPhone.getServiceStateTracker().getServiceState();
+        mPhysicalChannelConfigs = mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+
         sendMessage(EVENT_INITIALIZE);
     }
 
@@ -199,10 +221,21 @@
     }
 
     /**
-     * @return True if either the primary or secondary 5G hysteresis timer is active,
-     * and false if neither are.
+     * @return The current data network type, used to create TelephonyDisplayInfo in
+     * DisplayInfoController.
      */
-    public boolean is5GHysteresisActive() {
+    public @Annotation.NetworkType int getDataNetworkType() {
+        NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        return nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
+                : nri.getAccessNetworkTechnology();
+    }
+
+    /**
+     * @return {@code true} if either the primary or secondary 5G icon timers are active,
+     * and {@code false} if neither are.
+     */
+    public boolean areAnyTimersActive() {
         return mIsPrimaryTimerActive || mIsSecondaryTimerActive;
     }
 
@@ -213,142 +246,99 @@
                 EVENT_PREFERRED_NETWORK_MODE_CHANGED, null);
         mPhone.registerForPhysicalChannelConfig(getHandler(),
                 EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, null);
-        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(),
-                EVENT_DATA_RAT_CHANGED, null);
-        mPhone.getServiceStateTracker().registerForBandwidthChanged(
-                getHandler(), EVENT_BANDWIDTH_CHANGED, null);
+        mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
+                EVENT_SERVICE_STATE_CHANGED, null);
         mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService(
                 TelephonyManager.class).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
-        mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
-                EVENT_NR_STATE_CHANGED, null);
-        mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
-                EVENT_NR_FREQUENCY_CHANGED, null);
         mPhone.getDeviceStateMonitor().registerForPhysicalChannelConfigNotifChanged(getHandler(),
                 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);
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        ccm.registerCarrierConfigChangeListener(Runnable::run, mCarrierConfigChangeListener);
     }
 
     private void unRegisterForAllEvents() {
         mPhone.unregisterForRadioOffOrNotAvailable(getHandler());
         mPhone.unregisterForPreferredNetworkTypeChanged(getHandler());
-        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler());
-        mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler());
-        mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
+        mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
         mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler());
         mPhone.getContext().unregisterReceiver(mIntentReceiver);
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        if (mCarrierConfigChangeListener != null) {
+            ccm.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+        }
     }
 
     private void parseCarrierConfigs() {
-        String nrIconConfiguration = CarrierConfigManager.getDefaultConfig().getString(
-                CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
-        String overrideTimerRule = CarrierConfigManager.getDefaultConfig().getString(
-                CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING);
-        String overrideSecondaryTimerRule = CarrierConfigManager.getDefaultConfig().getString(
-                CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING);
-        mLteEnhancedPattern = CarrierConfigManager.getDefaultConfig().getString(
-                CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
-        mIsTimerResetEnabledForLegacyStateRRCIdle =
-                CarrierConfigManager.getDefaultConfig().getBoolean(
-                        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);
-        mIncludeLteForNrAdvancedThresholdBandwidth = CarrierConfigManager.getDefaultConfig()
-                .getBoolean(CarrierConfigManager
-                        .KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL);
-        mEnableNrAdvancedWhileRoaming = CarrierConfigManager.getDefaultConfig().getBoolean(
-                CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
-
-        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
-                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        PersistableBundle config = CarrierConfigManager.getDefaultConfig();
+        CarrierConfigManager configManager =
+                mPhone.getContext().getSystemService(CarrierConfigManager.class);
         if (configManager != null) {
             PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
             if (b != null) {
-                if (b.getString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING) != null) {
-                    nrIconConfiguration = b.getString(
-                            CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
-                }
-                if (b.getString(CarrierConfigManager
-                        .KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING) != null) {
-                    overrideTimerRule = b.getString(
-                            CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING);
-                }
-                if (b.getString(CarrierConfigManager
-                        .KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING) != null) {
-                    overrideSecondaryTimerRule = b.getString(
-                            CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING);
-                }
-                if (b.getString(CarrierConfigManager
-                        .KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING) != null) {
-                    mLteEnhancedPattern = b.getString(
-                            CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
-                }
-                mIsTimerResetEnabledForLegacyStateRRCIdle = b.getBoolean(
-                        CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL);
-                mLtePlusThresholdBandwidth = b.getInt(
-                        CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT,
-                        mLtePlusThresholdBandwidth);
-                mNrAdvancedThresholdBandwidth = b.getInt(
-                        CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT,
-                        mNrAdvancedThresholdBandwidth);
-                mIncludeLteForNrAdvancedThresholdBandwidth = b.getBoolean(CarrierConfigManager
-                        .KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
-                        mIncludeLteForNrAdvancedThresholdBandwidth);
-                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 && mNrAdvancedCapableByPcoChangedCallback == null) {
-                    mNrAdvancedCapableByPcoChangedCallback =
-                            new DataNetworkControllerCallback(getHandler()::post) {
-                        @Override
-                        public void onNrAdvancedCapableByPcoChanged(
-                                boolean nrAdvancedCapable) {
-                            log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
-                            mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
-                            sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE);
-                        }
-                    };
-                    mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
-                            mNrAdvancedCapableByPcoChangedCallback);
-                } else if (mNrAdvancedCapablePcoId == 0
-                        && mNrAdvancedCapableByPcoChangedCallback != null) {
-                    mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
-                            mNrAdvancedCapableByPcoChangedCallback);
-                    mNrAdvancedCapableByPcoChangedCallback = null;
-                }
-                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 (mNrPhysicalLinkStatusChangedCallback == null) {
-                        mNrPhysicalLinkStatusChangedCallback =
-                                new DataNetworkControllerCallback(getHandler()::post) {
-                            @Override
-                            public void onPhysicalLinkStatusChanged(
-                                    @LinkStatus int status) {
-                                sendMessage(obtainMessage(
-                                        EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                                        new AsyncResult(null, status, null)));
-                            }};
-                        mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
-                                mNrPhysicalLinkStatusChangedCallback);
-                    }
-                } else if (mNrPhysicalLinkStatusChangedCallback != null) {
-                    mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
-                            mNrPhysicalLinkStatusChangedCallback);
-                    mNrPhysicalLinkStatusChangedCallback = null;
-                }
+                config = b;
             }
         }
+        mLteEnhancedPattern = config.getString(
+                CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
+        mIsTimerResetEnabledForLegacyStateRrcIdle = config.getBoolean(
+                CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL);
+        mLtePlusThresholdBandwidth = config.getInt(
+                CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT);
+        mNrAdvancedThresholdBandwidth = config.getInt(
+                CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT);
+        mEnableNrAdvancedWhileRoaming = config.getBoolean(
+                CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
+        mAdditionalNrAdvancedBandsList = config.getIntArray(
+                CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
+        mNrAdvancedCapablePcoId = config.getInt(
+                CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
+        if (mNrAdvancedCapablePcoId > 0 && mNrAdvancedCapableByPcoChangedCallback == null) {
+            mNrAdvancedCapableByPcoChangedCallback =
+                    new DataNetworkControllerCallback(getHandler()::post) {
+                        @Override
+                        public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {
+                            log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
+                            mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
+                            sendMessage(EVENT_UPDATE);
+                        }
+                    };
+            mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+                    mNrAdvancedCapableByPcoChangedCallback);
+        } else if (mNrAdvancedCapablePcoId == 0 && mNrAdvancedCapableByPcoChangedCallback != null) {
+            mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
+                    mNrAdvancedCapableByPcoChangedCallback);
+            mNrAdvancedCapableByPcoChangedCallback = null;
+        }
+        mIsUsingUserDataForRrcDetection = config.getBoolean(
+                CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
+        if (!isUsingPhysicalChannelConfigForRrcDetection()) {
+            if (mNrPhysicalLinkStatusChangedCallback == null) {
+                mNrPhysicalLinkStatusChangedCallback =
+                        new DataNetworkControllerCallback(getHandler()::post) {
+                            @Override
+                            public void onPhysicalLinkStatusChanged(@LinkStatus int status) {
+                                sendMessage(obtainMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
+                                        new AsyncResult(null, status, null)));
+                            }
+                        };
+                mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+                        mNrPhysicalLinkStatusChangedCallback);
+            }
+        } else if (mNrPhysicalLinkStatusChangedCallback != null) {
+            mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
+                    mNrPhysicalLinkStatusChangedCallback);
+            mNrPhysicalLinkStatusChangedCallback = null;
+        }
+        String nrIconConfiguration = config.getString(
+                CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING);
+        String overrideTimerRule = config.getString(
+                CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING);
+        String overrideSecondaryTimerRule = config.getString(
+                CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING);
         createTimerRules(nrIconConfiguration, overrideTimerRule, overrideSecondaryTimerRule);
     }
 
@@ -357,7 +347,7 @@
         if (!TextUtils.isEmpty(icons)) {
             // Format: "STATE:ICON,STATE2:ICON2"
             for (String pair : icons.trim().split(",")) {
-                String[] kv = (pair.trim().toLowerCase()).split(":");
+                String[] kv = (pair.trim().toLowerCase(Locale.ROOT)).split(":");
                 if (kv.length != 2) {
                     if (DBG) loge("Invalid 5G icon configuration, config = " + pair);
                     continue;
@@ -384,7 +374,7 @@
         if (!TextUtils.isEmpty(timers)) {
             // Format: "FROM_STATE,TO_STATE,DURATION;FROM_STATE_2,TO_STATE_2,DURATION_2"
             for (String triple : timers.trim().split(";")) {
-                String[] kv = (triple.trim().toLowerCase()).split(",");
+                String[] kv = (triple.trim().toLowerCase(Locale.ROOT)).split(",");
                 if (kv.length != 3) {
                     if (DBG) loge("Invalid 5G icon timer configuration, config = " + triple);
                     continue;
@@ -410,7 +400,7 @@
         if (!TextUtils.isEmpty(secondaryTimers)) {
             // Format: "PRIMARY_STATE,TO_STATE,DURATION;PRIMARY_STATE_2,TO_STATE_2,DURATION_2"
             for (String triple : secondaryTimers.trim().split(";")) {
-                String[] kv = (triple.trim().toLowerCase()).split(",");
+                String[] kv = (triple.trim().toLowerCase(Locale.ROOT)).split(",");
                 if (kv.length != 3) {
                     if (DBG) {
                         loge("Invalid 5G icon secondary timer configuration, config = " + triple);
@@ -452,7 +442,7 @@
         int displayNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
         int dataNetworkType = getDataNetworkType();
         boolean nrNsa = isLte(dataNetworkType)
-                && mPhone.getServiceState().getNrState() != NetworkRegistrationInfo.NR_STATE_NONE;
+                && mServiceState.getNrState() != NetworkRegistrationInfo.NR_STATE_NONE;
         boolean nrSa = dataNetworkType == TelephonyManager.NETWORK_TYPE_NR;
 
         // NR display is not accurate when physical channel config notifications are off
@@ -483,7 +473,7 @@
                 keys.add(STATE_CONNECTED_NR_ADVANCED);
             }
         } else {
-            switch (mPhone.getServiceState().getNrState()) {
+            switch (mServiceState.getNrState()) {
                 case NetworkRegistrationInfo.NR_STATE_CONNECTED:
                     if (isNrAdvanced()) {
                         keys.add(STATE_CONNECTED_NR_ADVANCED);
@@ -513,9 +503,9 @@
     private @Annotation.OverrideNetworkType int getLteDisplayType() {
         int value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
         if ((getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA
-                || mPhone.getServiceState().isUsingCarrierAggregation())
-                && (IntStream.of(mPhone.getServiceState().getCellBandwidths()).sum()
-                        > mLtePlusThresholdBandwidth)) {
+                || mServiceState.isUsingCarrierAggregation())
+                && IntStream.of(mServiceState.getCellBandwidths()).sum()
+                > mLtePlusThresholdBandwidth) {
             value = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA;
         }
         if (isLteEnhancedAvailable()) {
@@ -529,8 +519,8 @@
             return false;
         }
         Pattern stringPattern = Pattern.compile(mLteEnhancedPattern);
-        for (String opName : new String[] {mPhone.getServiceState().getOperatorAlphaLongRaw(),
-                mPhone.getServiceState().getOperatorAlphaShortRaw()}) {
+        for (String opName : new String[] {mServiceState.getOperatorAlphaLongRaw(),
+                mServiceState.getOperatorAlphaShortRaw()}) {
             if (!TextUtils.isEmpty(opName)) {
                 Matcher matcher = stringPattern.matcher(opName);
                 if (matcher.find()) {
@@ -550,8 +540,6 @@
             if (DBG) log("DefaultState: process " + getEventName(msg.what));
             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;
@@ -568,20 +556,10 @@
                     registerForAllEvents();
                     parseCarrierConfigs();
                     break;
-                case EVENT_DATA_RAT_CHANGED:
-                case EVENT_NR_STATE_CHANGED:
-                case EVENT_NR_FREQUENCY_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();
-                    }
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    transitionToCurrentState();
                     break;
                 case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
@@ -623,6 +601,20 @@
                     resetAllTimers();
                     transitionTo(mLegacyState);
                     break;
+                case EVENT_PREFERRED_NETWORK_MODE_CHANGED:
+                    if (DBG) log("Reset timers since preferred network mode changed.");
+                    resetAllTimers();
+                    transitionToCurrentState();
+                    break;
+                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
+                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                    }
+                    transitionToCurrentState();
+                    break;
                 case EVENT_DEVICE_IDLE_MODE_CHANGED:
                     PowerManager pm = mPhone.getContext().getSystemService(PowerManager.class);
                     mIsDeviceIdleMode = pm.isDeviceIdleMode();
@@ -642,8 +634,6 @@
         }
     }
 
-    private final DefaultState mDefaultState = new DefaultState();
-
     /**
      * Device does not have NR available, due to any of the below reasons:
      * <ul>
@@ -671,11 +661,19 @@
         public boolean processMessage(Message msg) {
             if (DBG) log("LegacyState: process " + getEventName(msg.what));
             updateTimers();
-            int rat = getDataNetworkType();
             switch (msg.what) {
-                case EVENT_DATA_RAT_CHANGED:
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    // fallthrough
+                case EVENT_UPDATE:
+                    int rat = getDataNetworkType();
                     if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) {
-                        transitionTo(mNrConnectedState);
+                        if (isNrAdvanced()) {
+                            transitionTo(mNrConnectedAdvancedState);
+                        } else {
+                            transitionTo(mNrConnectedState);
+                        }
                     } else if (isLte(rat) && isNrNotRestricted()) {
                         transitionWithTimerTo(isPhysicalLinkActive()
                                 ? mLteConnectedState : mIdleState);
@@ -688,35 +686,22 @@
                     }
                     mIsNrRestricted = isNrRestricted();
                     break;
-                case EVENT_NR_STATE_CHANGED:
-                    if (isNrConnected()) {
-                        transitionTo(mNrConnectedState);
-                    } else if (isLte(rat) && isNrNotRestricted()) {
-                        transitionWithTimerTo(isPhysicalLinkActive()
-                                ? mLteConnectedState : mIdleState);
-                    } else if (isLte(rat) && isNrRestricted()) {
-                        updateOverrideNetworkType();
-                    }
-                    mIsNrRestricted = isNrRestricted();
-                    break;
-                case EVENT_NR_FREQUENCY_CHANGED:
-                    // ignored
-                    break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
                         mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
-                        if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) {
+                        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:
                     AsyncResult ar = (AsyncResult) msg.obj;
                     mPhysicalLinkStatus = (int) ar.result;
-                    if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) {
+                    if (mIsTimerResetEnabledForLegacyStateRrcIdle && !isPhysicalLinkActive()) {
                         if (DBG) log("Reset timers since timer reset is enabled for RRC idle.");
                         resetAllTimers();
                         updateOverrideNetworkType();
@@ -758,52 +743,52 @@
             if (DBG) log("IdleState: process " + getEventName(msg.what));
             updateTimers();
             switch (msg.what) {
-                case EVENT_DATA_RAT_CHANGED:
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    // fallthrough
+                case EVENT_UPDATE:
                     int rat = getDataNetworkType();
-                    if (rat == TelephonyManager.NETWORK_TYPE_NR) {
-                        transitionTo(mNrConnectedState);
+                    if (rat == TelephonyManager.NETWORK_TYPE_NR
+                            || (isLte(rat) && isNrConnected())) {
+                        if (isNrAdvanced()) {
+                            transitionTo(mNrConnectedAdvancedState);
+                        } else {
+                            transitionTo(mNrConnectedState);
+                        }
                     } else if (!isLte(rat) || !isNrNotRestricted()) {
                         transitionWithTimerTo(mLegacyState);
-                    }
-                    break;
-                case EVENT_NR_STATE_CHANGED:
-                    if (isNrConnected()) {
-                        transitionTo(mNrConnectedState);
-                    } else if (!isNrNotRestricted()) {
-                        transitionWithTimerTo(mLegacyState);
-                    }
-                    break;
-                case EVENT_NR_FREQUENCY_CHANGED:
-                    // ignore
-                    break;
-                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
-                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
-                        if (isNrNotRestricted()) {
-                            // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON
-                            if (isPhysicalLinkActive()) {
-                                transitionWithTimerTo(mLteConnectedState);
-                                break;
-                            }
+                    } else {
+                        if (isPhysicalLinkActive()) {
+                            transitionWithTimerTo(mLteConnectedState);
                         } else {
-                            log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
-                            sendMessage(EVENT_NR_STATE_CHANGED);
+                            // Update in case the override network type changed
+                            updateOverrideNetworkType();
                         }
                     }
-                    // Update in case of LTE/LTE+ switch
-                    updateOverrideNetworkType();
+                    break;
+                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
+                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        if (isPhysicalLinkActive()) {
+                            transitionWithTimerTo(mLteConnectedState);
+                        } else {
+                            log("Reevaluating state due to link status changed.");
+                            sendMessage(EVENT_UPDATE);
+                        }
+                    }
                     break;
                 case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
                     mPhysicalLinkStatus = (int) ar.result;
-                    if (isNrNotRestricted()) {
-                        // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON
-                        if (isPhysicalLinkActive()) {
-                            transitionWithTimerTo(mLteConnectedState);
-                        }
+                    if (isPhysicalLinkActive()) {
+                        transitionWithTimerTo(mLteConnectedState);
                     } else {
-                        log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
-                        sendMessage(EVENT_NR_STATE_CHANGED);
+                        log("Reevaluating state due to link status changed.");
+                        sendMessage(EVENT_UPDATE);
                     }
                     break;
                 default:
@@ -842,52 +827,52 @@
             if (DBG) log("LteConnectedState: process " + getEventName(msg.what));
             updateTimers();
             switch (msg.what) {
-                case EVENT_DATA_RAT_CHANGED:
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    // fallthrough
+                case EVENT_UPDATE:
                     int rat = getDataNetworkType();
-                    if (rat == TelephonyManager.NETWORK_TYPE_NR) {
-                        transitionTo(mNrConnectedState);
+                    if (rat == TelephonyManager.NETWORK_TYPE_NR
+                            || (isLte(rat) && isNrConnected())) {
+                        if (isNrAdvanced()) {
+                            transitionTo(mNrConnectedAdvancedState);
+                        } else {
+                            transitionTo(mNrConnectedState);
+                        }
                     } else if (!isLte(rat) || !isNrNotRestricted()) {
                         transitionWithTimerTo(mLegacyState);
-                    }
-                    break;
-                case EVENT_NR_STATE_CHANGED:
-                    if (isNrConnected()) {
-                        transitionTo(mNrConnectedState);
-                    } else if (!isNrNotRestricted()) {
-                        transitionWithTimerTo(mLegacyState);
-                    }
-                    break;
-                case EVENT_NR_FREQUENCY_CHANGED:
-                    // ignore
-                    break;
-                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
-                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
-                        if (isNrNotRestricted()) {
-                            // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE
-                            if (!isPhysicalLinkActive()) {
-                                transitionWithTimerTo(mIdleState);
-                                break;
-                            }
+                    } else {
+                        if (!isPhysicalLinkActive()) {
+                            transitionWithTimerTo(mIdleState);
                         } else {
-                            log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
-                            sendMessage(EVENT_NR_STATE_CHANGED);
+                            // Update in case the override network type changed
+                            updateOverrideNetworkType();
                         }
                     }
-                    // Update in case of LTE/LTE+ switch
-                    updateOverrideNetworkType();
+                    break;
+                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
+                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        if (!isPhysicalLinkActive()) {
+                            transitionWithTimerTo(mIdleState);
+                        } else {
+                            log("Reevaluating state due to link status changed.");
+                            sendMessage(EVENT_UPDATE);
+                        }
+                    }
                     break;
                 case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
                     mPhysicalLinkStatus = (int) ar.result;
-                    if (isNrNotRestricted()) {
-                        // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE
-                        if (!isPhysicalLinkActive()) {
-                            transitionWithTimerTo(mIdleState);
-                        }
+                    if (!isPhysicalLinkActive()) {
+                        transitionWithTimerTo(mIdleState);
                     } else {
-                        log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
-                        sendMessage(EVENT_NR_STATE_CHANGED);
+                        log("Reevaluating state due to link status changed.");
+                        sendMessage(EVENT_UPDATE);
                     }
                     break;
                 default:
@@ -911,28 +896,35 @@
      * Device is connected to 5G NR as the primary or secondary cell.
      */
     private final class NrConnectedState extends State {
-        private boolean mIsNrAdvanced = false;
-
         @Override
         public void enter() {
-            if (DBG) log("Entering NrConnectedState(" + getName() + ")");
+            if (DBG) log("Entering NrConnectedState");
             updateTimers();
             updateOverrideNetworkType();
             if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) {
-                mIsNrAdvanced = isNrAdvanced();
                 mPreviousState = getName();
             }
         }
 
         @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) {
-                case EVENT_DATA_RAT_CHANGED:
-                    if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) {
-                        updateOverrideNetworkType();
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    // fallthrough
+                case EVENT_UPDATE:
+                    int rat = getDataNetworkType();
+                    if (rat == TelephonyManager.NETWORK_TYPE_NR
+                            || (isLte(rat) && isNrConnected())) {
+                        if (isNrAdvanced()) {
+                            transitionTo(mNrConnectedAdvancedState);
+                        } else {
+                            // Update in case the override network type changed
+                            updateOverrideNetworkType();
+                        }
                     } else if (isLte(rat) && isNrNotRestricted()) {
                         transitionWithTimerTo(isPhysicalLinkActive()
                                 ? mLteConnectedState : mIdleState);
@@ -940,34 +932,21 @@
                         transitionWithTimerTo(mLegacyState);
                     }
                     break;
-                case EVENT_NR_STATE_CHANGED:
-                    if (isLte(rat) && isNrNotRestricted()) {
-                        transitionWithTimerTo(isPhysicalLinkActive()
-                                ? mLteConnectedState : mIdleState);
-                    } else if (rat != TelephonyManager.NETWORK_TYPE_NR && !isNrConnected()) {
-                        transitionWithTimerTo(mLegacyState);
-                    }
-                    break;
-                case EVENT_UPDATE_NR_ADVANCED_STATE:
-                    updateNrAdvancedState();
-                    break;
-                case EVENT_NR_FREQUENCY_CHANGED:
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
                         mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
                     }
-                    updateNrAdvancedState();
+                    // Check NR advanced in case NR advanced bands were added
+                    if (isNrAdvanced()) {
+                        transitionTo(mNrConnectedAdvancedState);
+                    }
                     break;
                 case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
                     mPhysicalLinkStatus = (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;
@@ -980,37 +959,96 @@
 
         @Override
         public String getName() {
-            return mIsNrAdvanced ? STATE_CONNECTED_NR_ADVANCED : STATE_CONNECTED;
-        }
-
-        private void updateNrAdvancedState() {
-            if (!isNrConnected() && getDataNetworkType() != TelephonyManager.NETWORK_TYPE_NR) {
-                log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
-                sendMessage(EVENT_NR_STATE_CHANGED);
-                return;
-            }
-            boolean isNrAdvanced = isNrAdvanced();
-            if (isNrAdvanced != mIsNrAdvanced) {
-                if (!isNrAdvanced) {
-                    if (DBG) log("updateNrAdvancedState: CONNECTED_NR_ADVANCED -> CONNECTED");
-                    transitionWithTimerTo(mNrConnectedState, STATE_CONNECTED);
-                } else {
-                    if (DBG) log("updateNrAdvancedState: CONNECTED -> CONNECTED_NR_ADVANCED");
-                    transitionTo(mNrConnectedState);
-                }
-            }
-            mIsNrAdvanced = isNrAdvanced();
-            log("mIsNrAdvanced=" + mIsNrAdvanced);
+            return STATE_CONNECTED;
         }
     }
 
     private final NrConnectedState mNrConnectedState = new NrConnectedState();
 
-    private void transitionWithTimerTo(IState destState) {
-        transitionWithTimerTo(destState, destState.getName());
+    /**
+     * Device is connected to 5G NR as the primary cell and the data rate is higher than
+     * the generic 5G data rate.
+     */
+    private final class NrConnectedAdvancedState extends State {
+        @Override
+        public void enter() {
+            if (DBG) log("Entering NrConnectedAdvancedState");
+            updateTimers();
+            updateOverrideNetworkType();
+            if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) {
+                mPreviousState = getName();
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (DBG) log("NrConnectedAdvancedState: process " + getEventName(msg.what));
+            updateTimers();
+            switch (msg.what) {
+                case EVENT_SERVICE_STATE_CHANGED:
+                    mServiceState = mPhone.getServiceStateTracker().getServiceState();
+                    if (DBG) log("ServiceState updated: " + mServiceState);
+                    // fallthrough
+                case EVENT_UPDATE:
+                    int rat = getDataNetworkType();
+                    if (rat == TelephonyManager.NETWORK_TYPE_NR
+                            || (isLte(rat) && isNrConnected())) {
+                        if (isNrAdvanced()) {
+                            // Update in case the override network type changed
+                            updateOverrideNetworkType();
+                        } else {
+                            if (rat == TelephonyManager.NETWORK_TYPE_NR && mOverrideNetworkType
+                                    != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) {
+                                // manually override network type after data rat changes since
+                                // timer will prevent it from being updated
+                                mOverrideNetworkType =
+                                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
+                            }
+                            transitionWithTimerTo(mNrConnectedState);
+                        }
+                    } else if (isLte(rat) && isNrNotRestricted()) {
+                        transitionWithTimerTo(isPhysicalLinkActive()
+                                ? mLteConnectedState : mIdleState);
+                    } else {
+                        transitionWithTimerTo(mLegacyState);
+                    }
+                    break;
+                case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
+                    mPhysicalChannelConfigs =
+                            mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
+                    if (DBG) log("Physical channel configs updated: " + mPhysicalChannelConfigs);
+                    if (isUsingPhysicalChannelConfigForRrcDetection()) {
+                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                    }
+                    // Check NR advanced in case NR advanced bands were removed
+                    if (!isNrAdvanced()) {
+                        transitionWithTimerTo(mNrConnectedState);
+                    }
+                    break;
+                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    mPhysicalLinkStatus = (int) ar.result;
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) {
+                mPreviousState = getName();
+            }
+            return HANDLED;
+        }
+
+        @Override
+        public String getName() {
+            return STATE_CONNECTED_NR_ADVANCED;
+        }
     }
 
-    private void transitionWithTimerTo(IState destState, String destName) {
+    private final NrConnectedAdvancedState mNrConnectedAdvancedState =
+            new NrConnectedAdvancedState();
+
+    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) {
@@ -1046,22 +1084,23 @@
     private void transitionToCurrentState() {
         int dataRat = getDataNetworkType();
         IState transitionState;
-        if (dataRat == TelephonyManager.NETWORK_TYPE_NR || isNrConnected()) {
-            transitionState = mNrConnectedState;
-            mPreviousState = isNrAdvanced() ? STATE_CONNECTED_NR_ADVANCED : STATE_CONNECTED;
+        if (dataRat == TelephonyManager.NETWORK_TYPE_NR || (isLte(dataRat) && isNrConnected())) {
+            if (isNrAdvanced()) {
+                transitionState = mNrConnectedAdvancedState;
+            } else {
+                transitionState = mNrConnectedState;
+            }
         } else if (isLte(dataRat) && isNrNotRestricted()) {
             if (isPhysicalLinkActive()) {
                 transitionState = mLteConnectedState;
-                mPreviousState = STATE_NOT_RESTRICTED_RRC_CON;
             } else {
                 transitionState = mIdleState;
-                mPreviousState = STATE_NOT_RESTRICTED_RRC_IDLE;
             }
         } else {
             transitionState = mLegacyState;
-            mPreviousState = isNrRestricted() ? STATE_RESTRICTED : STATE_LEGACY;
         }
         if (!transitionState.equals(getCurrentState())) {
+            mPreviousState = getCurrentState().getName();
             transitionTo(transitionState);
         } else {
             updateOverrideNetworkType();
@@ -1108,12 +1147,17 @@
             if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) {
                 if (DBG) log("Reset timers since state is 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.");
+            } else if (currentState.equals(STATE_CONNECTED)
+                    && !mPrimaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED)
+                    && !mSecondaryTimerState.equals(STATE_CONNECTED_NR_ADVANCED)) {
+                if (DBG) log("Reset non-NR_ADVANCED timers since state is NR_CONNECTED");
                 resetAllTimers();
+            } else {
+                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();
+                }
             }
         }
     }
@@ -1210,17 +1254,15 @@
     }
 
     private boolean isNrConnected() {
-        return mPhone.getServiceState().getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED;
+        return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED;
     }
 
     private boolean isNrNotRestricted() {
-        return mPhone.getServiceState().getNrState()
-                == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED;
+        return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED;
     }
 
     private boolean isNrRestricted() {
-        return mPhone.getServiceState().getNrState()
-                == NetworkRegistrationInfo.NR_STATE_RESTRICTED;
+        return mServiceState.getNrState() == NetworkRegistrationInfo.NR_STATE_RESTRICTED;
     }
 
     /**
@@ -1235,23 +1277,15 @@
 
         // 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) {
+        if (mServiceState.getDataRoaming() && !mEnableNrAdvancedWhileRoaming) {
             return false;
         }
 
-        int bandwidths = 0;
-        if (mPhone.getServiceStateTracker().getPhysicalChannelConfigList() != null) {
-            bandwidths = mPhone.getServiceStateTracker().getPhysicalChannelConfigList()
-                    .stream()
-                    .filter(config -> mIncludeLteForNrAdvancedThresholdBandwidth
-                            || config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR)
-                    .map(PhysicalChannelConfig::getCellBandwidthDownlinkKhz)
-                    .mapToInt(Integer::intValue)
-                    .sum();
-        }
         // Check if meeting minimum bandwidth requirement. For most carriers, there is no minimum
         // bandwidth requirement and mNrAdvancedThresholdBandwidth is 0.
-        if (mNrAdvancedThresholdBandwidth > 0 && bandwidths < mNrAdvancedThresholdBandwidth) {
+        if (mNrAdvancedThresholdBandwidth > 0
+                && IntStream.of(mPhone.getServiceState().getCellBandwidths()).sum()
+                < mNrAdvancedThresholdBandwidth) {
             return false;
         }
 
@@ -1261,18 +1295,15 @@
     }
 
     private boolean isNrMmwave() {
-        return mPhone.getServiceState().getNrFrequencyRange()
-                == ServiceState.FREQUENCY_RANGE_MMWAVE;
+        return mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE;
     }
 
     private boolean isAdditionalNrAdvancedBand() {
-        List<PhysicalChannelConfig> physicalChannelConfigList =
-                mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
         if (ArrayUtils.isEmpty(mAdditionalNrAdvancedBandsList)
-                || physicalChannelConfigList == null) {
+                || mPhysicalChannelConfigs == null) {
             return false;
         }
-        for (PhysicalChannelConfig item : physicalChannelConfigList) {
+        for (PhysicalChannelConfig item : mPhysicalChannelConfigs) {
             if (item.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR
                     && ArrayUtils.contains(mAdditionalNrAdvancedBandsList, item.getBand())) {
                 return true;
@@ -1291,19 +1322,10 @@
     }
 
     private int getPhysicalLinkStatusFromPhysicalChannelConfig() {
-        List<PhysicalChannelConfig> physicalChannelConfigList =
-                mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
-        return (physicalChannelConfigList == null || physicalChannelConfigList.isEmpty())
+        return (mPhysicalChannelConfigs == null || mPhysicalChannelConfigs.isEmpty())
                 ? DataCallResponse.LINK_STATUS_DORMANT : DataCallResponse.LINK_STATUS_ACTIVE;
     }
 
-    private int getDataNetworkType() {
-        NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        return nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
-                : nri.getAccessNetworkTechnology();
-    }
-
     private String getEventName(int event) {
         try {
             return sEvents[event];
@@ -1350,16 +1372,16 @@
         pw.println("mIsPhysicalChannelConfigOn=" + mIsPhysicalChannelConfigOn);
         pw.println("mIsPrimaryTimerActive=" + mIsPrimaryTimerActive);
         pw.println("mIsSecondaryTimerActive=" + mIsSecondaryTimerActive);
-        pw.println("mIsTimerRestEnabledForLegacyStateRRCIdle="
-                + mIsTimerResetEnabledForLegacyStateRRCIdle);
+        pw.println("mIsTimerResetEnabledForLegacyStateRrcIdle="
+                + mIsTimerResetEnabledForLegacyStateRrcIdle);
         pw.println("mLtePlusThresholdBandwidth=" + mLtePlusThresholdBandwidth);
         pw.println("mNrAdvancedThresholdBandwidth=" + mNrAdvancedThresholdBandwidth);
+        pw.println("mAdditionalNrAdvancedBandsList="
+                + Arrays.toString(mAdditionalNrAdvancedBandsList));
         pw.println("mPrimaryTimerState=" + mPrimaryTimerState);
         pw.println("mSecondaryTimerState=" + mSecondaryTimerState);
         pw.println("mPreviousState=" + mPreviousState);
-        pw.println("mPhysicalLinkStatus=" + mPhysicalLinkStatus);
-        pw.println("mAdditionalNrAdvancedBandsList="
-                + Arrays.toString(mAdditionalNrAdvancedBandsList));
+        pw.println("mPhysicalLinkStatus=" + DataUtils.linkStatusToString(mPhysicalLinkStatus));
         pw.println("mIsPhysicalChannelConfig16Supported=" + mIsPhysicalChannelConfig16Supported);
         pw.println("mIsNrAdvancedAllowedByPco=" + mIsNrAdvancedAllowedByPco);
         pw.println("mNrAdvancedCapablePcoId=" + mNrAdvancedCapablePcoId);
diff --git a/src/java/com/android/internal/telephony/NitzSignal.java b/src/java/com/android/internal/telephony/NitzSignal.java
index 889fe95..2619f3d 100644
--- a/src/java/com/android/internal/telephony/NitzSignal.java
+++ b/src/java/com/android/internal/telephony/NitzSignal.java
@@ -19,7 +19,7 @@
 import android.annotation.DurationMillisLong;
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
-import android.os.TimestampedValue;
+import android.app.time.UnixEpochTime;
 
 import java.time.Duration;
 import java.util.Objects;
@@ -88,13 +88,12 @@
     }
 
     /**
-     * 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.
+     * Creates a {@link UnixEpochTime} 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<>(
+    public UnixEpochTime createTimeSignal() {
+        return new UnixEpochTime(
                 getAgeAdjustedElapsedRealtimeMillis(),
                 getNitzData().getCurrentTimeInMillis());
     }
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index b5fc9df..4e62d20 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.BroadcastOptions;
@@ -24,6 +26,7 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
+import android.hardware.radio.modem.ImeiInfo;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Build;
@@ -35,17 +38,21 @@
 import android.os.RegistrantList;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
-import android.provider.DeviceConfig;
 import android.sysprop.TelephonyProperties;
 import android.telecom.VideoProfile;
 import android.telephony.AccessNetworkConstants;
+import android.telephony.Annotation.SrvccState;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CarrierRestrictionRules;
+import android.telephony.CellBroadcastIdRange;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
 import android.telephony.ClientRequestStats;
+import android.telephony.DomainSelectionService;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.NetworkRegistrationInfo;
@@ -60,9 +67,12 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.HalService;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.satellite.SatelliteDatagram;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -78,7 +88,11 @@
 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.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.emergency.EmergencyConstants;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
+import com.android.internal.telephony.imsphone.ImsCallInfo;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCall;
 import com.android.internal.telephony.metrics.SmsStats;
@@ -168,7 +182,8 @@
     protected static final int EVENT_RADIO_ON                    = 5;
     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;
+    @VisibleForTesting
+    public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
     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;
@@ -232,8 +247,12 @@
     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_IMS_DEREGISTRATION_TRIGGERED = 65;
+    protected static final int EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE = 66;
+    protected static final int EVENT_GET_DEVICE_IMEI_DONE = 67;
+    protected static final int EVENT_TRIGGER_NOTIFY_ANBR = 68;
 
-    protected static final int EVENT_LAST = EVENT_SET_USAGE_SETTING_DONE;
+    protected static final int EVENT_LAST = EVENT_TRIGGER_NOTIFY_ANBR;
 
     // For shared prefs.
     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
@@ -260,6 +279,10 @@
     // Integer used to let the calling application know that the we are ignoring auto mode switch.
     private static final int ALREADY_IN_AUTO_SELECTION = 1;
 
+    public static final String PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED =
+            "pref_null_cipher_and_integrity_enabled";
+    private final TelephonyAdminReceiver m2gAdminUpdater;
+
     /**
      * This method is invoked when the Phone exits Emergency Callback Mode.
      */
@@ -328,7 +351,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected AtomicReference<UiccCardApplication> mUiccApplication =
             new AtomicReference<UiccCardApplication>();
-    TelephonyTester mTelephonyTester;
+    private TelephonyTester mTelephonyTester;
     private String mName;
     private final String mActionDetached;
     private final String mActionAttached;
@@ -357,12 +380,6 @@
     private int mUsageSettingFromModem = SubscriptionManager.USAGE_SETTING_UNKNOWN;
     private boolean mIsUsageSettingSupported = true;
 
-    /**
-     * {@code true} if the new SubscriptionManagerService is enabled, otherwise the old
-     * SubscriptionController is used.
-     */
-    private boolean mIsSubscriptionManagerServiceEnabled = false;
-
     //IMS
     /**
      * {@link CallStateException} message text used to indicate that an IMS call has failed because
@@ -391,7 +408,7 @@
     public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
     public static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage";
 
-    private final RegistrantList mPreciseCallStateRegistrants = new RegistrantList();
+    protected final RegistrantList mPreciseCallStateRegistrants = new RegistrantList();
 
     private final RegistrantList mHandoverRegistrants = new RegistrantList();
 
@@ -466,6 +483,10 @@
 
     protected LinkBandwidthEstimator mLinkBandwidthEstimator;
 
+    public static final int IMEI_TYPE_UNKNOWN = -1;
+    public static final int IMEI_TYPE_PRIMARY = ImeiInfo.ImeiType.PRIMARY;
+    public static final int IMEI_TYPE_SECONDARY = ImeiInfo.ImeiType.SECONDARY;
+
     public IccRecords getIccRecords() {
         return mIccRecords.get();
     }
@@ -603,14 +624,8 @@
         // Initialize SMS stats
         mSmsStats = new SmsStats(this);
 
-        // This is a temp flag which will be removed before U AOSP public release.
-        mIsSubscriptionManagerServiceEnabled = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_using_subscription_manager_service)
-                || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY,
-                "enable_subscription_manager_service", false);
-        if (isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService = SubscriptionManagerService.getInstance();
-        }
+        mSubscriptionManagerService = SubscriptionManagerService.getInstance();
+        m2gAdminUpdater = new TelephonyAdminReceiver(context, this);
 
         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
             return;
@@ -860,7 +875,11 @@
         return null;
     }
 
-    public void notifySrvccState(Call.SrvccState state) {
+    /**
+     * Notifies the change of the SRVCC state.
+     * @param state the new SRVCC state.
+     */
+    public void notifySrvccState(@SrvccState int state) {
     }
 
     public void registerForSilentRedial(Handler h, int what, Object obj) {
@@ -883,6 +902,9 @@
         Call.SrvccState srvccState = Call.SrvccState.NONE;
         if (ret != null && ret.length != 0) {
             int state = ret[0];
+            if (imsPhone != null) {
+                imsPhone.notifySrvccState(state);
+            }
             switch(state) {
                 case TelephonyManager.SRVCC_STATE_HANDOVER_STARTED:
                     srvccState = Call.SrvccState.STARTED;
@@ -895,11 +917,6 @@
                     break;
                 case TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED:
                     srvccState = Call.SrvccState.COMPLETED;
-                    if (imsPhone != null) {
-                        imsPhone.notifySrvccState(srvccState);
-                    } else {
-                        Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
-                    }
                     break;
                 case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
                 case TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED:
@@ -974,17 +991,6 @@
     }
 
     /**
-     * Subclasses of Phone probably want to replace this with a
-     * version scoped to their packages
-     */
-    protected void notifyPreciseCallStateChangedP() {
-        AsyncResult ar = new AsyncResult(null, this, null);
-        mPreciseCallStateRegistrants.notifyRegistrants(ar);
-
-        mNotifier.notifyPreciseCallState(this);
-    }
-
-    /**
      * Notifies when a Handover happens due to SRVCC or Silent Redial
      */
     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
@@ -1431,8 +1437,8 @@
     @UnsupportedAppUsage
     public void setNetworkSelectionModeAutomatic(Message response) {
         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
-        // we don't want to do this unecesarily - it acutally causes
-        // the radio to repeate network selection and is costly
+        // we don't want to do this unnecessarily - it actually causes
+        // the radio to repeat network selection and is costly
         // first check if we're already in automatic mode
         Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC);
         msg.obj = response;
@@ -1465,6 +1471,7 @@
         nsm.operatorAlphaShort = "";
 
         if (doAutomatic) {
+            Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - set network selection auto");
             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
             mCi.setNetworkSelectionModeAutomatic(msg);
         } else {
@@ -1921,7 +1928,7 @@
     public boolean isRadioOffForThermalMitigation() {
         ServiceStateTracker sst = getServiceStateTracker();
         return sst != null && sst.getRadioPowerOffReasons()
-                .contains(Phone.RADIO_POWER_REASON_THERMAL);
+                .contains(TelephonyManager.RADIO_POWER_REASON_THERMAL);
     }
 
     /**
@@ -2308,6 +2315,12 @@
         if (!mIsCarrierNrSupported) {
             allowedNetworkTypes &= ~TelephonyManager.NETWORK_TYPE_BITMASK_NR;
         }
+        if (m2gAdminUpdater.isCellular2gDisabled()) {
+            logd("SubId " + getSubId()
+                    + " disabling 2g in getEffectiveAllowedNetworkTypes according to admin user "
+                    + "restriction");
+            allowedNetworkTypes &= ~TelephonyManager.NETWORK_CLASS_BITMASK_2G;
+        }
         logd("SubId" + getSubId() + ",getEffectiveAllowedNetworkTypes: "
                 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
         return allowedNetworkTypes;
@@ -2384,21 +2397,10 @@
      */
     public void loadAllowedNetworksFromSubscriptionDatabase() {
         String result = null;
-        if (isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(getSubId());
-            if (subInfo != null) {
-                result = subInfo.getAllowedNetworkTypesForReasons();
-            }
-        } else {
-            // Try to load ALLOWED_NETWORK_TYPES from SIMINFO.
-            if (SubscriptionController.getInstance() == null) {
-                return;
-            }
-
-            result = SubscriptionController.getInstance().getSubscriptionProperty(
-                    getSubId(),
-                    SubscriptionManager.ALLOWED_NETWORK_TYPES);
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(getSubId());
+        if (subInfo != null) {
+            result = subInfo.getAllowedNetworkTypesForReasons();
         }
 
         // After fw load network type from DB, do unlock if subId is valid.
@@ -2415,14 +2417,14 @@
         try {
             // Format: "REASON=VALUE,REASON2=VALUE2"
             for (String pair : result.trim().split(",")) {
-                String[] networkTypesValues = (pair.trim().toLowerCase()).split("=");
+                String[] networkTypesValues = (pair.trim().toLowerCase(Locale.ROOT)).split("=");
                 if (networkTypesValues.length != 2) {
                     Rlog.e(LOG_TAG, "Invalid ALLOWED_NETWORK_TYPES from DB, value = " + pair);
                     continue;
                 }
                 int key = convertAllowedNetworkTypeDbNameToMapIndex(networkTypesValues[0]);
                 long value = Long.parseLong(networkTypesValues[1]);
-                if (key != INVALID_ALLOWED_NETWORK_TYPES
+                if (TelephonyManager.isValidAllowedNetworkTypesReason(key)
                         && value != INVALID_ALLOWED_NETWORK_TYPES) {
                     synchronized (mAllowedNetworkTypesForReasons) {
                         mAllowedNetworkTypesForReasons.put(key, value);
@@ -2460,7 +2462,15 @@
         }
     }
 
-    private String convertAllowedNetworkTypeMapIndexToDbName(int reason) {
+    /**
+     * Convert the allowed network types reason to string.
+     *
+     * @param reason The allowed network types reason.
+     *
+     * @return The converted string.
+     */
+    public static String convertAllowedNetworkTypeMapIndexToDbName(
+            @TelephonyManager.AllowedNetworkTypesReason int reason) {
         switch (reason) {
             case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER:
                 return ALLOWED_NETWORK_TYPES_TEXT_USER;
@@ -2471,7 +2481,10 @@
             case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G:
                 return ALLOWED_NETWORK_TYPES_TEXT_ENABLE_2G;
             default:
-                return Integer.toString(INVALID_ALLOWED_NETWORK_TYPES);
+                throw new IllegalArgumentException(
+                        "No DB name conversion available for allowed network type reason: " + reason
+                                + ". Did you forget to add an ALLOWED_NETWORK_TYPE_TEXT entry for"
+                                + " a new reason?");
         }
     }
 
@@ -2971,6 +2984,9 @@
     // This property is used to handle phone process crashes, and is the same for CDMA and IMS
     // phones
     protected static boolean getInEcmMode() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            return EmergencyStateTracker.getInstance().isInEcm();
+        }
         return TelephonyProperties.in_ecm_mode().orElse(false);
     }
 
@@ -2980,6 +2996,9 @@
      * emergency operator.
      */
     public boolean isInEcm() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            return EmergencyStateTracker.getInstance().isInEcm();
+        }
         return mIsPhoneInEcmState;
     }
 
@@ -2988,6 +3007,9 @@
     }
 
     public boolean isInCdmaEcm() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            return EmergencyStateTracker.getInstance().isInCdmaEcm();
+        }
         return getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && isInEcm()
                 && (mImsPhone == null || !mImsPhone.isInImsEcm());
     }
@@ -4073,17 +4095,7 @@
      */
     @UnsupportedAppUsage
     public int getSubId() {
-        if (isSubscriptionManagerServiceEnabled()) {
-            return mSubscriptionManagerService.getSubId(mPhoneId);
-        }
-        if (SubscriptionController.getInstance() == null) {
-            // TODO b/78359408 getInstance sometimes returns null in Treehugger tests, which causes
-            // flakiness. Even though we haven't seen this crash in the wild we should keep this
-            // check in until we've figured out the root cause.
-            Rlog.e(LOG_TAG, "SubscriptionController.getInstance = null! Returning default subId");
-            return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        }
-        return SubscriptionController.getInstance().getSubId(mPhoneId);
+        return mSubscriptionManagerService.getSubId(mPhoneId);
     }
 
     /**
@@ -4379,6 +4391,7 @@
         // When radio capability switch is done, query IMEI value and update it in Phone objects
         // to make it in sync with the IMEI value currently used by Logical-Modem.
         if (capabilitySwitched) {
+            mCi.getImei(obtainMessage(EVENT_GET_DEVICE_IMEI_DONE));
             mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
         }
     }
@@ -4398,14 +4411,10 @@
 
     private int getResolvedUsageSetting(int subId) {
         SubscriptionInfo subInfo = null;
-        if (isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfoInternal = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfoInternal != null) {
-                subInfo = subInfoInternal.toSubscriptionInfo();
-            }
-        } else {
-            subInfo = SubscriptionController.getInstance().getSubscriptionInfo(subId);
+        SubscriptionInfoInternal subInfoInternal = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(subId);
+        if (subInfoInternal != null) {
+            subInfo = subInfoInternal.toSubscriptionInfo();
         }
 
         if (subInfo == null
@@ -4742,10 +4751,24 @@
      * Get the HAL version.
      *
      * @return the current HalVersion
+     *
+     * @deprecated Use {@link #getHalVersion(int service)} instead.
      */
+    @Deprecated
     public HalVersion getHalVersion() {
+        return getHalVersion(HAL_SERVICE_RADIO);
+    }
+
+    /**
+     * Get the HAL version with a specific service.
+     *
+     * @param service the service id to query
+     * @return the current HalVersion for a specific service
+     *
+     */
+    public HalVersion getHalVersion(@HalService int service) {
         if (mCi != null && mCi instanceof RIL) {
-            return ((RIL) mCi).getHalVersion();
+            return ((RIL) mCi).getHalVersion(service);
         }
         return RIL.RADIO_HAL_VERSION_UNKNOWN;
     }
@@ -4889,11 +4912,600 @@
     }
 
     /**
-     * @return {@code true} if the new {@link SubscriptionManagerService} is enabled, otherwise the
-     * old {@link SubscriptionController} is used.
+     * Returns the user's last setting for terminal-based call waiting
+     * @param forCsOnly indicates the caller expects the result for CS calls only
      */
-    public boolean isSubscriptionManagerServiceEnabled() {
-        return mIsSubscriptionManagerServiceEnabled;
+    public int getTerminalBasedCallWaitingState(boolean forCsOnly) {
+        return CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED;
+    }
+
+    /**
+     * Notifies the change of the user setting of the terminal-based call waiting service
+     * to IMS service.
+     */
+    public void setTerminalBasedCallWaitingStatus(int state) {
+    }
+
+    /**
+     * Notifies that the IMS service connected supports the terminal-based call waiting service
+     */
+    public void setTerminalBasedCallWaitingSupported(boolean supported) {
+    }
+
+    /**
+     * Notifies the NAS and RRC layers of the radio the type of upcoming IMS traffic.
+     *
+     * @param token A nonce to identify the request.
+     * @param trafficType IMS traffic type like registration, voice, video, SMS, emergency, and etc.
+     * @param accessNetworkType The type of the radio access network used.
+     * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+     *        mobile terminated use case eg. MO/MT call/SMS etc.
+     * @param response is callback message.
+     */
+    public void startImsTraffic(int token,
+            @MmTelFeature.ImsTrafficType int trafficType,
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+            @MmTelFeature.ImsTrafficDirection int trafficDirection, Message response) {
+        mCi.startImsTraffic(token, trafficType, accessNetworkType, trafficDirection, response);
+    }
+
+    /**
+     * Notifies IMS traffic has been stopped.
+     *
+     * @param token The token assigned by startImsTraffic.
+     * @param response is callback message.
+     */
+    public void stopImsTraffic(int token, Message response) {
+        mCi.stopImsTraffic(token, response);
+    }
+
+    /**
+     * Register for notifications of connection setup failure
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForConnectionSetupFailure(Handler h, int what, Object obj) {
+        mCi.registerForConnectionSetupFailure(h, what, obj);
+    }
+
+    /**
+     * Unregister for notifications of connection setup failure
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForConnectionSetupFailure(Handler h) {
+        mCi.unregisterForConnectionSetupFailure(h);
+    }
+
+    /**
+     * Triggers the UE initiated EPS fallback procedure.
+     *
+     * @param reason specifies the reason for EPS fallback.
+     * @param response is callback message.
+     */
+    public void triggerEpsFallback(@MmTelFeature.EpsFallbackReason int reason, Message response) {
+        mCi.triggerEpsFallback(reason, response);
+    }
+
+    /**
+     * Notifies the recommended bit rate for the indicated logical channel and direction.
+     *
+     * @param mediaType MediaType is used to identify media stream such as audio or video.
+     * @param direction Direction of this packet stream (e.g. uplink or downlink).
+     * @param bitsPerSecond The recommended bit rate for the UE for a specific logical channel and
+     *        a specific direction by NW.
+     */
+    public void triggerNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+    }
+
+    /**
+     * Sets the emergency mode
+     *
+     * @param emcMode The radio emergency mode type.
+     * @param result Callback message.
+     */
+    public void setEmergencyMode(@EmergencyConstants.EmergencyMode int emcMode,
+            @Nullable Message result) {
+        mCi.setEmergencyMode(emcMode, result);
+    }
+
+    /**
+     * Triggers an emergency network scan.
+     *
+     * @param accessNetwork Contains the list of access network types to be prioritized
+     *        during emergency scan. The 1st entry has the highest priority.
+     * @param scanType Indicates the type of scans to be performed i.e. limited scan,
+     *        full service scan or any scan.
+     * @param result Callback message.
+     */
+    public void triggerEmergencyNetworkScan(
+            @NonNull @AccessNetworkConstants.RadioAccessNetworkType int[] accessNetwork,
+            @DomainSelectionService.EmergencyScanType int scanType, @Nullable Message result) {
+        mCi.triggerEmergencyNetworkScan(accessNetwork, scanType, result);
+    }
+
+    /**
+     * Cancels ongoing emergency network scan
+     * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
+     *        If {@code true}, then the modem shall start the new scan from the beginning,
+     *        otherwise the modem shall resume from the last search.
+     * @param result Callback message.
+     */
+    public void cancelEmergencyNetworkScan(boolean resetScan, @Nullable Message result) {
+        mCi.cancelEmergencyNetworkScan(resetScan, result);
+    }
+
+    /**
+     * Exits ongoing emergency mode
+     * @param result Callback message.
+     */
+    public void exitEmergencyMode(@Nullable Message result) {
+        mCi.exitEmergencyMode(result);
+    }
+
+    /**
+     * Registers for emergency network scan result.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForEmergencyNetworkScan(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        mCi.registerForEmergencyNetworkScan(h, what, obj);
+    }
+
+    /**
+     * Unregisters for emergency network scan result.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForEmergencyNetworkScan(@NonNull Handler h) {
+        mCi.unregisterForEmergencyNetworkScan(h);
+    }
+
+    /**
+     * Notifies that IMS deregistration is triggered.
+     *
+     * @param reason the reason why the deregistration is triggered.
+     */
+    public void triggerImsDeregistration(
+            @ImsRegistrationImplBase.ImsDeregistrationReason int reason) {
+        if (mImsPhone != null) {
+            mImsPhone.triggerImsDeregistration(reason);
+        }
+    }
+
+    /**
+     * Registers for the domain selected for emergency calls.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForEmergencyDomainSelected(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+    }
+
+    /**
+     * Unregisters for the domain selected for emergency calls.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForEmergencyDomainSelected(@NonNull Handler h) {
+    }
+
+    /**
+     * Notifies the domain selected.
+     *
+     * @param transportType The preferred transport type.
+     */
+    public void notifyEmergencyDomainSelected(
+            @AccessNetworkConstants.TransportType int transportType) {
+    }
+
+    /**
+     * @return Telephony tester instance.
+     */
+    public @Nullable TelephonyTester getTelephonyTester() {
+        return mTelephonyTester;
+    }
+
+    /**
+     * @return User handle associated with the phone's subscription id. {@code null} if subscription
+     * is invalid or not found.
+     */
+    @Nullable
+    public UserHandle getUserHandle() {
+        int subId = getSubId();
+
+        UserHandle userHandle = null;
+        try {
+            SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+            if (subManager != null) {
+                userHandle = subManager.getSubscriptionUserHandle(subId);
+            }
+        } catch (IllegalArgumentException ex) {
+            loge("getUserHandle: ex=" + ex);
+        }
+
+        return userHandle;
+    }
+
+    /**
+     * Checks if the context user is a managed profile.
+     *
+     * Note that this applies specifically to <em>managed</em> profiles.
+     *
+     * @return whether the context user is a managed profile.
+     */
+    public boolean isManagedProfile() {
+        UserHandle userHandle = getUserHandle();
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userHandle == null || userManager == null) return false;
+        return userManager.isManagedProfile(userHandle.getIdentifier());
+    }
+
+    /**
+     * @return global null cipher and integrity enabled preference
+     */
+    public boolean getNullCipherAndIntegrityEnabledPreference() {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+        return sp.getBoolean(PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, true);
+    }
+
+    /**
+     * @return whether or not this Phone interacts with a modem that supports the null cipher
+     * and integrity feature.
+     */
+    public boolean isNullCipherAndIntegritySupported() {
+        return false;
+    }
+
+    /**
+     * Override to implement handling of an update to the enablement of the null cipher and
+     * integrity preference.
+     * {@see #PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED}
+     */
+    public void handleNullCipherEnabledChange() {
+    }
+
+    /**
+     * Notifies the IMS call status to the modem.
+     *
+     * @param imsCallInfo The list of {@link ImsCallInfo}.
+     * @param response A callback to receive the response.
+     */
+    public void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message response) {
+        mCi.updateImsCallStatus(imsCallInfo, response);
+    }
+
+    /**
+     * Enables or disables N1 mode (access to 5G core network) in accordance with
+     * 3GPP TS 24.501 4.9.
+     * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode.
+     * @param result Callback message to receive the result.
+     */
+    public void setN1ModeEnabled(boolean enable, Message result) {
+        mCi.setN1ModeEnabled(enable, result);
+    }
+
+    /**
+     * Check whether N1 mode (access to 5G core network) is enabled or not.
+     * @param result Callback message to receive the result.
+     */
+    public void isN1ModeEnabled(Message result) {
+        mCi.isN1ModeEnabled(result);
+    }
+
+    /**
+     * Return current cell broadcast ranges.
+     */
+    public List<CellBroadcastIdRange> getCellBroadcastIdRanges() {
+        return new ArrayList<>();
+    }
+
+    /**
+     * Set reception of cell broadcast messages with the list of the given ranges.
+     */
+    public void setCellBroadcastIdRanges(
+            @NonNull List<CellBroadcastIdRange> ranges, Consumer<Integer> callback) {
+        callback.accept(TelephonyManager.CELL_BROADCAST_RESULT_UNSUPPORTED);
+    }
+
+    /**
+     * Start receiving satellite position updates.
+     * This can be called by the pointing UI when the user starts pointing to the satellite.
+     * Modem should continue to report the pointing input as the device or satellite moves.
+     *
+     * @param result The Message to send to result of the operation to.
+     **/
+    public void startSatellitePositionUpdates(Message result) {
+        mCi.startSendingSatellitePointingInfo(result);
+    }
+
+    /**
+     * Stop receiving satellite position updates.
+     * This can be called by the pointing UI when the user stops pointing to the satellite.
+     *
+     * @param result The Message to send to result of the operation to.
+     **/
+    public void stopSatellitePositionUpdates(Message result) {
+        mCi.stopSendingSatellitePointingInfo(result);
+    }
+
+    /**
+     * Get maximum number of characters per text message on satellite.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void getMaxCharactersPerSatelliteTextMessage(Message result) {
+        mCi.getMaxCharactersPerSatelliteTextMessage(result);
+    }
+
+    /**
+     * Power on or off the satellite modem.
+     * @param result The Message to send the result of the operation to.
+     * @param powerOn {@code true} to power on the satellite modem and {@code false} to power off.
+     */
+    public void setSatellitePower(Message result, boolean powerOn) {
+        mCi.setSatellitePower(result, powerOn);
+    }
+
+    /**
+     * Check whether the satellite modem is powered on.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void isSatellitePowerOn(Message result) {
+        mCi.getSatellitePowerState(result);
+    }
+
+    /**
+     * Check whether the satellite service is supported on the device.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void isSatelliteSupported(Message result) {
+        mCi.isSatelliteSupported(result);
+    }
+
+    /**
+     * Check whether the satellite modem is provisioned.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void isSatelliteProvisioned(Message result) {
+        mCi.getSatelliteProvisionState(result);
+    }
+
+    /**
+     * Get the satellite capabilities.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void getSatelliteCapabilities(Message result) {
+        mCi.getSatelliteCapabilities(result);
+    }
+
+    /**
+     * Registers for pointing info changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatellitePositionInfoChanged(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        //TODO: Rename CommandsInterface and other modules when updating HAL APIs.
+        mCi.registerForSatellitePointingInfoChanged(h, what, obj);
+    }
+
+    /**
+     * Unregisters for pointing info changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatellitePositionInfoChanged(@NonNull Handler h) {
+        //TODO: Rename CommandsInterface and other modules when updating HAL APIs.
+        mCi.unregisterForSatellitePointingInfoChanged(h);
+    }
+
+    /**
+     * Registers for datagrams delivered events from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteDatagramsDelivered(@NonNull Handler h,
+            int what, @Nullable Object obj) {
+        //TODO: Remove.
+        mCi.registerForSatelliteMessagesTransferComplete(h, what, obj);
+    }
+
+    /**
+     * Unregisters for datagrams delivered events from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteDatagramsDelivered(@NonNull Handler h) {
+        //TODO: Remove.
+        mCi.unregisterForSatelliteMessagesTransferComplete(h);
+    }
+
+    /**
+     * Provision the subscription with a satellite provider.
+     * This is needed to register the device/subscription if the provider allows dynamic
+     * registration.
+     *
+     * @param result Callback message to receive the result.
+     * @param token The token of the device/subscription to be provisioned.
+     */
+    public void provisionSatelliteService(Message result, String token) {
+        // TODO: update parameters in HAL
+        // mCi.provisionSatelliteService(result, token);
+    }
+
+    /**
+     * Deprovision the device/subscription with a satellite provider.
+     * This is needed to unregister the device/subscription if the provider allows dynamic
+     * registration.
+     * If provisioning is in progress for the given SIM, cancel the request.
+     * If there is no request in progress, deprovision the given SIM.
+     *
+     * @param result Callback message to receive the result.
+     * @param token The token of the device/subscription to be deprovisioned.
+     */
+    public void deprovisionSatelliteService(Message result, String token) {
+        //TODO (b/266126070): add implementation.
+    }
+
+    /**
+     * Register for a satellite provision state changed event.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteProvisionStateChanged(Handler h, int what, Object obj) {
+        mCi.registerForSatelliteProvisionStateChanged(h, what, obj);
+    }
+
+    /**
+     * Unregister for a satellite provision state changed event.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteProvisionStateChanged(Handler h) {
+        mCi.unregisterForSatelliteProvisionStateChanged(h);
+    }
+
+    /**
+     * Get the list of provisioned satellite features.
+     *
+     * @param result Callback message to receive the result.
+     */
+    public void getProvisionedSatelliteFeatures(Message result) {
+        //TODO (b/266126070): add implementation.
+    }
+
+    /**
+     * Registers for satellite state changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteModemStateChanged(@NonNull Handler h, int what,
+            @Nullable Object obj) {
+        mCi.registerForSatelliteModeChanged(h, what, obj);
+    }
+
+    /**
+     * Unregisters for satellite state changed from satellite modem.
+     *
+     * @param h Handler to be removed from registrant list.
+     */
+    public void unregisterForSatelliteModemStateChanged(@NonNull Handler h) {
+        mCi.unregisterForSatelliteModeChanged(h);
+    }
+
+    /**
+     * Registers for pending datagram count info from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForPendingDatagramCount(@NonNull Handler h, int what,
+            @Nullable Object obj) {
+        mCi.registerForPendingSatelliteMessageCount(h, what, obj);
+    }
+
+    /**
+     * Unregisters for pending datagram count info from satellite modem.
+     *
+     * @param h Handler to be removed from registrant list.
+     */
+    public void unregisterForPendingDatagramCount(@NonNull Handler h) {
+        mCi.unregisterForPendingSatelliteMessageCount(h);
+    }
+
+    /**
+     * Register to receive incoming datagrams over satellite.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteDatagramsReceived(@NonNull Handler h, int what,
+            @Nullable Object obj) {
+        // TODO: rename
+        mCi.registerForNewSatelliteMessages(h, what, obj);
+    }
+
+    /**
+     * Unregister to stop receiving incoming datagrams over satellite.
+     *
+     * @param h Handler to be removed from registrant list.
+     */
+    public void unregisterForSatelliteDatagramsReceived(@NonNull Handler h) {
+        // TODO: rename
+        mCi.unregisterForNewSatelliteMessages(h);
+    }
+
+    /**
+     * Poll pending datagrams over satellite.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void pollPendingSatelliteDatagrams(Message result) {
+        //mCi.pollPendingSatelliteDatagrams(result);
+    }
+
+    /**
+     * Send datagram over satellite.
+     * @param result The Message to send the result of the operation to.
+     * @param datagram Datagram to send over satellite.
+     * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+     *                                 full screen mode.
+     */
+    public void sendSatelliteDatagram(Message result, SatelliteDatagram datagram,
+            boolean needFullScreenPointingUI) {
+        //mCi.sendSatelliteDatagram(result, datagram);
+    }
+
+    /**
+     * Check whether satellite communication is allowed for the current location.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void isSatelliteCommunicationAllowedForCurrentLocation(Message result) {
+        mCi.isSatelliteCommunicationAllowedForCurrentLocation(result);
+    }
+
+    /**
+     * Get the time after which the satellite will be visible.
+     * @param result The Message to send the result of the operation to.
+     */
+    public void requestTimeForNextSatelliteVisibility(Message result) {
+        mCi.getTimeForNextSatelliteVisibility(result);
+    }
+
+    /**
+     * Start callback mode
+     * @param type for callback mode entry.
+     */
+    public void startCallbackMode(@TelephonyManager.EmergencyCallbackModeType int type) {
+        Rlog.d(LOG_TAG, "startCallbackMode:type=" + type);
+        mNotifier.notifyCallbackModeStarted(this, type);
+    }
+
+    /**
+     * Stop callback mode
+     * @param type for callback mode exit.
+     * @param reason for stopping callback mode.
+     */
+    public void stopCallbackMode(@TelephonyManager.EmergencyCallbackModeType int type,
+            @TelephonyManager.EmergencyCallbackModeStopReason int reason) {
+        Rlog.d(LOG_TAG, "stopCallbackMode:type=" + type + ", reason=" + reason);
+        mNotifier.notifyCallbackModeStopped(this, type, reason);
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -4918,7 +5530,7 @@
         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
         pw.println(" getUnitTestMode()=" + getUnitTestMode());
         pw.println(" getState()=" + getState());
-        pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
+        pw.println(" getIccSerialNumber()=" + Rlog.pii(LOG_TAG, getIccSerialNumber()));
         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 081e7a0..8b95824 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -72,6 +72,7 @@
     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 String BOOT_ALLOW_MOCK_MODEM_PROPERTY = "ro.boot.radio.allow_mock_modem";
     private static final boolean DEBUG = !"user".equals(Build.TYPE);
     /**
      * Init method to instantiate the object
@@ -123,6 +124,21 @@
         }
     }
 
+    // If virtual DSDA is enabled for this UE, then updates maxActiveVoiceSubscriptions to 2.
+    private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions(
+            final PhoneCapability staticCapability) {
+        boolean enableVirtualDsda = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_enable_virtual_dsda);
+
+        if (staticCapability.getLogicalModemList().size() > 1 && enableVirtualDsda) {
+            return new PhoneCapability.Builder(staticCapability)
+                    .setMaxActiveVoiceSubscriptions(2)
+                    .build();
+        } else {
+            return staticCapability;
+        }
+    }
+
     /**
      * Static method to get instance.
      */
@@ -181,6 +197,8 @@
                     ar = (AsyncResult) msg.obj;
                     if (ar != null && ar.exception == null) {
                         mStaticCapability = (PhoneCapability) ar.result;
+                        mStaticCapability =
+                                maybeUpdateMaxActiveVoiceSubscriptions(mStaticCapability);
                         notifyCapabilityChanged();
                     } else {
                         log(msg.what + " failure. Not getting phone capability." + ar.exception);
@@ -367,11 +385,7 @@
             // eg if we are going from 2 phones to 1 phone, we need to deregister RIL for the
             // second phone. This loop does nothing if numOfActiveModems is increasing.
             for (int phoneId = numOfActiveModems; phoneId < oldNumOfActiveModems; phoneId++) {
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionManagerService.getInstance().markSubscriptionsInactive(phoneId);
-                } else {
-                    SubscriptionController.getInstance().clearSubInfoRecord(phoneId);
-                }
+                SubscriptionManagerService.getInstance().markSubscriptionsInactive(phoneId);
                 subInfoCleared = true;
                 mPhones[phoneId].mCi.onSlotActiveStatusChange(
                         SubscriptionManager.isValidPhoneId(phoneId));
@@ -405,13 +419,8 @@
                         + "setting VOICE & SMS subId to -1 (No Preference)");
 
                 //Set the default VOICE subId to -1 ("No Preference")
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionManagerService.getInstance().setDefaultVoiceSubId(
-                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                } else {
-                    SubscriptionController.getInstance().setDefaultVoiceSubId(
-                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                }
+                SubscriptionManagerService.getInstance().setDefaultVoiceSubId(
+                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
                 //TODO:: Set the default SMS sub to "No Preference". Tracking this bug (b/227386042)
             } else {
@@ -475,34 +484,46 @@
      * @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);
+        final boolean isAllowedForBoot =
+                SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false);
 
-        // Check for ALLOW_MOCK_MODEM_PROPERTY on user builds
-        if (isAllowed || DEBUG) {
-            if (serviceName != null) {
+        // Check for ALLOW_MOCK_MODEM_PROPERTY and BOOT_ALLOW_MOCK_MODEM_PROPERTY on user builds
+        if (isAllowed || isAllowedForBoot || DEBUG) {
+            if (mRadioConfig != 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;
+            if (!statusRadioConfig) {
+                loge("setModemService: switching modem service for radioconfig fail");
+                return false;
+            }
+
+            for (int i = 0; i < getPhoneCount(); i++) {
+                if (mPhones[i] != null) {
+                    statusRil = mPhones[i].mCi.setModemService(serviceName);
+                }
+
+                if (!statusRil) {
+                    loge("setModemService: switch modem for radio " + i + " fail");
+
+                    // Disconnect the switched service
+                    mRadioConfig.setModemService(null);
+                    for (int t = 0; t < i; t++) {
+                        mPhones[t].mCi.setModemService(null);
+                    }
+                    return false;
+                }
+            }
         } else {
             loge("setModemService is not allowed");
             return false;
         }
+
+        return true;
     }
 
      /**
@@ -510,7 +531,6 @@
      * @return the service name of the connected service.
      */
     public String getModemService() {
-        //TODO: consider multi-sim case
         if (mPhones[0] == null) {
             return "";
         }
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 8220ee3..57a375b 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
+
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA_LTE;
 
@@ -29,10 +31,8 @@
 import android.content.pm.PackageManager;
 import android.net.LocalServerSocket;
 import android.os.Build;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.preference.PreferenceManager;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.telephony.AnomalyReporter;
@@ -87,8 +87,6 @@
     private static @Nullable EuiccCardController sEuiccCardController;
     private static SubscriptionManagerService sSubscriptionManagerService;
 
-    static private SubscriptionInfoUpdater sSubInfoRecordUpdater = null;
-
     @UnsupportedAppUsage
     static private boolean sMadeDefaults = false;
     @UnsupportedAppUsage
@@ -105,8 +103,6 @@
     private static MetricsCollector sMetricsCollector;
     private static RadioInterfaceCapabilityController sRadioHalCapabilities;
 
-    private static boolean sSubscriptionManagerServiceEnabled = false;
-
     //***** Class Methods
 
     public static void makeDefaultPhones(Context context) {
@@ -123,12 +119,6 @@
             if (!sMadeDefaults) {
                 sContext = context;
 
-                // This is a temp flag which will be removed before U AOSP public release.
-                sSubscriptionManagerServiceEnabled = context.getResources().getBoolean(
-                        com.android.internal.R.bool.config_using_subscription_manager_service)
-                        || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY,
-                        "enable_subscription_manager_service", false);
-
                 // create the telephony device controller.
                 TelephonyDevController.create();
 
@@ -191,7 +181,7 @@
 
                 if (numPhones > 0) {
                     final RadioConfig radioConfig = RadioConfig.make(context,
-                            sCommandsInterfaces[0].getHalVersion());
+                            sCommandsInterfaces[0].getHalVersion(HAL_SERVICE_RADIO));
                     sRadioHalCapabilities = RadioInterfaceCapabilityController.init(radioConfig,
                             sCommandsInterfaces[0]);
                 } else {
@@ -206,24 +196,12 @@
                 // call getInstance()
                 sUiccController = UiccController.make(context);
 
-
-                if (isSubscriptionManagerServiceEnabled()) {
-                    Rlog.i(LOG_TAG, "Creating SubscriptionManagerService");
-                    sSubscriptionManagerService = new SubscriptionManagerService(context,
-                            Looper.myLooper());
-                } else {
-                    Rlog.i(LOG_TAG, "Creating SubscriptionController");
-                    TelephonyComponentFactory.getInstance().inject(SubscriptionController.class
-                            .getName()).initSubscriptionController(context);
-                }
-
-                SubscriptionController sc = null;
-                if (!isSubscriptionManagerServiceEnabled()) {
-                    sc = SubscriptionController.getInstance();
-                }
+                Rlog.i(LOG_TAG, "Creating SubscriptionManagerService");
+                sSubscriptionManagerService = new SubscriptionManagerService(context,
+                        Looper.myLooper());
 
                 TelephonyComponentFactory.getInstance().inject(MultiSimSettingController.class.
-                        getName()).initMultiSimSettingController(context, sc);
+                        getName()).initMultiSimSettingController(context);
 
                 if (context.getPackageManager().hasSystemFeature(
                         PackageManager.FEATURE_TELEPHONY_EUICC)) {
@@ -255,16 +233,6 @@
 
                 sMadeDefaults = true;
 
-                if (!isSubscriptionManagerServiceEnabled()) {
-                    Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
-                    HandlerThread pfhandlerThread = new HandlerThread("PhoneFactoryHandlerThread");
-                    pfhandlerThread.start();
-                    sSubInfoRecordUpdater = TelephonyComponentFactory.getInstance().inject(
-                            SubscriptionInfoUpdater.class.getName())
-                            .makeSubscriptionInfoUpdater(pfhandlerThread.getLooper(), context,
-                                    SubscriptionController.getInstance());
-                }
-
                 // Only bring up IMS if the device supports having an IMS stack.
                 if (context.getPackageManager().hasSystemFeature(
                         PackageManager.FEATURE_TELEPHONY_IMS)) {
@@ -304,14 +272,6 @@
     }
 
     /**
-     * @return {@code true} if the new {@link SubscriptionManagerService} is enabled, otherwise the
-     * old {@link SubscriptionController} is used.
-     */
-    public static boolean isSubscriptionManagerServiceEnabled() {
-        return sSubscriptionManagerServiceEnabled;
-    }
-
-    /**
      * Upon single SIM to dual SIM switch or vice versa, we dynamically allocate or de-allocate
      * Phone and CommandInterface objects.
      * @param context
@@ -410,10 +370,6 @@
         }
     }
 
-    public static SubscriptionInfoUpdater getSubscriptionInfoUpdater() {
-        return sSubInfoRecordUpdater;
-    }
-
     /**
      * Get the network factory associated with a given phone ID.
      * @param phoneId the phone id
@@ -450,7 +406,6 @@
      * @param phoneId The phone's id.
      * @return the preferred network mode bitmask that should be set.
      */
-    // TODO: Fix when we "properly" have TelephonyDevController/SubscriptionController ..
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static int calculatePreferredNetworkType(int phoneId) {
         if (getPhone(phoneId) == null) {
@@ -467,10 +422,7 @@
     /* Gets the default subscription */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static int getDefaultSubscription() {
-        if (isSubscriptionManagerServiceEnabled()) {
-            return SubscriptionManagerService.getInstance().getDefaultSubId();
-        }
-        return SubscriptionController.getInstance().getDefaultSubId();
+        return SubscriptionManagerService.getInstance().getDefaultSubId();
     }
 
     /* Returns User SMS Prompt property,  enabled or not */
@@ -498,19 +450,7 @@
     }
 
     /**
-     * Request a refresh of the embedded subscription list.
-     *
-     * @param cardId the card ID of the eUICC.
-     * @param callback Optional callback to execute after the refresh completes. Must terminate
-     *     quickly as it will be called from SubscriptionInfoUpdater's handler thread.
-     */
-    public static void requestEmbeddedSubscriptionInfoListRefresh(
-            int cardId, @Nullable Runnable callback) {
-        sSubInfoRecordUpdater.requestEmbeddedSubscriptionInfoListRefresh(cardId, callback);
-    }
-
-    /**
-     * Get a the SmsController.
+     * Get the instance of {@link SmsController}.
      */
     public static SmsController getSmsController() {
         synchronized (sLockProxyPhones) {
@@ -613,25 +553,16 @@
         pw.decreaseIndent();
         pw.println("++++++++++++++++++++++++++++++++");
 
-        if (!isSubscriptionManagerServiceEnabled()) {
-            pw.println("SubscriptionController:");
-            pw.increaseIndent();
-            try {
-                SubscriptionController.getInstance().dump(fd, pw, args);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            pw.flush();
-            pw.decreaseIndent();
-            pw.println("++++++++++++++++++++++++++++++++");
+        pw.flush();
+        pw.decreaseIndent();
+        pw.println("++++++++++++++++++++++++++++++++");
 
-            pw.println("SubInfoRecordUpdater:");
-            pw.increaseIndent();
-            try {
-                sSubInfoRecordUpdater.dump(fd, pw, args);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
+        pw.println("sRadioHalCapabilities:");
+        pw.increaseIndent();
+        try {
+            sRadioHalCapabilities.dump(fd, pw, args);
+        } catch (Exception e) {
+            e.printStackTrace();
         }
         pw.flush();
         pw.decreaseIndent();
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index 5b4d5e5..32c0c73 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -36,9 +35,9 @@
 
 import com.android.internal.telephony.PhoneConstants.DataState;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.function.Consumer;
 
 /**
@@ -211,16 +210,6 @@
     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;
-    int RADIO_POWER_REASON_THERMAL = 1;
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"RADIO_POWER_REASON_"},
-        value = {
-            RADIO_POWER_REASON_USER,
-            RADIO_POWER_REASON_THERMAL})
-    public @interface RadioPowerReason {}
-
     // Used for band mode selection methods
     static final int BM_UNSPECIFIED = RILConstants.BAND_MODE_UNSPECIFIED; // automatic
     static final int BM_EURO_BAND   = RILConstants.BAND_MODE_EURO;
@@ -593,8 +582,9 @@
      * getServiceState().getState() will not change immediately after this call.
      * registerForServiceStateChanged() to find out when the
      * request is complete. This will set the reason for radio power state as {@link
-     * #RADIO_POWER_REASON_USER}. This will not guarantee that the requested radio power state will
-     * actually be set. See {@link #setRadioPowerForReason(boolean, boolean, boolean, boolean, int)}
+     * android.telephony.TelephonyManager#RADIO_POWER_REASON_USER}. This will not guarantee that the
+     * requested radio power state will actually be set.
+     * See {@link #setRadioPowerForReason(boolean, boolean, boolean, boolean, int)}
      * for details.
      *
      * @param power true means "on", false means "off".
@@ -620,8 +610,9 @@
      * getServiceState().getState() will not change immediately after this call.
      * registerForServiceStateChanged() to find out when the
      * request is complete. This will set the reason for radio power state as {@link
-     * #RADIO_POWER_REASON_USER}. This will not guarantee that the requested radio power state will
-     * actually be set. See {@link #setRadioPowerForReason(boolean, boolean, boolean, boolean, int)}
+     * android.telephony.TelephonyManager#RADIO_POWER_REASON_USER}. This will not guarantee that the
+     * requested radio power state will actually be set.
+     * See {@link #setRadioPowerForReason(boolean, boolean, boolean, boolean, int)}
      * for details.
      *
      * @param power true means "on", false means "off".
@@ -638,7 +629,7 @@
     default void setRadioPower(boolean power, boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply) {
         setRadioPowerForReason(power, forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply,
-                RADIO_POWER_REASON_USER);
+                TelephonyManager.RADIO_POWER_REASON_USER);
     }
 
     /**
@@ -656,11 +647,19 @@
      * @param power true means "on", false means "off".
      * @param reason RadioPowerReason constant defining the reason why the radio power was set.
      */
-    default void setRadioPowerForReason(boolean power, @RadioPowerReason int reason) {
+    default void setRadioPowerForReason(boolean power,
+            @TelephonyManager.RadioPowerReason int reason) {
         setRadioPowerForReason(power, false, false, false, reason);
     }
 
     /**
+     * @return reasons for powering off radio.
+     */
+    default Set<Integer> getRadioPowerOffReasons() {
+        return new HashSet<>();
+    }
+
+    /**
      * Sets the radio power on/off state with option to specify whether it's for emergency call
      * (off is sometimes called "airplane mode") and option to set the reason for setting the power
      * state. Current state can be gotten via {@link #getServiceState()}.
@@ -686,7 +685,7 @@
      */
     default void setRadioPowerForReason(boolean power, boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply,
-            @RadioPowerReason int reason) {}
+            @TelephonyManager.RadioPowerReason int reason) {}
 
     /**
      * Get the line 1 phone number (MSISDN). For CDMA phones, the MDN is returned
@@ -1036,6 +1035,10 @@
     String getImei();
 
     /**
+     * Retrieves IMEI type for phones.
+     */
+    int getImeiType();
+    /**
      * Retrieves the IccPhoneBookInterfaceManager of the Phone
      */
     public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager();
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 701a157..20d6702 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.telephony.Annotation;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.BarringInfo;
@@ -31,8 +32,11 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager.DataEnabledReason;
+import android.telephony.TelephonyManager.EmergencyCallbackModeStopReason;
+import android.telephony.TelephonyManager.EmergencyCallbackModeType;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.MediaQualityStatus;
 
 import java.util.List;
 
@@ -78,7 +82,10 @@
 
     void notifyCellInfo(Phone sender, List<CellInfo> cellInfo);
 
-    void notifyPreciseCallState(Phone sender);
+    /** Send a notification that precise call state changed. */
+    void notifyPreciseCallState(Phone sender, String[] imsCallIds,
+            @Annotation.ImsCallServiceType int[] imsCallServiceTypes,
+            @Annotation.ImsCallType int[] imsCallTypes);
 
     void notifyDisconnectCause(Phone sender, int cause, int preciseCause);
 
@@ -113,6 +120,9 @@
     /** Notify of a change to the call quality of an active foreground call. */
     void notifyCallQualityChanged(Phone sender, CallQuality callQuality, int callNetworkType);
 
+    /** Notify of a change to the media quality status of an active foreground call. */
+    void notifyMediaQualityStatusChanged(Phone sender, MediaQualityStatus status);
+
     /** Notify registration failed */
     void notifyRegistrationFailed(Phone sender, @NonNull CellIdentity cellIdentity,
             @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
@@ -132,4 +142,11 @@
     /** Notify link capacity estimate has changed. */
     void notifyLinkCapacityEstimateChanged(Phone sender,
             List<LinkCapacityEstimate> linkCapacityEstimateList);
+
+    /** Notify callback mode started. */
+    void notifyCallbackModeStarted(Phone sender, @EmergencyCallbackModeType int type);
+
+    /** Notify callback mode stopped. */
+    void notifyCallbackModeStopped(Phone sender, @EmergencyCallbackModeType int type,
+            @EmergencyCallbackModeStopReason int reason);
 }
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index 8048eba..d30a73c 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -27,6 +27,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.RemoteException;
@@ -41,10 +42,14 @@
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.IsimRecords;
+import com.android.internal.telephony.uicc.SIMRecords;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.telephony.Rlog;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
     private static final String TAG = "PhoneSubInfoController";
     private static final boolean DBG = true;
@@ -154,13 +159,8 @@
         long identity = Binder.clearCallingIdentity();
         boolean isActive;
         try {
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                isActive = SubscriptionManagerService.getInstance().isActiveSubId(subId,
-                        callingPackage, callingFeatureId);
-            } else {
-                isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage,
-                        callingFeatureId);
-            }
+            isActive = SubscriptionManagerService.getInstance().isActiveSubId(subId,
+                    callingPackage, callingFeatureId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -174,15 +174,12 @@
             }
             identity = Binder.clearCallingIdentity();
             try {
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                            .getSubscriptionInfoInternal(subId);
-                    if (subInfo != null && !TextUtils.isEmpty(subInfo.getImsi())) {
-                        return subInfo.getImsi();
-                    }
-                    return null;
+                SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                        .getSubscriptionInfoInternal(subId);
+                if (subInfo != null && !TextUtils.isEmpty(subInfo.getImsi())) {
+                    return subInfo.getImsi();
                 }
-                return SubscriptionController.getInstance().getImsiPrivileged(subId);
+                return null;
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -351,6 +348,34 @@
     }
 
     /**
+     * Fetches the IMS private user identity (EF_IMPI) based on subscriptionId.
+     *
+     * @param subId subscriptionId
+     * @return IMPI (IMS private user identity) of type string.
+     * @throws IllegalArgumentException if the subscriptionId is not valid
+     * @throws IllegalStateException in case the ISIM hasn’t been loaded.
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    public String getImsPrivateUserIdentity(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid SubscriptionID  = " + subId);
+        }
+        if (!TelephonyPermissions.checkCallingOrSelfUseIccAuthWithDeviceIdentifier(mContext,
+                callingPackage, callingFeatureId, "getImsPrivateUserIdentity")) {
+            throw (new SecurityException("No permissions to the caller"));
+        }
+        Phone phone = getPhone(subId);
+        assert phone != null;
+        IsimRecords isim = phone.getIsimRecords();
+        if (isim != null) {
+            return isim.getIsimImpi();
+        } else {
+            throw new IllegalStateException("ISIM is not loaded");
+        }
+    }
+
+    /**
     * get the Isim Domain based on subId
     */
     public String getIsimDomain(int subId) {
@@ -381,6 +406,42 @@
     }
 
     /**
+     * Fetches the ISIM public user identities (EF_IMPU) from UICC based on subId
+     *
+     * @param subId subscriptionId
+     * @param callingPackage package name of the caller
+     * @param callingFeatureId feature Id of the caller
+     * @return List of public user identities of type android.net.Uri or empty list  if
+     * EF_IMPU is not available.
+     * @throws IllegalArgumentException if the subscriptionId is not valid
+     * @throws IllegalStateException in case the ISIM hasn’t been loaded.
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    public List<Uri> getImsPublicUserIdentities(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (TelephonyPermissions.
+                checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber(
+                mContext, subId, callingPackage, callingFeatureId, "getImsPublicUserIdentities")) {
+            Phone phone = getPhone(subId);
+            assert phone != null;
+            IsimRecords isimRecords = phone.getIsimRecords();
+            if (isimRecords != null) {
+                String[] impus = isimRecords.getIsimImpu();
+                List<Uri> impuList = new ArrayList<>();
+                for (String impu : impus) {
+                    if (impu != null && impu.trim().length() > 0) {
+                        impuList.add(Uri.parse(impu));
+                    }
+                }
+                return impuList;
+            }
+            throw new IllegalStateException("ISIM is not loaded");
+        } else {
+            throw new IllegalArgumentException("Invalid SubscriptionID  = " + subId);
+        }
+    }
+
+    /**
     * get the Isim Ist based on subId
     */
     public String getIsimIst(int subId) throws RemoteException {
@@ -410,6 +471,29 @@
                 });
     }
 
+    /**
+     * Returns the USIM service table that fetched from EFUST elementary field that are loaded
+     * based on the appType.
+     */
+    public String getSimServiceTable(int subId, int appType) throws RemoteException {
+        return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSimServiceTable",
+                (phone) -> {
+                    UiccPort uiccPort = phone.getUiccPort();
+                    if (uiccPort == null || uiccPort.getUiccProfile() == null) {
+                        loge("getSimServiceTable(): uiccPort or uiccProfile is null");
+                        return null;
+                    }
+                    UiccCardApplication uiccApp = uiccPort.getUiccProfile().getApplicationByType(
+                            appType);
+                    if (uiccApp == null) {
+                        loge("getSimServiceTable(): no app with specified apptype="
+                                + appType);
+                        return null;
+                    }
+                    return ((SIMRecords)uiccApp.getIccRecords()).getSimServiceTable();
+                });
+    }
+
     @Override
     public String getIccSimChallengeResponse(int subId, int appType, int authType, String data,
             String callingPackage, String callingFeatureId) throws RemoteException {
@@ -430,7 +514,9 @@
             }
 
             if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM
-                    && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) {
+                    && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA
+                    && authType != UiccCardApplication.AUTH_CONTEXT_GBA_BOOTSTRAP
+                    && authType != UiccCardApplication.AUTHTYPE_GBA_NAF_KEY_EXTERNAL) {
                 loge("getIccSimChallengeResponse() unsupported authType: " + authType);
                 return null;
             }
@@ -483,7 +569,7 @@
             if (phone != null) {
                 return callMethodHelper.callMethod(phone);
             } else {
-                loge(message + " phone is null for Subscription:" + subId);
+                if (VDBG) loge(message + " phone is null for Subscription:" + subId);
                 return null;
             }
         } finally {
@@ -573,6 +659,37 @@
         }
     }
 
+    /**
+     * Returns SIP URI or tel URI of the Public Service Identity of the SM-SC fetched from
+     * EF_PSISMSC elementary field as defined in Section 4.5.9 (3GPP TS 31.102).
+     * @throws IllegalStateException in case if phone or UiccApplication is not available.
+     */
+    public Uri getSmscIdentity(int subId, int appType) throws RemoteException {
+        Uri smscIdentityUri = callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSmscIdentity",
+                (phone) -> {
+                    try {
+                        String smscIdentity = null;
+                        UiccPort uiccPort = phone.getUiccPort();
+                        UiccCardApplication uiccApp =
+                                uiccPort.getUiccProfile().getApplicationByType(
+                                        appType);
+                        smscIdentity = (uiccApp != null) ? uiccApp.getIccRecords().getSmscIdentity()
+                                : null;
+                        if (TextUtils.isEmpty(smscIdentity)) {
+                            return Uri.EMPTY;
+                        }
+                        return Uri.parse(smscIdentity);
+                    } catch (NullPointerException ex) {
+                        Rlog.e(TAG, "getSmscIdentity(): Exception = " + ex);
+                        return null;
+                    }
+                });
+        if (smscIdentityUri == null) {
+            throw new IllegalStateException("Telephony service error");
+        }
+        return smscIdentityUri;
+    }
+
     private void log(String s) {
         Rlog.d(TAG, s);
     }
diff --git a/src/java/com/android/internal/telephony/ProxyController.java b/src/java/com/android/internal/telephony/ProxyController.java
index 498953c..ed9982e 100644
--- a/src/java/com/android/internal/telephony/ProxyController.java
+++ b/src/java/com/android/internal/telephony/ProxyController.java
@@ -47,8 +47,10 @@
     @VisibleForTesting
     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;
+    @VisibleForTesting
+    public static final int EVENT_FINISH_RC_RESPONSE        = 4;
+    @VisibleForTesting
+    public static final int EVENT_TIMEOUT                   = 5;
     @VisibleForTesting
     public static final int EVENT_MULTI_SIM_CONFIG_CHANGED  = 6;
 
@@ -212,6 +214,7 @@
         clearTransaction();
 
         // Keep a wake lock until we finish radio capability changed
+        logd("Acquiring wake lock for setting radio capability");
         mWakeLock.acquire();
 
         return doSetRadioCapabilities(rafs);
@@ -357,19 +360,25 @@
                 }
             }
             RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
-            if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
+            // Added exception condition  to continue to mark as transaction fail case.
+            // Checking session validity during exception is not valid
+            if (ar.exception == null
+                    && ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId))) {
                 logd("onStartRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                         + " rc=" + rc);
                 return;
             }
             mRadioAccessFamilyStatusCounter--;
-            int id = rc.getPhoneId();
+            //rc.getPhoneId() moved to avoid Null Pointer Exception, since when exception occurs
+            //its expected rc is null.
             if (ar.exception != null) {
-                logd("onStartRadioCapabilityResponse: Error response session=" + rc.getSession());
-                logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=FAIL");
-                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
+                logd("onStartRadioCapabilityResponse got exception=" + ar.exception);
+                //mSetRadioAccessFamilyStatus will be set anyway to SET_RC_STATUS_FAIL
+                // if either of them fail at issueFinish() method below,i.e. both phone id count
+                // is set to SET_RC_STATUS_FAIL.
                 mTransactionFailed = true;
             } else {
+                int id = rc.getPhoneId();
                 logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=STARTED");
                 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
             }
@@ -481,13 +490,20 @@
      * @param msg obj field isa RadioCapability
      */
     void onFinishRadioCapabilityResponse(Message msg) {
-        RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
-        if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
-            logd("onFinishRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
-                    + " rc=" + rc);
-            return;
-        }
         synchronized (mSetRadioAccessFamilyStatus) {
+            AsyncResult ar = (AsyncResult)  msg.obj;
+            RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
+            // Added exception condition on finish to continue to revert if exception occurred.
+            // Checking session validity during exception is not valid
+            if (ar.exception == null
+                    && ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId))) {
+                logd("onFinishRadioCapabilityResponse: Ignore session="
+                        + mRadioCapabilitySessionId + " rc=" + rc);
+                return;
+            }
+            if (ar.exception != null) {
+                logd("onFinishRadioCapabilityResponse got exception=" + ar.exception);
+            }
             logd(" onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter="
                     + mRadioAccessFamilyStatusCounter);
             mRadioAccessFamilyStatusCounter--;
@@ -575,7 +591,6 @@
             clearTransaction();
         } else {
             intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED);
-
             // now revert.
             mTransactionFailed = false;
             RadioAccessFamily[] rafs = new RadioAccessFamily[mPhones.length];
@@ -602,6 +617,7 @@
             }
 
             if (isWakeLockHeld()) {
+                logd("clearTransaction:checking wakelock held and releasing");
                 mWakeLock.release();
             }
         }
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 0249f47..5ecdfcb 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -16,6 +16,15 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+import static android.telephony.TelephonyManager.HAL_SERVICE_IMS;
+import static android.telephony.TelephonyManager.HAL_SERVICE_MESSAGING;
+import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
+import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
+import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
+
 import static com.android.internal.telephony.RILConstants.*;
 
 import android.annotation.NonNull;
@@ -45,7 +54,9 @@
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.sysprop.TelephonyProperties;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.BarringInfo;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellInfo;
 import android.telephony.CellSignalStrengthCdma;
@@ -55,6 +66,7 @@
 import android.telephony.CellSignalStrengthTdscdma;
 import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.ClientRequestStats;
+import android.telephony.DomainSelectionService;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
@@ -67,18 +79,24 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyHistogram;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.HalService;
 import android.telephony.TelephonyManager.PrefNetworkMode;
 import android.telephony.data.DataProfile;
 import android.telephony.data.NetworkSliceInfo;
 import android.telephony.data.TrafficDescriptor;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.ConnectionFailureInfo;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.emergency.EmergencyConstants;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.imsphone.ImsCallInfo;
 import com.android.internal.telephony.metrics.ModemRestartStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
@@ -92,8 +110,10 @@
 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.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
@@ -133,6 +153,9 @@
     private final ClientWakelockTracker mClientWakelockTracker = new ClientWakelockTracker();
 
     /** @hide */
+    public static final HalVersion RADIO_HAL_VERSION_UNSUPPORTED = HalVersion.UNSUPPORTED;
+
+    /** @hide */
     public static final HalVersion RADIO_HAL_VERSION_UNKNOWN = HalVersion.UNKNOWN;
 
     /** @hide */
@@ -159,8 +182,11 @@
     /** @hide */
     public static final HalVersion RADIO_HAL_VERSION_2_0 = new HalVersion(2, 0);
 
-    // IRadio version
-    private HalVersion mRadioVersion = RADIO_HAL_VERSION_UNKNOWN;
+    /** @hide */
+    public static final HalVersion RADIO_HAL_VERSION_2_1 = new HalVersion(2, 1);
+
+    // Hal version
+    private Map<Integer, HalVersion> mHalVersion = new HashMap<>();
 
     //***** Instance Variables
 
@@ -198,15 +224,9 @@
 
     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;
+    public static final int MIN_SERVICE_IDX = HAL_SERVICE_RADIO;
+
+    public static final int MAX_SERVICE_IDX = HAL_SERVICE_IMS;
 
     /**
      * An array of sets that records if services are disabled in the HAL for a specific phone ID
@@ -233,6 +253,8 @@
     private volatile IRadio mRadioProxy = null;
     private DataResponse mDataResponse;
     private DataIndication mDataIndication;
+    private ImsResponse mImsResponse;
+    private ImsIndication mImsIndication;
     private MessagingResponse mMessagingResponse;
     private MessagingIndication mMessagingIndication;
     private ModemResponse mModemResponse;
@@ -362,11 +384,11 @@
 
                 case EVENT_AIDL_PROXY_DEAD:
                     int aidlService = msg.arg1;
-                    AtomicLong obj = (AtomicLong) msg.obj;
-                    riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msg.obj
+                    long msgCookie = (long) msg.obj;
+                    riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msgCookie
                             + ", service = " + serviceToString(aidlService) + ", cookie = "
                             + mServiceCookies.get(aidlService));
-                    if (obj.get() == mServiceCookies.get(aidlService).get()) {
+                    if (msgCookie == mServiceCookies.get(aidlService).get()) {
                         mIsRadioProxyInitialized = false;
                         resetProxyAndRequestList(aidlService);
                     }
@@ -413,8 +435,8 @@
         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,
+                    HAL_SERVICE_RADIO, 0 /* ignored arg2 */, cookie));
         }
     }
 
@@ -428,8 +450,11 @@
 
         public void linkToDeath(IBinder service) throws RemoteException {
             if (service != null) {
+                riljLog("Linked to death for service " + serviceToString(mService));
                 mBinder = service;
                 mBinder.linkToDeath(this, (int) mServiceCookies.get(mService).incrementAndGet());
+            } else {
+                riljLoge("Unable to link to death for service " + serviceToString(mService));
             }
         }
 
@@ -444,13 +469,13 @@
         public void binderDied() {
             riljLog("Service " + serviceToString(mService) + " has died.");
             mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_AIDL_PROXY_DEAD, mService,
-                    0 /* ignored arg2 */, mServiceCookies.get(mService)));
+                    0 /* ignored arg2 */, mServiceCookies.get(mService).get()));
             unlinkToDeath();
         }
     }
 
     private synchronized void resetProxyAndRequestList(int service) {
-        if (service == RADIO_SERVICE) {
+        if (service == HAL_SERVICE_RADIO) {
             mRadioProxy = null;
         } else {
             mServiceProxies.get(service).clear();
@@ -467,7 +492,7 @@
         // Clear request list on close
         clearRequestList(RADIO_NOT_AVAILABLE, false);
 
-        if (service == RADIO_SERVICE) {
+        if (service == HAL_SERVICE_RADIO) {
             getRadioProxy(null);
         } else {
             getRadioServiceProxy(service, null);
@@ -496,13 +521,13 @@
             // Disable HIDL service
             if (mRadioProxy != null) {
                 riljLog("Disable HIDL service");
-                mDisabledRadioServices.get(RADIO_SERVICE).add(mPhoneId);
+                mDisabledRadioServices.get(HAL_SERVICE_RADIO).add(mPhoneId);
             }
 
             mMockModem.bindAllMockModemService();
 
             for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-                if (service == RADIO_SERVICE) continue;
+                if (service == HAL_SERVICE_RADIO) continue;
 
                 int retryCount = 0;
                 IBinder binder;
@@ -537,14 +562,26 @@
         if ((serviceName == null) || (!serviceBound)) {
             if (serviceBound) riljLog("Unbinding to MockModemService");
 
-            if (mDisabledRadioServices.get(RADIO_SERVICE).contains(mPhoneId)) {
-                mDisabledRadioServices.get(RADIO_SERVICE).clear();
+            if (mDisabledRadioServices.get(HAL_SERVICE_RADIO).contains(mPhoneId)) {
+                mDisabledRadioServices.get(HAL_SERVICE_RADIO).clear();
             }
 
             if (mMockModem != null) {
-                mRadioVersion = RADIO_HAL_VERSION_UNKNOWN;
                 mMockModem = null;
                 for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
+                    if (service == HAL_SERVICE_RADIO) {
+                        if (isRadioVersion2_0()) {
+                            mHalVersion.put(service, RADIO_HAL_VERSION_2_0);
+                        } else {
+                            mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
+                        }
+                    } else {
+                        if (isRadioServiceSupported(service)) {
+                            mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
+                        } else {
+                            mHalVersion.put(service, RADIO_HAL_VERSION_UNSUPPORTED);
+                        }
+                    }
                     resetProxyAndRequestList(service);
                 }
             }
@@ -586,7 +623,10 @@
     /** 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 (mHalVersion.containsKey(HAL_SERVICE_RADIO)
+                && mHalVersion.get(HAL_SERVICE_RADIO).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");
@@ -603,14 +643,14 @@
         }
 
         try {
-            if (mDisabledRadioServices.get(RADIO_SERVICE).contains(mPhoneId)) {
+            if (mDisabledRadioServices.get(HAL_SERVICE_RADIO).contains(mPhoneId)) {
                 riljLoge("getRadioProxy: mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId]
                         + " is disabled");
             } else {
                 try {
                     mRadioProxy = android.hardware.radio.V1_6.IRadio.getService(
                             HIDL_SERVICE_NAME[mPhoneId], true);
-                    mRadioVersion = RADIO_HAL_VERSION_1_6;
+                    mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_6);
                 } catch (NoSuchElementException e) {
                 }
 
@@ -618,7 +658,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_5.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_5;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_5);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -627,7 +667,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_4.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_4;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_4);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -636,7 +676,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_3.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_3;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_3);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -645,7 +685,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_2.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_2;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_2);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -654,7 +694,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_1.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_1;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_1);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -663,7 +703,7 @@
                     try {
                         mRadioProxy = android.hardware.radio.V1_0.IRadio.getService(
                                 HIDL_SERVICE_NAME[mPhoneId], true);
-                        mRadioVersion = RADIO_HAL_VERSION_1_0;
+                        mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_1_0);
                     } catch (NoSuchElementException e) {
                     }
                 }
@@ -672,11 +712,11 @@
                     if (!mIsRadioProxyInitialized) {
                         mIsRadioProxyInitialized = true;
                         mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
-                                mServiceCookies.get(RADIO_SERVICE).incrementAndGet());
+                                mServiceCookies.get(HAL_SERVICE_RADIO).incrementAndGet());
                         mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
                     }
                 } else {
-                    mDisabledRadioServices.get(RADIO_SERVICE).add(mPhoneId);
+                    mDisabledRadioServices.get(HAL_SERVICE_RADIO).add(mPhoneId);
                     riljLoge("getRadioProxy: set mRadioProxy for "
                             + HIDL_SERVICE_NAME[mPhoneId] + " as disabled");
                 }
@@ -701,29 +741,32 @@
 
     /**
      * 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.
+     * {@link RadioNetworkProxy}, {@link RadioSimProxy}, {@link RadioVoiceProxy},
+     * {@link RadioImsProxy}, or null 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);
+            return (T) getRadioServiceProxy(HAL_SERVICE_DATA, result);
         }
         if (serviceClass == RadioMessagingProxy.class) {
-            return (T) getRadioServiceProxy(MESSAGING_SERVICE, result);
+            return (T) getRadioServiceProxy(HAL_SERVICE_MESSAGING, result);
         }
         if (serviceClass == RadioModemProxy.class) {
-            return (T) getRadioServiceProxy(MODEM_SERVICE, result);
+            return (T) getRadioServiceProxy(HAL_SERVICE_MODEM, result);
         }
         if (serviceClass == RadioNetworkProxy.class) {
-            return (T) getRadioServiceProxy(NETWORK_SERVICE, result);
+            return (T) getRadioServiceProxy(HAL_SERVICE_NETWORK, result);
         }
         if (serviceClass == RadioSimProxy.class) {
-            return (T) getRadioServiceProxy(SIM_SERVICE, result);
+            return (T) getRadioServiceProxy(HAL_SERVICE_SIM, result);
         }
         if (serviceClass == RadioVoiceProxy.class) {
-            return (T) getRadioServiceProxy(VOICE_SERVICE, result);
+            return (T) getRadioServiceProxy(HAL_SERVICE_VOICE, result);
+        }
+        if (serviceClass == RadioImsProxy.class) {
+            return (T) getRadioServiceProxy(HAL_SERVICE_IMS, result);
         }
         riljLoge("getRadioServiceProxy: unrecognized " + serviceClass);
         return null;
@@ -731,12 +774,15 @@
 
     /**
      * 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.
+     * For HAL_SERVICE_RADIO, 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 ((service >= HAL_SERVICE_IMS) && !isRadioServiceSupported(service)) {
+            return mServiceProxies.get(service);
+        }
         if (!mIsCellularSupported) {
             if (RILJ_LOGV) riljLog("getRadioServiceProxy: Not calling getService(): wifi-only");
             if (result != null) {
@@ -753,168 +799,190 @@
         }
 
         try {
-            if (mDisabledRadioServices.get(service).contains(mPhoneId)) {
+            if (mMockModem == null && mDisabledRadioServices.get(service).contains(mPhoneId)) {
                 riljLoge("getRadioServiceProxy: " + serviceToString(service) + " for "
                         + HIDL_SERVICE_NAME[mPhoneId] + " is disabled");
             } else {
                 IBinder binder;
                 switch (service) {
-                    case DATA_SERVICE:
+                    case HAL_SERVICE_DATA:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.data.IRadioData.DESCRIPTOR + "/"
                                             + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(DATA_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_DATA);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioDataProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioDataProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.data.IRadioData.Stub.asInterface(
-                                            binder));
+                                            binder)));
                         }
                         break;
-                    case MESSAGING_SERVICE:
+                    case HAL_SERVICE_MESSAGING:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.messaging.IRadioMessaging.DESCRIPTOR
                                             + "/" + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(MESSAGING_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_MESSAGING);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioMessagingProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioMessagingProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.messaging.IRadioMessaging.Stub
-                                            .asInterface(binder));
+                                            .asInterface(binder)));
                         }
                         break;
-                    case MODEM_SERVICE:
+                    case HAL_SERVICE_MODEM:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.modem.IRadioModem.DESCRIPTOR + "/"
                                             + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(MODEM_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_MODEM);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioModemProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioModemProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.modem.IRadioModem.Stub
-                                            .asInterface(binder));
+                                            .asInterface(binder)));
                         }
                         break;
-                    case NETWORK_SERVICE:
+                    case HAL_SERVICE_NETWORK:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.network.IRadioNetwork.DESCRIPTOR + "/"
                                             + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(NETWORK_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_NETWORK);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioNetworkProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioNetworkProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.network.IRadioNetwork.Stub
-                                            .asInterface(binder));
+                                            .asInterface(binder)));
                         }
                         break;
-                    case SIM_SERVICE:
+                    case HAL_SERVICE_SIM:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.sim.IRadioSim.DESCRIPTOR + "/"
                                             + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(SIM_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_SIM);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioSimProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioSimProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.sim.IRadioSim.Stub
-                                            .asInterface(binder));
+                                            .asInterface(binder)));
                         }
                         break;
-                    case VOICE_SERVICE:
+                    case HAL_SERVICE_VOICE:
                         if (mMockModem == null) {
                             binder = ServiceManager.waitForDeclaredService(
                                     android.hardware.radio.voice.IRadioVoice.DESCRIPTOR + "/"
                                             + HIDL_SERVICE_NAME[mPhoneId]);
                         } else {
-                            binder = mMockModem.getServiceBinder(VOICE_SERVICE);
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_VOICE);
                         }
                         if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioVoiceProxy) serviceProxy).setAidl(mRadioVersion,
+                            mHalVersion.put(service, ((RadioVoiceProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
                                     android.hardware.radio.voice.IRadioVoice.Stub
-                                            .asInterface(binder));
+                                            .asInterface(binder)));
+                        }
+                        break;
+                    case HAL_SERVICE_IMS:
+                        if (mMockModem == null) {
+                            binder = ServiceManager.waitForDeclaredService(
+                                    android.hardware.radio.ims.IRadioIms.DESCRIPTOR + "/"
+                                            + HIDL_SERVICE_NAME[mPhoneId]);
+                        } else {
+                            binder = mMockModem.getServiceBinder(HAL_SERVICE_IMS);
+                        }
+                        if (binder != null) {
+                            mHalVersion.put(service, ((RadioImsProxy) serviceProxy).setAidl(
+                                    mHalVersion.get(service),
+                                    android.hardware.radio.ims.IRadioIms.Stub
+                                            .asInterface(binder)));
                         }
                         break;
                 }
 
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_6;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_6);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_5;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_5);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_4;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_4);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_3;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_3);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_2;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_2);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_1;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_1);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 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)) {
+                if (serviceProxy.isEmpty()
+                        && mHalVersion.get(service).less(RADIO_HAL_VERSION_2_0)) {
                     try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_0;
-                        serviceProxy.setHidl(mRadioVersion,
+                        mHalVersion.put(service, RADIO_HAL_VERSION_1_0);
+                        serviceProxy.setHidl(mHalVersion.get(service),
                                 android.hardware.radio.V1_0.IRadio.getService(
                                         HIDL_SERVICE_NAME[mPhoneId], true));
                     } catch (NoSuchElementException e) {
@@ -924,57 +992,65 @@
                 if (!serviceProxy.isEmpty()) {
                     if (serviceProxy.isAidl()) {
                         switch (service) {
-                            case DATA_SERVICE:
+                            case HAL_SERVICE_DATA:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioDataProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioDataProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mDataResponse, mDataIndication);
                                 break;
-                            case MESSAGING_SERVICE:
+                            case HAL_SERVICE_MESSAGING:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioMessagingProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioMessagingProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mMessagingResponse, mMessagingIndication);
                                 break;
-                            case MODEM_SERVICE:
+                            case HAL_SERVICE_MODEM:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioModemProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioModemProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mModemResponse, mModemIndication);
                                 break;
-                            case NETWORK_SERVICE:
+                            case HAL_SERVICE_NETWORK:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioNetworkProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioNetworkProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mNetworkResponse, mNetworkIndication);
                                 break;
-                            case SIM_SERVICE:
+                            case HAL_SERVICE_SIM:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioSimProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioSimProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mSimResponse, mSimIndication);
                                 break;
-                            case VOICE_SERVICE:
+                            case HAL_SERVICE_VOICE:
                                 mDeathRecipients.get(service).linkToDeath(
                                         ((RadioVoiceProxy) serviceProxy).getAidl().asBinder());
                                 ((RadioVoiceProxy) serviceProxy).getAidl().setResponseFunctions(
                                         mVoiceResponse, mVoiceIndication);
                                 break;
+                            case HAL_SERVICE_IMS:
+                                mDeathRecipients.get(service).linkToDeath(
+                                        ((RadioImsProxy) serviceProxy).getAidl().asBinder());
+                                ((RadioImsProxy) serviceProxy).getAidl().setResponseFunctions(
+                                        mImsResponse, mImsIndication);
+                                break;
                         }
                     } else {
-                        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+                        if (mHalVersion.get(service)
+                                .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());
+                                    mServiceCookies.get(HAL_SERVICE_RADIO).incrementAndGet());
                             serviceProxy.getHidl().setResponseFunctions(
                                     mRadioResponse, mRadioIndication);
                         }
                     }
                 } else {
                     mDisabledRadioServices.get(service).add(mPhoneId);
+                    mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
                     riljLoge("getRadioServiceProxy: set " + serviceToString(service) + " for "
                             + HIDL_SERVICE_NAME[mPhoneId] + " as disabled");
                 }
@@ -1003,7 +1079,7 @@
         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) {
+                if (service == HAL_SERVICE_RADIO) {
                     getRadioProxy(null);
                 } else {
                     getRadioServiceProxy(service, null);
@@ -1044,7 +1120,11 @@
             mRadioBugDetector = new RadioBugDetector(context, mPhoneId);
         }
         try {
-            if (isRadioVersion2_0()) mRadioVersion = RADIO_HAL_VERSION_2_0;
+            if (isRadioVersion2_0()) {
+                mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_2_0);
+            } else {
+                mHalVersion.put(HAL_SERVICE_RADIO, RADIO_HAL_VERSION_UNKNOWN);
+            }
         } 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
@@ -1060,6 +1140,8 @@
         mRadioIndication = new RadioIndication(this);
         mDataResponse = new DataResponse(this);
         mDataIndication = new DataIndication(this);
+        mImsResponse = new ImsResponse(this);
+        mImsIndication = new ImsIndication(this);
         mMessagingResponse = new MessagingResponse(this);
         mMessagingIndication = new MessagingIndication(this);
         mModemResponse = new ModemResponse(this);
@@ -1073,19 +1155,33 @@
         mRilHandler = new RilHandler();
         mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
         for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-            if (service != RADIO_SERVICE) {
+            if (service != HAL_SERVICE_RADIO) {
+                try {
+                    if (isRadioServiceSupported(service)) {
+                        mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
+                    } else {
+                        mHalVersion.put(service, RADIO_HAL_VERSION_UNSUPPORTED);
+                    }
+                } 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;
+                }
                 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());
+            mServiceProxies.put(HAL_SERVICE_DATA, new RadioDataProxy());
+            mServiceProxies.put(HAL_SERVICE_MESSAGING, new RadioMessagingProxy());
+            mServiceProxies.put(HAL_SERVICE_MODEM, new RadioModemProxy());
+            mServiceProxies.put(HAL_SERVICE_NETWORK, new RadioNetworkProxy());
+            mServiceProxies.put(HAL_SERVICE_SIM, new RadioSimProxy());
+            mServiceProxies.put(HAL_SERVICE_VOICE, new RadioVoiceProxy());
+            mServiceProxies.put(HAL_SERVICE_IMS, new RadioImsProxy());
         } else {
             mServiceProxies = proxies;
         }
@@ -1114,7 +1210,7 @@
         // 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) {
+            if (service == HAL_SERVICE_RADIO) {
                 getRadioProxy(null);
             } else {
                 if (proxies == null) {
@@ -1122,30 +1218,62 @@
                     getRadioServiceProxy(service, null);
                 }
             }
-        }
 
-        if (RILJ_LOGD) {
-            riljLog("Radio HAL version: " + mRadioVersion);
+            if (RILJ_LOGD) {
+                riljLog("HAL version of " + serviceToString(service)
+                        + ": " + mHalVersion.get(service));
+            }
         }
     }
 
     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])) {
+        for (int service = HAL_SERVICE_DATA; service <= MAX_SERVICE_IDX; service++) {
+            if (isRadioServiceSupported(service)) {
                 return true;
             }
         }
         return false;
     }
 
+    private boolean isRadioServiceSupported(int service) {
+        String serviceName = "";
+
+        if (service == HAL_SERVICE_RADIO) {
+            return true;
+        }
+
+        switch (service) {
+            case HAL_SERVICE_DATA:
+                serviceName = android.hardware.radio.data.IRadioData.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_MESSAGING:
+                serviceName = android.hardware.radio.messaging.IRadioMessaging.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_MODEM:
+                serviceName = android.hardware.radio.modem.IRadioModem.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_NETWORK:
+                serviceName = android.hardware.radio.network.IRadioNetwork.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_SIM:
+                serviceName = android.hardware.radio.sim.IRadioSim.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_VOICE:
+                serviceName = android.hardware.radio.voice.IRadioVoice.DESCRIPTOR;
+                break;
+            case HAL_SERVICE_IMS:
+                serviceName = android.hardware.radio.ims.IRadioIms.DESCRIPTOR;
+                break;
+        }
+
+        if (!serviceName.equals("")
+                && 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;
@@ -1205,7 +1333,7 @@
             try {
                 simProxy.getIccCardStatus(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getIccCardStatus", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getIccCardStatus", e);
             }
         }
     }
@@ -1252,7 +1380,7 @@
                 simProxy.supplyIccPinForApp(rr.mSerial, RILUtils.convertNullToEmptyString(pin),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPinForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "supplyIccPinForApp", e);
             }
         }
     }
@@ -1279,7 +1407,7 @@
                         RILUtils.convertNullToEmptyString(newPin),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPukForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "supplyIccPukForApp", e);
             }
         }
     }
@@ -1305,7 +1433,7 @@
                 simProxy.supplyIccPin2ForApp(rr.mSerial, RILUtils.convertNullToEmptyString(pin),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPin2ForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "supplyIccPin2ForApp", e);
             }
         }
     }
@@ -1332,7 +1460,7 @@
                         RILUtils.convertNullToEmptyString(newPin2),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPuk2ForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "supplyIccPuk2ForApp", e);
             }
         }
     }
@@ -1360,7 +1488,7 @@
                         RILUtils.convertNullToEmptyString(newPin),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "changeIccPinForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "changeIccPinForApp", e);
             }
         }
     }
@@ -1388,7 +1516,7 @@
                         RILUtils.convertNullToEmptyString(newPin2),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "changeIccPin2ForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "changeIccPin2ForApp", e);
             }
         }
     }
@@ -1410,7 +1538,7 @@
                         RILUtils.convertNullToEmptyString(netpin));
             } catch (RemoteException | RuntimeException e) {
                 handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "supplyNetworkDepersonalization", e);
+                        HAL_SERVICE_NETWORK, "supplyNetworkDepersonalization", e);
             }
         }
     }
@@ -1420,7 +1548,7 @@
             Message result) {
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
         if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, result,
                     mRILDefaultWorkSource);
 
@@ -1433,7 +1561,7 @@
                 simProxy.supplySimDepersonalization(rr.mSerial, persoType,
                         RILUtils.convertNullToEmptyString(controlKey));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplySimDepersonalization", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "supplySimDepersonalization", e);
             }
         } else {
             if (PersoSubState.PERSOSUBSTATE_SIM_NETWORK == persoType) {
@@ -1465,7 +1593,7 @@
             try {
                 voiceProxy.getCurrentCalls(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCurrentCalls", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getCurrentCalls", e);
             }
         }
     }
@@ -1481,7 +1609,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_MODEM).greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result, mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
@@ -1492,7 +1620,8 @@
             try {
                 modemProxy.enableModem(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "enableModem", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM,
+                        "enableModem", e);
             }
         } else {
             if (RILJ_LOGV) riljLog("enableModem: not supported.");
@@ -1509,7 +1638,7 @@
             Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, result,
                     mRILDefaultWorkSource);
 
@@ -1521,7 +1650,8 @@
             try {
                 networkProxy.setSystemSelectionChannels(rr.mSerial, specifiers);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setSystemSelectionChannels", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "setSystemSelectionChannels", e);
             }
         } else {
             if (RILJ_LOGV) riljLog("setSystemSelectionChannels: not supported.");
@@ -1537,7 +1667,7 @@
     public void getSystemSelectionChannels(Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, result,
                     mRILDefaultWorkSource);
 
@@ -1549,7 +1679,8 @@
             try {
                 networkProxy.getSystemSelectionChannels(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getSystemSelectionChannels", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "getSystemSelectionChannels", e);
             }
         } else {
             if (RILJ_LOGV) riljLog("getSystemSelectionChannels: not supported.");
@@ -1565,7 +1696,7 @@
     public void getModemStatus(Message result) {
         RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
         if (modemProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
+        if (mHalVersion.get(HAL_SERVICE_MODEM).greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
                     mRILDefaultWorkSource);
 
@@ -1576,7 +1707,7 @@
             try {
                 modemProxy.getModemStackStatus(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getModemStatus", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getModemStatus", e);
             }
         } else {
             if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
@@ -1591,7 +1722,8 @@
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
             boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result) {
-        if (isEmergencyCall && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)
+        if (isEmergencyCall
+                && mHalVersion.get(HAL_SERVICE_VOICE).greaterOrEqual(RADIO_HAL_VERSION_1_4)
                 && emergencyNumberInfo != null) {
             emergencyDial(address, emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode,
                     uusInfo, result);
@@ -1609,7 +1741,7 @@
             try {
                 voiceProxy.dial(rr.mSerial, address, clirMode, uusInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "dial", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "dial", e);
             }
         }
     }
@@ -1618,7 +1750,7 @@
             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)) {
+        if (mHalVersion.get(HAL_SERVICE_VOICE).greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_EMERGENCY_DIAL, result,
                     mRILDefaultWorkSource);
 
@@ -1631,7 +1763,7 @@
                 voiceProxy.emergencyDial(rr.mSerial, RILUtils.convertNullToEmptyString(address),
                         emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, uusInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "emergencyDial", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "emergencyDial", e);
             }
         } else {
             riljLoge("emergencyDial is not supported with 1.4 below IRadio");
@@ -1650,13 +1782,13 @@
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result, mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + ">  " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
                         + " aid = " + aid);
             }
             try {
                 simProxy.getImsiForApp(rr.mSerial, RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getImsiForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getImsiForApp", e);
             }
         }
     }
@@ -1675,7 +1807,7 @@
             try {
                 voiceProxy.hangup(rr.mSerial, gsmIndex);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "hangup", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "hangup", e);
             }
         }
     }
@@ -1695,7 +1827,7 @@
             try {
                 voiceProxy.hangupWaitingOrBackground(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "hangupWaitingOrBackground", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "hangupWaitingOrBackground", e);
             }
         }
     }
@@ -1716,7 +1848,7 @@
                 voiceProxy.hangupForegroundResumeBackground(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
                 handleRadioProxyExceptionForRR(
-                        VOICE_SERVICE, "hangupForegroundResumeBackground", e);
+                        HAL_SERVICE_VOICE, "hangupForegroundResumeBackground", e);
             }
         }
     }
@@ -1735,7 +1867,8 @@
             try {
                 voiceProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "switchWaitingOrHoldingAndActive", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE,
+                        "switchWaitingOrHoldingAndActive", e);
             }
         }
     }
@@ -1753,7 +1886,7 @@
             try {
                 voiceProxy.conference(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "conference", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "conference", e);
             }
         }
     }
@@ -1771,7 +1904,7 @@
             try {
                 voiceProxy.rejectCall(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "rejectCall", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "rejectCall", e);
             }
         }
     }
@@ -1790,7 +1923,7 @@
             try {
                 voiceProxy.getLastCallFailCause(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getLastCallFailCause", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getLastCallFailCause", e);
             }
         }
     }
@@ -1809,7 +1942,7 @@
             try {
                 networkProxy.getSignalStrength(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getSignalStrength", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getSignalStrength", e);
             }
         }
     }
@@ -1833,7 +1966,7 @@
             try {
                 networkProxy.getVoiceRegistrationState(rr.mSerial, overrideHalVersion);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getVoiceRegistrationState", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getVoiceRegistrationState", e);
             }
         }
     }
@@ -1857,7 +1990,7 @@
             try {
                 networkProxy.getDataRegistrationState(rr.mSerial, overrideHalVersion);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getDataRegistrationState", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getDataRegistrationState", e);
             }
         }
     }
@@ -1875,7 +2008,7 @@
             try {
                 networkProxy.getOperator(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getOperator", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getOperator", e);
             }
         }
     }
@@ -1898,7 +2031,7 @@
                 modemProxy.setRadioPower(rr.mSerial, on, forEmergencyCall,
                         preferredForEmergencyCall);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioPower", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "setRadioPower", e);
             }
         }
     }
@@ -1917,7 +2050,7 @@
             try {
                 voiceProxy.sendDtmf(rr.mSerial, c + "");
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendDtmf", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "sendDtmf", e);
             }
         }
     }
@@ -1939,7 +2072,7 @@
                 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);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "sendSMS", e);
             }
         }
     }
@@ -1980,7 +2113,7 @@
                 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);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "sendSMSExpectMore", e);
             }
         }
     }
@@ -2010,8 +2143,21 @@
                 dataProxy.setupDataCall(rr.mSerial, mPhoneId, accessNetworkType, dataProfile,
                         isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo,
                         trafficDescriptor, matchAllRuleAllowed);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setupDataCall", e);
+            } catch (RemoteException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "setupDataCall", e);
+            } catch (RuntimeException e) {
+                riljLoge("setupDataCall RuntimeException: " + e);
+                int error = RadioError.SYSTEM_ERR;
+                int responseType = RadioResponseType.SOLICITED;
+                processResponseInternal(HAL_SERVICE_DATA, rr.mSerial, error, responseType);
+                processResponseDoneInternal(rr, error, responseType, null);
+            }
+        } else {
+            riljLoge("setupDataCall: DataProxy is empty");
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
+                result.sendToTarget();
             }
         }
     }
@@ -2048,7 +2194,7 @@
                         RILUtils.convertNullToEmptyString(pin2),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccIoForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "iccIoForApp", e);
             }
         }
     }
@@ -2070,7 +2216,7 @@
             try {
                 voiceProxy.sendUssd(rr.mSerial, RILUtils.convertNullToEmptyString(ussd));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendUssd", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "sendUssd", e);
             }
         }
     }
@@ -2089,7 +2235,7 @@
             try {
                 voiceProxy.cancelPendingUssd(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "cancelPendingUssd", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "cancelPendingUssd", e);
             }
         }
     }
@@ -2107,7 +2253,7 @@
             try {
                 voiceProxy.getClir(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getClir", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getClir", e);
             }
         }
     }
@@ -2126,7 +2272,7 @@
             try {
                 voiceProxy.setClir(rr.mSerial, clirMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setClir", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setClir", e);
             }
         }
     }
@@ -2147,7 +2293,7 @@
             try {
                 voiceProxy.getCallForwardStatus(rr.mSerial, cfReason, serviceClass, number);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCallForwardStatus", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getCallForwardStatus", e);
             }
         }
     }
@@ -2170,7 +2316,7 @@
                 voiceProxy.setCallForward(
                         rr.mSerial, action, cfReason, serviceClass, number, timeSeconds);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setCallForward", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setCallForward", e);
             }
         }
     }
@@ -2190,7 +2336,7 @@
             try {
                 voiceProxy.getCallWaiting(rr.mSerial, serviceClass);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCallWaiting", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getCallWaiting", e);
             }
         }
     }
@@ -2210,7 +2356,7 @@
             try {
                 voiceProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setCallWaiting", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setCallWaiting", e);
             }
         }
     }
@@ -2231,7 +2377,7 @@
             try {
                 messagingProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING,
                         "acknowledgeLastIncomingGsmSms", e);
             }
         }
@@ -2251,7 +2397,7 @@
                 voiceProxy.acceptCall(rr.mSerial);
                 mMetrics.writeRilAnswer(mPhoneId, rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "acceptCall", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "acceptCall", e);
             }
         }
     }
@@ -2273,7 +2419,7 @@
                 dataProxy.deactivateDataCall(rr.mSerial, cid, reason);
                 mMetrics.writeRilDeactivateDataCall(mPhoneId, rr.mSerial, cid, reason);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "deactivateDataCall", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "deactivateDataCall", e);
             }
         }
     }
@@ -2304,7 +2450,7 @@
                         RILUtils.convertNullToEmptyString(password),
                         serviceClass, RILUtils.convertNullToEmptyString(appId));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getFacilityLockForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getFacilityLockForApp", e);
             }
         }
     }
@@ -2335,7 +2481,7 @@
                         RILUtils.convertNullToEmptyString(password), serviceClass,
                         RILUtils.convertNullToEmptyString(appId));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setFacilityLockForApp", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "setFacilityLockForApp", e);
             }
         }
     }
@@ -2360,7 +2506,7 @@
                         RILUtils.convertNullToEmptyString(oldPwd),
                         RILUtils.convertNullToEmptyString(newPwd));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "changeBarringPassword", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "changeBarringPassword", e);
             }
         }
     }
@@ -2379,7 +2525,7 @@
             try {
                 networkProxy.getNetworkSelectionMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getNetworkSelectionMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getNetworkSelectionMode", e);
             }
         }
     }
@@ -2399,7 +2545,7 @@
                 networkProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
                 handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "setNetworkSelectionModeAutomatic", e);
+                        HAL_SERVICE_NETWORK, "setNetworkSelectionModeAutomatic", e);
             }
         }
     }
@@ -2420,7 +2566,8 @@
                 networkProxy.setNetworkSelectionModeManual(rr.mSerial,
                         RILUtils.convertNullToEmptyString(operatorNumeric), ran);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setNetworkSelectionModeManual", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "setNetworkSelectionModeManual", e);
             }
         }
     }
@@ -2439,7 +2586,7 @@
             try {
                 networkProxy.getAvailableNetworks(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getAvailableNetworks", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getAvailableNetworks", e);
             }
         }
     }
@@ -2454,7 +2601,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_START_NETWORK_SCAN);
             if (RILJ_LOGD) {
                 riljLog("startNetworkScan: overrideHalVersion=" + overrideHalVersion);
@@ -2471,7 +2618,7 @@
                 networkProxy.startNetworkScan(rr.mSerial, networkScanRequest, overrideHalVersion,
                         result);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "startNetworkScan", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "startNetworkScan", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startNetworkScan: REQUEST_NOT_SUPPORTED");
@@ -2487,7 +2634,7 @@
     public void stopNetworkScan(Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STOP_NETWORK_SCAN, result,
                     mRILDefaultWorkSource);
 
@@ -2498,7 +2645,7 @@
             try {
                 networkProxy.stopNetworkScan(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "stopNetworkScan", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "stopNetworkScan", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "stopNetworkScan: REQUEST_NOT_SUPPORTED");
@@ -2524,7 +2671,7 @@
             try {
                 voiceProxy.startDtmf(rr.mSerial, c + "");
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "startDtmf", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "startDtmf", e);
             }
         }
     }
@@ -2542,7 +2689,7 @@
             try {
                 voiceProxy.stopDtmf(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "stopDtmf", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "stopDtmf", e);
             }
         }
     }
@@ -2562,7 +2709,7 @@
             try {
                 voiceProxy.separateConnection(rr.mSerial, gsmIndex);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "separateConnection", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "separateConnection", e);
             }
         }
     }
@@ -2581,7 +2728,7 @@
             try {
                 modemProxy.getBasebandVersion(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getBasebandVersion", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getBasebandVersion", e);
             }
         }
     }
@@ -2600,7 +2747,7 @@
             try {
                 voiceProxy.setMute(rr.mSerial, enableMute);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setMute", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setMute", e);
             }
         }
     }
@@ -2618,7 +2765,7 @@
             try {
                 voiceProxy.getMute(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getMute", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getMute", e);
             }
         }
     }
@@ -2636,7 +2783,7 @@
             try {
                 voiceProxy.getClip(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getClip", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getClip", e);
             }
         }
     }
@@ -2664,7 +2811,7 @@
             try {
                 dataProxy.getDataCallList(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "getDataCallList", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "getDataCallList", e);
             }
         }
     }
@@ -2695,7 +2842,8 @@
             try {
                 networkProxy.setSuppServiceNotifications(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setSuppServiceNotifications", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "setSuppServiceNotifications", e);
             }
         }
     }
@@ -2718,7 +2866,7 @@
                         RILUtils.convertNullToEmptyString(smsc),
                         RILUtils.convertNullToEmptyString(pdu));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "writeSmsToSim", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "writeSmsToSim", e);
             }
         }
     }
@@ -2739,7 +2887,7 @@
             try {
                 messagingProxy.deleteSmsOnSim(rr.mSerial, index);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "deleteSmsOnSim", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "deleteSmsOnSim", e);
             }
         }
     }
@@ -2758,7 +2906,7 @@
             try {
                 networkProxy.setBandMode(rr.mSerial, bandMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setBandMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setBandMode", e);
             }
         }
     }
@@ -2777,7 +2925,7 @@
             try {
                 networkProxy.getAvailableBandModes(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "queryAvailableBandMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "queryAvailableBandMode", e);
             }
         }
     }
@@ -2797,7 +2945,7 @@
             try {
                 simProxy.sendEnvelope(rr.mSerial, RILUtils.convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendEnvelope", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "sendEnvelope", e);
             }
         }
     }
@@ -2819,7 +2967,7 @@
                 simProxy.sendTerminalResponseToSim(rr.mSerial,
                         RILUtils.convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendTerminalResponse", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "sendTerminalResponse", e);
             }
         }
     }
@@ -2840,7 +2988,7 @@
                 simProxy.sendEnvelopeWithStatus(rr.mSerial,
                         RILUtils.convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendEnvelopeWithStatus", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "sendEnvelopeWithStatus", e);
             }
         }
     }
@@ -2859,7 +3007,7 @@
             try {
                 voiceProxy.explicitCallTransfer(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "explicitCallTransfer", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "explicitCallTransfer", e);
             }
         }
     }
@@ -2881,7 +3029,7 @@
             try {
                 networkProxy.setPreferredNetworkTypeBitmap(rr.mSerial, mAllowedNetworkTypesBitmask);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setPreferredNetworkType", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setPreferredNetworkType", e);
             }
         }
     }
@@ -2900,7 +3048,7 @@
             try {
                 networkProxy.getAllowedNetworkTypesBitmap(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getPreferredNetworkType", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getPreferredNetworkType", e);
             }
         }
     }
@@ -2910,7 +3058,7 @@
             @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (!networkProxy.isEmpty()) {
-            if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+            if (mHalVersion.get(HAL_SERVICE_NETWORK).less(RADIO_HAL_VERSION_1_6)) {
                 // For older HAL, redirects the call to setPreferredNetworkType.
                 setPreferredNetworkType(
                         RadioAccessFamily.getNetworkTypeFromRaf(networkTypeBitmask), result);
@@ -2927,7 +3075,8 @@
             try {
                 networkProxy.setAllowedNetworkTypesBitmap(rr.mSerial, mAllowedNetworkTypesBitmask);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setAllowedNetworkTypeBitmask", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "setAllowedNetworkTypeBitmask", e);
             }
         }
     }
@@ -2946,7 +3095,8 @@
             try {
                 networkProxy.getAllowedNetworkTypesBitmap(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getAllowedNetworkTypeBitmask", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "getAllowedNetworkTypeBitmask", e);
             }
         }
     }
@@ -2966,7 +3116,7 @@
             try {
                 networkProxy.setLocationUpdates(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setLocationUpdates", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setLocationUpdates", e);
             }
         }
     }
@@ -2978,7 +3128,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED, result,
                     getDefaultWorkSourceIfInvalid(workSource));
 
@@ -2989,7 +3139,8 @@
             try {
                 networkProxy.isNrDualConnectivityEnabled(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "isNrDualConnectivityEnabled", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "isNrDualConnectivityEnabled", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -3019,7 +3170,7 @@
             WorkSource workSource) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY, result,
                     getDefaultWorkSourceIfInvalid(workSource));
 
@@ -3031,7 +3182,7 @@
             try {
                 networkProxy.setNrDualConnectivityState(rr.mSerial, (byte) nrDualConnectivityState);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "enableNrDualConnectivity", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "enableNrDualConnectivity", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "enableNrDualConnectivity: REQUEST_NOT_SUPPORTED");
@@ -3057,7 +3208,7 @@
     @Override
     public void isVoNrEnabled(Message result, WorkSource workSource) {
 
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+        if (mHalVersion.get(HAL_SERVICE_VOICE).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
             RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
             if (!voiceProxy.isEmpty()) {
                 RILRequest rr = obtainRequest(RIL_REQUEST_IS_VONR_ENABLED , result,
@@ -3070,7 +3221,7 @@
                 try {
                     voiceProxy.isVoNrEnabled(rr.mSerial);
                 } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(VOICE_SERVICE, "isVoNrEnabled", e);
+                    handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "isVoNrEnabled", e);
                 }
             }
         } else {
@@ -3090,7 +3241,7 @@
     public void setVoNrEnabled(boolean enabled, Message result, WorkSource workSource) {
         setVoNrEnabled(enabled);
 
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+        if (mHalVersion.get(HAL_SERVICE_VOICE).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
             RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
             if (!voiceProxy.isEmpty()) {
                 RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_VONR, result,
@@ -3103,7 +3254,7 @@
                 try {
                     voiceProxy.setVoNrEnabled(rr.mSerial, enabled);
                 } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(VOICE_SERVICE, "setVoNrEnabled", e);
+                    handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setVoNrEnabled", e);
                 }
             }
         } else {
@@ -3135,7 +3286,7 @@
             try {
                 simProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setCdmaSubscriptionSource", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "setCdmaSubscriptionSource", e);
             }
         }
     }
@@ -3154,7 +3305,8 @@
             try {
                 networkProxy.getCdmaRoamingPreference(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "queryCdmaRoamingPreference", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "queryCdmaRoamingPreference", e);
             }
         }
     }
@@ -3174,7 +3326,7 @@
             try {
                 networkProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setCdmaRoamingPreference", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setCdmaRoamingPreference", e);
             }
         }
     }
@@ -3193,7 +3345,7 @@
             try {
                 voiceProxy.getTtyMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getTtyMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getTtyMode", e);
             }
         }
     }
@@ -3212,7 +3364,7 @@
             try {
                 voiceProxy.setTtyMode(rr.mSerial, ttyMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setTtyMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setTtyMode", e);
             }
         }
     }
@@ -3232,7 +3384,7 @@
             try {
                 voiceProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setPreferredVoicePrivacy", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "setPreferredVoicePrivacy", e);
             }
         }
     }
@@ -3251,7 +3403,7 @@
             try {
                 voiceProxy.getPreferredVoicePrivacy(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getPreferredVoicePrivacy", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "getPreferredVoicePrivacy", e);
             }
         }
     }
@@ -3271,7 +3423,7 @@
                 voiceProxy.sendCdmaFeatureCode(rr.mSerial,
                         RILUtils.convertNullToEmptyString(featureCode));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendCdmaFeatureCode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "sendCdmaFeatureCode", e);
             }
         }
     }
@@ -3292,7 +3444,7 @@
                 voiceProxy.sendBurstDtmf(rr.mSerial, RILUtils.convertNullToEmptyString(dtmfString),
                         on, off);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendBurstDtmf", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "sendBurstDtmf", e);
             }
         }
     }
@@ -3312,13 +3464,13 @@
 
             try {
                 messagingProxy.sendCdmaSmsExpectMore(rr.mSerial, pdu);
-                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                if (mHalVersion.get(HAL_SERVICE_MESSAGING).greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
                     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, "sendCdmaSMSExpectMore", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "sendCdmaSMSExpectMore", e);
             }
         }
     }
@@ -3340,7 +3492,7 @@
                 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);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "sendCdmaSms", e);
             }
         }
     }
@@ -3361,7 +3513,7 @@
             try {
                 messagingProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, success, cause);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING,
                         "acknowledgeLastIncomingCdmaSms", e);
             }
         }
@@ -3382,7 +3534,7 @@
             try {
                 messagingProxy.getGsmBroadcastConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getGsmBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "getGsmBroadcastConfig", e);
             }
         }
     }
@@ -3406,7 +3558,7 @@
             try {
                 messagingProxy.setGsmBroadcastConfig(rr.mSerial, config);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setGsmBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "setGsmBroadcastConfig", e);
             }
         }
     }
@@ -3427,7 +3579,8 @@
             try {
                 messagingProxy.setGsmBroadcastActivation(rr.mSerial, activate);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setGsmBroadcastActivation", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING,
+                        "setGsmBroadcastActivation", e);
             }
         }
     }
@@ -3447,7 +3600,7 @@
             try {
                 messagingProxy.getCdmaBroadcastConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getCdmaBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "getCdmaBroadcastConfig", e);
             }
         }
     }
@@ -3471,7 +3624,7 @@
             try {
                 messagingProxy.setCdmaBroadcastConfig(rr.mSerial, configs);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setCdmaBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "setCdmaBroadcastConfig", e);
             }
         }
     }
@@ -3492,7 +3645,8 @@
             try {
                 messagingProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setCdmaBroadcastActivation", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING,
+                        "setCdmaBroadcastActivation", e);
             }
         }
     }
@@ -3511,7 +3665,7 @@
             try {
                 simProxy.getCdmaSubscription(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getCdmaSubscription", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getCdmaSubscription", e);
             }
         }
     }
@@ -3532,7 +3686,7 @@
             try {
                 messagingProxy.writeSmsToRuim(rr.mSerial, status, pdu);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "writeSmsToRuim", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "writeSmsToRuim", e);
             }
         }
     }
@@ -3553,7 +3707,7 @@
             try {
                 messagingProxy.deleteSmsOnRuim(rr.mSerial, index);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "deleteSmsOnRuim", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "deleteSmsOnRuim", e);
             }
         }
     }
@@ -3572,7 +3726,41 @@
             try {
                 modemProxy.getDeviceIdentity(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getDeviceIdentity", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getDeviceIdentity", e);
+            }
+        }
+    }
+
+    @Override
+    public void getImei(Message result) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (modemProxy.isEmpty()) {
+            if (RILJ_LOGD) {
+                Rlog.e(RILJ_LOG_TAG, "getImei: modemProxy is Empty");
+            }
+            return;
+        }
+        if (mHalVersion.get(HAL_SERVICE_MODEM).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IMEI, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                modemProxy.getImei(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getImei", e);
+            }
+        }  else {
+            if (RILJ_LOGD) {
+                Rlog.e(RILJ_LOG_TAG, "getImei: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
             }
         }
     }
@@ -3591,7 +3779,7 @@
             try {
                 voiceProxy.exitEmergencyCallbackMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "exitEmergencyCallbackMode", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_VOICE, "exitEmergencyCallbackMode", e);
             }
         }
     }
@@ -3611,7 +3799,7 @@
             try {
                 messagingProxy.getSmscAddress(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getSmscAddress", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "getSmscAddress", e);
             }
         }
     }
@@ -3633,7 +3821,7 @@
                 messagingProxy.setSmscAddress(rr.mSerial,
                         RILUtils.convertNullToEmptyString(address));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setSmscAddress", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "setSmscAddress", e);
             }
         }
     }
@@ -3654,7 +3842,7 @@
             try {
                 messagingProxy.reportSmsMemoryStatus(rr.mSerial, available);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "reportSmsMemoryStatus", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING, "reportSmsMemoryStatus", e);
             }
         }
     }
@@ -3673,7 +3861,7 @@
             try {
                 simProxy.reportStkServiceIsRunning(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "reportStkServiceIsRunning", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "reportStkServiceIsRunning", e);
             }
         }
     }
@@ -3692,7 +3880,7 @@
             try {
                 simProxy.getCdmaSubscriptionSource(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getCdmaSubscriptionSource", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getCdmaSubscriptionSource", e);
             }
         }
     }
@@ -3714,7 +3902,7 @@
                 messagingProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
                         RILUtils.convertNullToEmptyString(ackPdu));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MESSAGING,
                         "acknowledgeIncomingGsmSmsWithPdu", e);
             }
         }
@@ -3734,7 +3922,7 @@
             try {
                 networkProxy.getVoiceRadioTechnology(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getVoiceRadioTechnology", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getVoiceRadioTechnology", e);
             }
         }
     }
@@ -3753,7 +3941,7 @@
             try {
                 networkProxy.getCellInfoList(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getCellInfoList", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getCellInfoList", e);
             }
         }
     }
@@ -3773,7 +3961,7 @@
             try {
                 networkProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setCellInfoListRate", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setCellInfoListRate", e);
             }
         }
     }
@@ -3793,7 +3981,7 @@
             try {
                 dataProxy.setInitialAttachApn(rr.mSerial, dataProfile, isRoaming);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setInitialAttachApn", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "setInitialAttachApn", e);
             }
         }
     }
@@ -3812,7 +4000,7 @@
             try {
                 networkProxy.getImsRegistrationState(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getImsRegistrationState", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getImsRegistrationState", e);
             }
         }
     }
@@ -3835,7 +4023,7 @@
                 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(HAL_SERVICE_MESSAGING, "sendImsGsmSms", e);
             }
         }
     }
@@ -3857,7 +4045,7 @@
                 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(HAL_SERVICE_MESSAGING, "sendImsCdmaSms", e);
             }
         }
     }
@@ -3885,7 +4073,7 @@
                 simProxy.iccTransmitApduBasicChannel(
                         rr.mSerial, cla, instruction, p1, p2, p3, data);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccTransmitApduBasicChannel", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "iccTransmitApduBasicChannel", e);
             }
         }
     }
@@ -3910,13 +4098,13 @@
                 simProxy.iccOpenLogicalChannel(rr.mSerial, RILUtils.convertNullToEmptyString(aid),
                         p2);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccOpenLogicalChannel", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "iccOpenLogicalChannel", e);
             }
         }
     }
 
     @Override
-    public void iccCloseLogicalChannel(int channel, Message result) {
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message result) {
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
         if (!simProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_CLOSE_CHANNEL, result,
@@ -3924,20 +4112,19 @@
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " channel = " + channel);
+                        + " channel = " + channel + " isEs10 = " + isEs10);
             }
-
             try {
-                simProxy.iccCloseLogicalChannel(rr.mSerial, channel);
+                simProxy.iccCloseLogicalChannel(rr.mSerial, channel, isEs10);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccCloseLogicalChannel", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "iccCloseLogicalChannel", e);
             }
         }
     }
 
     @Override
     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2,
-            int p3, String data, Message result) {
+            int p3, String data, boolean isEs10Command, Message result) {
         if (channel <= 0) {
             throw new RuntimeException(
                     "Invalid channel in iccTransmitApduLogicalChannel: " + channel);
@@ -3954,6 +4141,7 @@
                             + 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)
+                            + " isEs10Command = " + isEs10Command
                             + " data = " + data);
                 } else {
                     riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
@@ -3962,9 +4150,9 @@
 
             try {
                 simProxy.iccTransmitApduLogicalChannel(
-                        rr.mSerial, channel, cla, instruction, p1, p2, p3, data);
+                        rr.mSerial, channel, cla, instruction, p1, p2, p3, data, isEs10Command);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccTransmitApduLogicalChannel", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "iccTransmitApduLogicalChannel", e);
             }
         }
     }
@@ -3984,7 +4172,7 @@
             try {
                 modemProxy.nvReadItem(rr.mSerial, itemID);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvReadItem", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "nvReadItem", e);
             }
         }
     }
@@ -4005,7 +4193,7 @@
                 modemProxy.nvWriteItem(rr.mSerial, itemId,
                         RILUtils.convertNullToEmptyString(itemValue));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteItem", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "nvWriteItem", e);
             }
         }
     }
@@ -4026,7 +4214,7 @@
             try {
                 modemProxy.nvWriteCdmaPrl(rr.mSerial, preferredRoamingList);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteCdmaPrl", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "nvWriteCdmaPrl", e);
             }
         }
     }
@@ -4046,7 +4234,7 @@
             try {
                 modemProxy.nvResetConfig(rr.mSerial, resetType);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvResetConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "nvResetConfig", e);
             }
         }
     }
@@ -4068,7 +4256,7 @@
             try {
                 simProxy.setUiccSubscription(rr.mSerial, slotId, appIndex, subId, subStatus);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setUiccSubscription", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "setUiccSubscription", e);
             }
         }
     }
@@ -4083,7 +4271,7 @@
         // 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);
+        return mHalVersion.get(HAL_SERVICE_RADIO).greaterOrEqual(RADIO_HAL_VERSION_1_2);
     }
 
     @Override
@@ -4100,7 +4288,7 @@
             try {
                 dataProxy.setDataAllowed(rr.mSerial, allowed);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataAllowed", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "setDataAllowed", e);
             }
         }
     }
@@ -4120,7 +4308,7 @@
             try {
                 modemProxy.getHardwareConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getHardwareConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getHardwareConfig", e);
             }
         }
     }
@@ -4143,7 +4331,7 @@
                         RILUtils.convertNullToEmptyString(data),
                         RILUtils.convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "requestIccSimAuthentication", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "requestIccSimAuthentication", e);
             }
         }
     }
@@ -4166,7 +4354,7 @@
             try {
                 dataProxy.setDataProfile(rr.mSerial, dps, isRoaming);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataProfile", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "setDataProfile", e);
             }
         }
     }
@@ -4184,7 +4372,7 @@
             try {
                 modemProxy.requestShutdown(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "requestShutdown", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "requestShutdown", e);
             }
         }
     }
@@ -4203,7 +4391,7 @@
             try {
                 modemProxy.getRadioCapability(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getRadioCapability", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getRadioCapability", e);
             }
         }
     }
@@ -4223,14 +4411,14 @@
             try {
                 modemProxy.setRadioCapability(rr.mSerial, rc);
             } catch (Exception e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioCapability", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "setRadioCapability", e);
             }
         }
     }
 
     @Override
     public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+        if (mHalVersion.get(HAL_SERVICE_RADIO).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");
@@ -4254,14 +4442,14 @@
             try {
                 radioProxy.startLceService(rr.mSerial, reportIntervalMs, pullMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "startLceService", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_RADIO, "startLceService", e);
             }
         }
     }
 
     @Override
     public void stopLceService(Message result) {
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+        if (mHalVersion.get(HAL_SERVICE_RADIO).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");
@@ -4284,7 +4472,7 @@
             try {
                 radioProxy.stopLceService(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "stopLceService", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_RADIO, "stopLceService", e);
             }
         }
     }
@@ -4303,7 +4491,7 @@
             long completionWindowMillis) {
         RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
         if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_DATA_THROTTLING, result,
                     getDefaultWorkSourceIfInvalid(workSource));
 
@@ -4318,7 +4506,7 @@
                 dataProxy.setDataThrottling(rr.mSerial, (byte) dataThrottlingAction,
                         completionWindowMillis);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataThrottling", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "setDataThrottling", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "setDataThrottling: REQUEST_NOT_SUPPORTED");
@@ -4343,7 +4531,7 @@
     @Deprecated
     @Override
     public void pullLceData(Message result) {
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+        if (mHalVersion.get(HAL_SERVICE_RADIO).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");
@@ -4366,7 +4554,7 @@
             try {
                 radioProxy.pullLceData(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "pullLceData", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_RADIO, "pullLceData", e);
             }
         }
     }
@@ -4388,7 +4576,7 @@
                         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);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "getModemActivityInfo", e);
             }
         }
     }
@@ -4411,7 +4599,7 @@
             try {
                 simProxy.setAllowedCarriers(rr.mSerial, carrierRestrictionRules, result);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setAllowedCarriers", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "setAllowedCarriers", e);
             }
         }
     }
@@ -4430,7 +4618,7 @@
             try {
                 simProxy.getAllowedCarriers(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getAllowedCarriers", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getAllowedCarriers", e);
             }
         }
     }
@@ -4450,7 +4638,7 @@
             try {
                 modemProxy.sendDeviceState(rr.mSerial, stateType, state);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "sendDeviceState", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_MODEM, "sendDeviceState", e);
             }
         }
     }
@@ -4470,7 +4658,7 @@
             try {
                 networkProxy.setIndicationFilter(rr.mSerial, filter);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setIndicationFilter", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setIndicationFilter", e);
             }
         }
     }
@@ -4480,7 +4668,7 @@
             @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)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
                     result, mRILDefaultWorkSource);
 
@@ -4491,7 +4679,7 @@
             try {
                 networkProxy.setSignalStrengthReportingCriteria(rr.mSerial, signalThresholdInfos);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE,
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
                         "setSignalStrengthReportingCriteria", e);
             }
         } else {
@@ -4505,7 +4693,7 @@
             Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA, result,
                     mRILDefaultWorkSource);
 
@@ -4519,7 +4707,7 @@
                         ran);
             } catch (RemoteException | RuntimeException e) {
                 handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "setLinkCapacityReportingCriteria", e);
+                        HAL_SERVICE_NETWORK, "setLinkCapacityReportingCriteria", e);
             }
         } else {
             riljLoge("setLinkCapacityReportingCriteria ignored on IRadio version less than 1.2");
@@ -4541,7 +4729,7 @@
             try {
                 simProxy.setSimCardPower(rr.mSerial, state, result);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setSimCardPower", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "setSimCardPower", e);
             }
         }
     }
@@ -4552,7 +4740,7 @@
         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)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
                     mRILDefaultWorkSource);
             if (RILJ_LOGD) {
@@ -4562,7 +4750,8 @@
             try {
                 simProxy.setCarrierInfoForImsiEncryption(rr.mSerial, imsiEncryptionInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setCarrierInfoForImsiEncryption", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM,
+                        "setCarrierInfoForImsiEncryption", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -4582,7 +4771,7 @@
         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)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_START_KEEPALIVE, result,
                     mRILDefaultWorkSource);
 
@@ -4593,7 +4782,7 @@
             try {
                 dataProxy.startKeepalive(rr.mSerial, contextId, packetData, intervalMillis, result);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "startNattKeepalive", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "startNattKeepalive", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startNattKeepalive: REQUEST_NOT_SUPPORTED");
@@ -4609,7 +4798,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STOP_KEEPALIVE, result,
                     mRILDefaultWorkSource);
 
@@ -4620,7 +4809,7 @@
             try {
                 dataProxy.stopKeepalive(rr.mSerial, sessionHandle);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "stopNattKeepalive", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "stopNattKeepalive", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "stopNattKeepalive: REQUEST_NOT_SUPPORTED");
@@ -4669,7 +4858,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS, result,
                     mRILDefaultWorkSource);
 
@@ -4681,7 +4870,7 @@
             try {
                 simProxy.enableUiccApplications(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "enableUiccApplications", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "enableUiccApplications", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "enableUiccApplications: REQUEST_NOT_SUPPORTED");
@@ -4702,7 +4891,7 @@
     public void areUiccApplicationsEnabled(Message result) {
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
         if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT, result,
                     mRILDefaultWorkSource);
 
@@ -4713,7 +4902,7 @@
             try {
                 simProxy.areUiccApplicationsEnabled(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "areUiccApplicationsEnabled", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "areUiccApplicationsEnabled", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -4733,7 +4922,7 @@
     @Override
     public boolean canToggleUiccApplicationsEnablement() {
         return !getRadioServiceProxy(RadioSimProxy.class, null).isEmpty()
-                && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5);
+                && mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_5);
     }
 
     @Override
@@ -4759,7 +4948,7 @@
                 voiceProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
             } catch (RemoteException | RuntimeException e) {
                 handleRadioProxyExceptionForRR(
-                        VOICE_SERVICE, "handleStkCallSetupRequestFromSim", e);
+                        HAL_SERVICE_VOICE, "handleStkCallSetupRequestFromSim", e);
             }
         }
     }
@@ -4771,7 +4960,7 @@
     public void getBarringInfo(Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_BARRING_INFO, result,
                     mRILDefaultWorkSource);
 
@@ -4782,7 +4971,7 @@
             try {
                 networkProxy.getBarringInfo(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getBarringInfo", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getBarringInfo", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getBarringInfo: REQUEST_NOT_SUPPORTED");
@@ -4801,7 +4990,7 @@
     public void allocatePduSessionId(Message result) {
         RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
         if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ALLOCATE_PDU_SESSION_ID, result,
                     mRILDefaultWorkSource);
             if (RILJ_LOGD) {
@@ -4811,7 +5000,7 @@
             try {
                 dataProxy.allocatePduSessionId(rr.mSerial);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "allocatePduSessionId", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "allocatePduSessionId", e);
             }
         } else {
             AsyncResult.forMessage(result, null,
@@ -4827,7 +5016,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_RELEASE_PDU_SESSION_ID, result,
                     mRILDefaultWorkSource);
             if (RILJ_LOGD) {
@@ -4837,7 +5026,7 @@
             try {
                 dataProxy.releasePduSessionId(rr.mSerial, pduSessionId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "releasePduSessionId", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "releasePduSessionId", e);
             }
         } else {
             AsyncResult.forMessage(result, null,
@@ -4853,7 +5042,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_START_HANDOVER, result,
                     mRILDefaultWorkSource);
             if (RILJ_LOGD) {
@@ -4863,7 +5052,7 @@
             try {
                 dataProxy.startHandover(rr.mSerial, callId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "startHandover", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "startHandover", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startHandover: REQUEST_NOT_SUPPORTED");
@@ -4882,7 +5071,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_HANDOVER, result,
                     mRILDefaultWorkSource);
             if (RILJ_LOGD) {
@@ -4892,7 +5081,7 @@
             try {
                 dataProxy.cancelHandover(rr.mSerial, callId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "cancelHandover", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "cancelHandover", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "cancelHandover: REQUEST_NOT_SUPPORTED");
@@ -4909,7 +5098,7 @@
     public void getSlicingConfig(Message result) {
         RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
         if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_DATA).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SLICING_CONFIG, result,
                     mRILDefaultWorkSource);
 
@@ -4920,7 +5109,7 @@
             try {
                 dataProxy.getSlicingConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "getSlicingConfig", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_DATA, "getSlicingConfig", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getSlicingConfig: REQUEST_NOT_SUPPORTED");
@@ -4934,7 +5123,7 @@
     public void getSimPhonebookRecords(Message result) {
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
         if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS, result,
                     mRILDefaultWorkSource);
 
@@ -4945,7 +5134,7 @@
             try {
                 simProxy.getSimPhonebookRecords(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getSimPhonebookRecords", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getSimPhonebookRecords", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -4963,7 +5152,7 @@
     public void getSimPhonebookCapacity(Message result) {
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
         if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY, result,
                     mRILDefaultWorkSource);
 
@@ -4974,7 +5163,7 @@
             try {
                 simProxy.getSimPhonebookCapacity(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getSimPhonebookCapacity", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "getSimPhonebookCapacity", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -4992,7 +5181,7 @@
     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)) {
+        if (mHalVersion.get(HAL_SERVICE_SIM).greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD, result,
                     mRILDefaultWorkSource);
 
@@ -5004,7 +5193,7 @@
             try {
                 simProxy.updateSimPhonebookRecords(rr.mSerial, phonebookRecord);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "updateSimPhonebookRecords", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_SIM, "updateSimPhonebookRecords", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -5029,7 +5218,7 @@
             /* @TelephonyManager.UsageSetting */ int usageSetting) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_USAGE_SETTING, result,
                     mRILDefaultWorkSource);
 
@@ -5040,7 +5229,7 @@
             try {
                 networkProxy.setUsageSetting(rr.mSerial, usageSetting);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setUsageSetting", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setUsageSetting", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -5063,7 +5252,7 @@
     public void getUsageSetting(Message result) {
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
         if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_USAGE_SETTING, result,
                     mRILDefaultWorkSource);
 
@@ -5074,7 +5263,7 @@
             try {
                 networkProxy.getUsageSetting(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getUsageSetting", e);
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "getUsageSetting", e);
             }
         } else {
             if (RILJ_LOGD) {
@@ -5088,6 +5277,783 @@
         }
     }
 
+    @Override
+    public void setSrvccCallInfo(SrvccConnection[] srvccConnections, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SRVCC_CALL_INFO, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                // Do not log function arg for privacy
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                imsProxy.setSrvccCallInfo(rr.mSerial,
+                        RILUtils.convertToHalSrvccCall(srvccConnections));
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "setSrvccCallInfo", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "setSrvccCallInfo: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void updateImsRegistrationInfo(
+            @RegistrationManager.ImsRegistrationState int state,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
+            @RegistrationManager.SuggestedAction int suggestedAction,
+            int capabilities, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_UPDATE_IMS_REGISTRATION_INFO, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " state=" + state + ", radioTech=" + imsRadioTech
+                        + ", suggested=" + suggestedAction + ", cap=" + capabilities);
+            }
+
+            android.hardware.radio.ims.ImsRegistration registrationInfo =
+                    new android.hardware.radio.ims.ImsRegistration();
+            registrationInfo.regState = RILUtils.convertImsRegistrationState(state);
+            registrationInfo.accessNetworkType = RILUtils.convertImsRegistrationTech(imsRadioTech);
+            registrationInfo.suggestedAction = suggestedAction;
+            registrationInfo.capabilities = RILUtils.convertImsCapability(capabilities);
+
+            try {
+                imsProxy.updateImsRegistrationInfo(rr.mSerial, registrationInfo);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "updateImsRegistrationInfo", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "updateImsRegistrationInfo: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void startImsTraffic(int token,
+            int trafficType, int accessNetworkType, int trafficDirection, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_START_IMS_TRAFFIC, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + "{" + token + ", " + trafficType + ", "
+                        + accessNetworkType + ", " + trafficDirection + "}");
+            }
+
+            try {
+                imsProxy.startImsTraffic(rr.mSerial, token,
+                        RILUtils.convertImsTrafficType(trafficType), accessNetworkType,
+                        RILUtils.convertImsTrafficDirection(trafficDirection));
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "startImsTraffic", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "startImsTraffic: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void stopImsTraffic(int token, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_STOP_IMS_TRAFFIC, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + "{" + token + "}");
+            }
+
+            try {
+                imsProxy.stopImsTraffic(rr.mSerial, token);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "stopImsTraffic", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "stopImsTraffic: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void triggerEpsFallback(int reason, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_TRIGGER_EPS_FALLBACK, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " reason=" + reason);
+            }
+
+            try {
+                imsProxy.triggerEpsFallback(rr.mSerial, reason);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "triggerEpsFallback", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "triggerEpsFallback: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void sendAnbrQuery(int mediaType, int direction, int bitsPerSecond,
+            Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_ANBR_QUERY, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                imsProxy.sendAnbrQuery(rr.mSerial, mediaType, direction, bitsPerSecond);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "sendAnbrQuery", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "sendAnbrQuery: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setEmergencyMode(int emcMode, Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_EMERGENCY_MODE, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " mode=" + EmergencyConstants.emergencyModeToString(emcMode));
+            }
+
+            try {
+                networkProxy.setEmergencyMode(rr.mSerial, emcMode);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setEmergencyMode", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "setEmergencyMode: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void triggerEmergencyNetworkScan(
+            @NonNull @AccessNetworkConstants.RadioAccessNetworkType int[] accessNetwork,
+            @DomainSelectionService.EmergencyScanType int scanType, Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_TRIGGER_EMERGENCY_NETWORK_SCAN, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " networkType=" + RILUtils.accessNetworkTypesToString(accessNetwork)
+                        + ", scanType=" + RILUtils.scanTypeToString(scanType));
+            }
+
+            try {
+                networkProxy.triggerEmergencyNetworkScan(rr.mSerial,
+                        RILUtils.convertEmergencyNetworkScanTrigger(accessNetwork, scanType));
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "triggerEmergencyNetworkScan", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "triggerEmergencyNetworkScan: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void cancelEmergencyNetworkScan(boolean resetScan, Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_EMERGENCY_NETWORK_SCAN, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " resetScan=" + resetScan);
+            }
+
+            try {
+                networkProxy.cancelEmergencyNetworkScan(rr.mSerial, resetScan);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK,
+                        "cancelEmergencyNetworkScan", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "cancelEmergencyNetworkScan: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void exitEmergencyMode(Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_EXIT_EMERGENCY_MODE, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                networkProxy.exitEmergencyMode(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "exitEmergencyMode", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "exitEmergencyMode: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * Set if null ciphering / null integrity modes are permitted.
+     *
+     * @param result Callback message containing the success or failure status.
+     * @param enabled true if null ciphering / null integrity modes are permitted, false otherwise
+     */
+    @Override
+    public void setNullCipherAndIntegrityEnabled(boolean enabled, Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_NULL_CIPHER_AND_INTEGRITY_ENABLED, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                networkProxy.setNullCipherAndIntegrityEnabled(rr.mSerial, enabled);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(
+                        HAL_SERVICE_NETWORK, "setNullCipherAndIntegrityEnabled", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "setNullCipherAndIntegrityEnabled: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * Get if null ciphering / null integrity are enabled / disabled.
+     *
+     * @param result Callback message containing the success or failure status.
+     */
+    @Override
+    public void isNullCipherAndIntegrityEnabled(Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_ENABLED, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                networkProxy.isNullCipherAndIntegrityEnabled(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(
+                        HAL_SERVICE_NETWORK, "isNullCipherAndIntegrityEnabled", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "isNullCipherAndIntegrityEnabled: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void updateImsCallStatus(@NonNull List<ImsCallInfo> imsCallInfo, Message result) {
+        RadioImsProxy imsProxy = getRadioServiceProxy(RadioImsProxy.class, result);
+        if (imsProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_IMS).greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_UPDATE_IMS_CALL_STATUS, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " " + imsCallInfo);
+            }
+            try {
+                imsProxy.updateImsCallStatus(rr.mSerial, RILUtils.convertImsCallInfo(imsCallInfo));
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_IMS, "updateImsCallStatus", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "updateImsCallStatus: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setN1ModeEnabled(boolean enable, Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_N1_MODE_ENABLED, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " enable=" + enable);
+            }
+
+            try {
+                networkProxy.setN1ModeEnabled(rr.mSerial, enable);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "setN1ModeEnabled", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "setN1ModeEnabled: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void isN1ModeEnabled(Message result) {
+        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
+        if (networkProxy.isEmpty()) return;
+        if (mHalVersion.get(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_IS_N1_MODE_ENABLED, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                networkProxy.isN1ModeEnabled(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(HAL_SERVICE_NETWORK, "isN1ModeEnabled", e);
+            }
+        } else {
+            if (RILJ_LOGD) {
+                Rlog.d(RILJ_LOG_TAG, "isN1ModeEnabled: REQUEST_NOT_SUPPORTED");
+            }
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    /**
+     * Get feature capabilities supported by satellite.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    @Override
+    public void getSatelliteCapabilities(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Turn satellite modem on/off.
+     *
+     * @param result Message that will be sent back to the requester
+     * @param on True for turning on.
+     *           False for turning off.
+     */
+    @Override
+    public void setSatellitePower(Message result, boolean on) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get satellite modem state.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    @Override
+    public void getSatellitePowerState(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get satellite provision state.
+     *
+     * @param result Message that will be sent back to the requester
+     */
+    @Override
+    public void getSatelliteProvisionState(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Provision the subscription with a satellite provider. This is needed to register the
+     * subscription if the provider allows dynamic registration.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param imei IMEI of the SIM associated with the satellite modem.
+     * @param msisdn MSISDN of the SIM associated with the satellite modem.
+     * @param imsi IMSI of the SIM associated with the satellite modem.
+     * @param features List of features to be provisioned.
+     */
+    @Override
+    public void provisionSatelliteService(
+            Message result, String imei, String msisdn, String imsi, int[] features) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Add contacts that are allowed to be used for satellite communication. This is applicable for
+     * incoming messages as well.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param contacts List of allowed contacts to be added.
+     */
+    @Override
+    public void addAllowedSatelliteContacts(Message result, String[] contacts) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Remove contacts that are allowed to be used for satellite communication. This is applicable
+     * for incoming messages as well.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param contacts List of allowed contacts to be removed.
+     */
+    @Override
+    public void removeAllowedSatelliteContacts(Message result, String[] contacts) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Send text messages.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param messages List of messages in text format to be sent.
+     * @param destination The recipient of the message.
+     * @param latitude The current latitude of the device.
+     * @param longitude The current longitude of the device.
+     */
+    @Override
+    public void sendSatelliteMessages(Message result, String[] messages, String destination,
+            double latitude, double longitude) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get pending messages.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void getPendingSatelliteMessages(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get current satellite registration mode.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void getSatelliteMode(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Set the filter for what type of indication framework want to receive from modem.
+     *
+     * @param result Message that will be sent back to the requester.
+     * @param filterBitmask The filter bitmask identifying what type of indication framework want to
+     *                         receive from modem.
+     */
+    @Override
+    public void setSatelliteIndicationFilter(Message result, int filterBitmask) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Check whether satellite modem is supported by the device.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void isSatelliteSupported(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * User started pointing to the satellite. Modem should continue to update the ponting input
+     * as user moves device.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void startSendingSatellitePointingInfo(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Stop pointing to satellite indications.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void stopSendingSatellitePointingInfo(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get max text limit for messaging per message.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void getMaxCharactersPerSatelliteTextMessage(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get whether satellite communication is allowed for the current location
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void isSatelliteCommunicationAllowedForCurrentLocation(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
+    /**
+     * Get time for next visibility of satellite.
+     *
+     * @param result Message that will be sent back to the requester.
+     */
+    @Override
+    public void getTimeForNextSatelliteVisibility(Message result) {
+        // Satellite HAL APIs are not supported before Android V.
+        if (result != null) {
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
+        }
+    }
+
     //***** Private Methods
     /**
      * This is a helper function to be called when an indication callback is called for any radio
@@ -5129,7 +6095,7 @@
      */
     @VisibleForTesting
     public RILRequest processResponse(RadioResponseInfo responseInfo) {
-        return processResponseInternal(RADIO_SERVICE, responseInfo.serial, responseInfo.error,
+        return processResponseInternal(HAL_SERVICE_RADIO, responseInfo.serial, responseInfo.error,
                 responseInfo.type);
     }
 
@@ -5143,7 +6109,7 @@
     @VisibleForTesting
     public RILRequest processResponse_1_6(
             android.hardware.radio.V1_6.RadioResponseInfo responseInfo) {
-        return processResponseInternal(RADIO_SERVICE, responseInfo.serial, responseInfo.error,
+        return processResponseInternal(HAL_SERVICE_RADIO, responseInfo.serial, responseInfo.error,
                 responseInfo.type);
     }
 
@@ -5155,7 +6121,6 @@
      * @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,
@@ -5190,7 +6155,7 @@
                     + " ,error: " + error);
             return null;
         }
-        Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_NETWORK, "RIL", "" /* unused */, rr.mSerial);
+        Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_NETWORK, "RIL", rr.mSerial);
 
         // Time logging for RIL command and storing it in TelephonyHistogram.
         addToRilHistogram(rr);
@@ -5355,13 +6320,13 @@
         RILRequest rr = RILRequest.obtain(RIL_RESPONSE_ACKNOWLEDGEMENT, null,
                 mRILDefaultWorkSource);
         acquireWakeLock(rr, FOR_ACK_WAKELOCK);
-        if (service == RADIO_SERVICE) {
+        if (service == HAL_SERVICE_RADIO) {
             IRadio radioProxy = getRadioProxy(null);
             if (radioProxy != null) {
                 try {
                     radioProxy.responseAcknowledgement();
                 } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(RADIO_SERVICE, "sendAck", e);
+                    handleRadioProxyExceptionForRR(HAL_SERVICE_RADIO, "sendAck", e);
                     riljLoge("sendAck: " + e);
                 }
             } else {
@@ -5506,7 +6471,7 @@
             synchronized (mWakeLock) {
                 if (mWakeLockCount == 0 && !mWakeLock.isHeld()) return false;
                 Rlog.d(RILJ_LOG_TAG, "NOTE: mWakeLockCount is " + mWakeLockCount
-                        + "at time of clearing");
+                        + " at time of clearing");
                 mWakeLockCount = 0;
                 mWakeLock.release();
                 mClientWakelockTracker.stopTrackingAll();
@@ -5679,6 +6644,22 @@
                 sb.append("[").append(hwcfg).append("] ");
             }
             s = sb.toString();
+        } else if (req == RIL_REQUEST_START_IMS_TRAFFIC
+                || req == RIL_UNSOL_CONNECTION_SETUP_FAILURE) {
+            sb = new StringBuilder("{");
+            Object[] info = (Object[]) ret;
+            int token = (Integer) info[0];
+            sb.append(token).append(", ");
+            if (info[1] != null) {
+                ConnectionFailureInfo failureInfo = (ConnectionFailureInfo) info[1];
+                sb.append(failureInfo.getReason()).append(", ");
+                sb.append(failureInfo.getCauseCode()).append(", ");
+                sb.append(failureInfo.getWaitTimeMillis());
+            } else {
+                sb.append("null");
+            }
+            sb.append("}");
+            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
@@ -5856,6 +6837,13 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("RIL: " + this);
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_DATA));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_MESSAGING));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_MODEM));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_NETWORK));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_SIM));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_VOICE));
+        pw.println(" " + mServiceProxies.get(HAL_SERVICE_IMS));
         pw.println(" mWakeLock=" + mWakeLock);
         pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
         synchronized (mRequestList) {
@@ -5931,31 +6919,60 @@
                 new CellSignalStrengthNr());
     }
 
-    /**
-     * Get the HAL version.
-     *
-     * @return the current HalVersion
-     */
-    public HalVersion getHalVersion() {
-        return mRadioVersion;
+    void notifyBarringInfoChanged(@NonNull BarringInfo barringInfo) {
+        mLastBarringInfo = barringInfo;
+        mBarringInfoChangedRegistrants.notifyRegistrants(new AsyncResult(null, barringInfo, null));
     }
 
-    private static String serviceToString(int service) {
+    /**
+     * Get the HAL version with a specific service.
+     *
+     * @param service the hal service id
+     * @return the current HalVersion
+     */
+    public HalVersion getHalVersion(int service) {
+        HalVersion halVersion = mHalVersion.get(service);
+        if (halVersion == null) {
+            if (isRadioServiceSupported(service)) {
+                halVersion = RADIO_HAL_VERSION_UNKNOWN;
+            } else {
+                halVersion = RADIO_HAL_VERSION_UNSUPPORTED;
+            }
+        }
+        return halVersion;
+    }
+
+    /**
+     * Get the HAL version corresponding to the interface version of a IRadioService module.
+     * @param interfaceVersion The interface version, from IRadioService#getInterfaceVersion().
+     * @return The corresponding HalVersion.
+     */
+    public static HalVersion getServiceHalVersion(int interfaceVersion) {
+        switch (interfaceVersion) {
+            case 1: return RADIO_HAL_VERSION_2_0;
+            case 2: return RADIO_HAL_VERSION_2_1;
+            default: return RADIO_HAL_VERSION_UNKNOWN;
+        }
+    }
+
+    private static String serviceToString(@HalService int service) {
         switch (service) {
-            case RADIO_SERVICE:
+            case HAL_SERVICE_RADIO:
                 return "RADIO";
-            case DATA_SERVICE:
+            case HAL_SERVICE_DATA:
                 return "DATA";
-            case MESSAGING_SERVICE:
+            case HAL_SERVICE_MESSAGING:
                 return "MESSAGING";
-            case MODEM_SERVICE:
+            case HAL_SERVICE_MODEM:
                 return "MODEM";
-            case NETWORK_SERVICE:
+            case HAL_SERVICE_NETWORK:
                 return "NETWORK";
-            case SIM_SERVICE:
+            case HAL_SERVICE_SIM:
                 return "SIM";
-            case VOICE_SERVICE:
+            case HAL_SERVICE_VOICE:
                 return "VOICE";
+            case HAL_SERVICE_IMS:
+                return "IMS";
             default:
                 return "UNKNOWN:" + service;
         }
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index 61f1e82..9db186f 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -29,6 +29,7 @@
 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_EMERGENCY_NETWORK_SCAN;
 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;
@@ -58,6 +59,7 @@
 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_DEVICE_IMEI;
 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;
@@ -74,6 +76,7 @@
 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_EXIT_EMERGENCY_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;
@@ -112,7 +115,9 @@
 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_N1_MODE_ENABLED;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_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;
@@ -138,6 +143,7 @@
 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_ANBR_QUERY;
 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;
@@ -154,20 +160,24 @@
 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_EMERGENCY_MODE;
 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_N1_MODE_ENABLED;
 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_NULL_CIPHER_AND_INTEGRITY_ENABLED;
 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_SRVCC_CALL_INFO;
 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;
@@ -185,6 +195,7 @@
 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_IMS_TRAFFIC;
 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;
@@ -194,12 +205,17 @@
 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_IMS_TRAFFIC;
 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_TRIGGER_EMERGENCY_NETWORK_SCAN;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_TRIGGER_EPS_FALLBACK;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UDUB;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_IMS_CALL_STATUS;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_IMS_REGISTRATION_INFO;
 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;
@@ -214,8 +230,10 @@
 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_CONNECTION_SETUP_FAILURE;
 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_NETWORK_SCAN_RESULT;
 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;
@@ -226,6 +244,7 @@
 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_NOTIFY_ANBR;
 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;
@@ -253,6 +272,7 @@
 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_SLICING_CONFIG_CHANGED;
 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;
@@ -260,11 +280,13 @@
 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_TRIGGER_IMS_DEREGISTRATION;
 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.NonNull;
 import android.annotation.Nullable;
 import android.net.InetAddresses;
 import android.net.LinkAddress;
@@ -298,8 +320,11 @@
 import android.telephony.CellSignalStrengthTdscdma;
 import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.ClosedSubscriberGroupInfo;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.ModemInfo;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneCapability;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.PhysicalChannelConfig;
@@ -326,6 +351,12 @@
 import android.telephony.data.RouteSelectionDescriptor;
 import android.telephony.data.TrafficDescriptor;
 import android.telephony.data.UrspRule;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.ConnectionFailureInfo;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.ImsRegistrationImplBase.ImsDeregistrationReason;
+import android.telephony.satellite.SatelliteManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.SparseArray;
@@ -339,6 +370,7 @@
 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.imsphone.ImsCallInfo;
 import com.android.internal.telephony.uicc.AdnCapacity;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccCardStatus;
@@ -346,6 +378,7 @@
 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.PortUtils;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
 import com.android.telephony.Rlog;
 
@@ -1441,8 +1474,9 @@
                     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(), "********");
+                        terminalResponse = terminalResponse.toLowerCase(Locale.ROOT).replace(
+                                IccUtils.bytesToHexString(target).toLowerCase(Locale.ROOT),
+                                "********");
                     }
                     // The text string tag and the length field should also be hidden.
                     from = ctlv.getValueIndex() + ctlv.getLength();
@@ -1660,12 +1694,10 @@
         if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN) != 0) {
             raf |= android.hardware.radio.RadioAccessFamily.IWLAN;
         }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0
+                || (networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 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;
         }
@@ -1801,10 +1833,12 @@
      * @param p2 p2
      * @param p3 p3
      * @param data data
+     * @param radioHalVersion radio hal version
      * @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) {
+            int instruction, int p1, int p2, int p3, String data, boolean isEs10Command,
+            HalVersion radioHalVersion) {
         android.hardware.radio.sim.SimApdu msg = new android.hardware.radio.sim.SimApdu();
         msg.sessionId = channel;
         msg.cla = cla;
@@ -1813,6 +1847,9 @@
         msg.p2 = p2;
         msg.p3 = p3;
         msg.data = convertNullToEmptyString(data);
+        if (radioHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_2_1)) {
+            msg.isEs10 = isEs10Command;
+        }
         return msg;
     }
 
@@ -3256,7 +3293,8 @@
             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);
+                    CellSignalStrengthNr.flip(ss.base.ssRsrq), ss.base.ssSinr,
+                    CellInfo.UNAVAILABLE);
         }
         return null;
     }
@@ -3271,7 +3309,7 @@
         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);
+                CellSignalStrengthNr.flip(ss.ssRsrq), ss.ssSinr, ss.timingAdvance);
     }
 
     private static ClosedSubscriberGroupInfo convertHalClosedSubscriberGroupInfo(
@@ -3835,9 +3873,13 @@
                         convertHalQosBandwidth(eps.uplink), eps.qci);
             case android.hardware.radio.data.Qos.nr:
                 android.hardware.radio.data.NrQos nr = qos.getNr();
+                int averagingWindowMs = nr.averagingWindowMillis;
+                if (averagingWindowMs
+                        == android.hardware.radio.data.NrQos.AVERAGING_WINDOW_UNKNOWN) {
+                    averagingWindowMs = nr.averagingWindowMs;
+                }
                 return new NrQos(convertHalQosBandwidth(nr.downlink),
-                        convertHalQosBandwidth(nr.uplink), nr.qfi, nr.fiveQi,
-                        nr.averagingWindowMs);
+                        convertHalQosBandwidth(nr.uplink), nr.qfi, nr.fiveQi, averagingWindowMs);
             default:
                 return null;
         }
@@ -4331,6 +4373,7 @@
             android.hardware.radio.sim.CardStatus cardStatus) {
         IccCardStatus iccCardStatus = new IccCardStatus();
         iccCardStatus.setCardState(cardStatus.cardState);
+        iccCardStatus.setMultipleEnabledProfilesMode(cardStatus.supportedMepMode);
         iccCardStatus.setUniversalPinState(cardStatus.universalPinState);
         iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus.gsmUmtsSubscriptionAppIndex;
         iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus.cdmaSubscriptionAppIndex;
@@ -4358,7 +4401,9 @@
         }
         IccSlotPortMapping slotPortMapping = new IccSlotPortMapping();
         slotPortMapping.mPhysicalSlotIndex = cardStatus.slotMap.physicalSlotId;
-        slotPortMapping.mPortIndex = cardStatus.slotMap.portId;
+        slotPortMapping.mPortIndex = PortUtils.convertFromHalPortIndex(
+                cardStatus.slotMap.physicalSlotId, cardStatus.slotMap.portId,
+                iccCardStatus.mCardState, iccCardStatus.mSupportedMepMode);
         iccCardStatus.mSlotPortMapping = slotPortMapping;
         return iccCardStatus;
     }
@@ -4474,6 +4519,7 @@
                 }
                 iccSlotStatus.atr = slotStatus.atr;
                 iccSlotStatus.eid = slotStatus.eid;
+                iccSlotStatus.setMultipleEnabledProfilesMode(slotStatus.supportedMepMode);
                 response.add(iccSlotStatus);
             }
             return response;
@@ -4541,7 +4587,8 @@
             int logicalSlotIdx = mapping.getLogicalSlotIndex();
             res[logicalSlotIdx] = new android.hardware.radio.config.SlotPortMapping();
             res[logicalSlotIdx].physicalSlotId = mapping.getPhysicalSlotIndex();
-            res[logicalSlotIdx].portId = mapping.getPortIndex();
+            res[logicalSlotIdx].portId = PortUtils.convertToHalPortIndex(
+                    mapping.getPhysicalSlotIndex(), mapping.getPortIndex());
         }
         return res;
     }
@@ -4566,12 +4613,14 @@
     public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) {
         int maxActiveVoiceCalls = 0;
         int maxActiveData = 0;
+        int maxActiveInternetData = 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;
+            maxActiveInternetData = phoneCapability.maxActiveInternetData;
             validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
             for (int modemId : phoneCapability.logicalModemIds) {
                 logicalModemList.add(new ModemInfo(modemId));
@@ -4580,16 +4629,249 @@
             final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability =
                     (android.hardware.radio.config.V1_1.PhoneCapability) o;
             maxActiveData = phoneCapability.maxActiveData;
+            maxActiveInternetData = phoneCapability.maxActiveInternetData;
             validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
             for (android.hardware.radio.config.V1_1.ModemInfo modemInfo :
                     phoneCapability.logicalModemList) {
                 logicalModemList.add(new ModemInfo(modemInfo.modemId));
             }
         }
+        // maxActiveInternetData defines how many logical modems can have internet PDN connections
+        // simultaneously. For L+L DSDS modem it’s 1, and for DSDA modem it’s 2.
+        maxActiveVoiceCalls = maxActiveInternetData;
         return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
                 validationBeforeSwitchSupported, deviceNrCapabilities);
     }
 
+    /**
+     * Convert network scan type
+     * @param scanType The network scan type
+     * @return The converted EmergencyScanType
+     */
+    public static int convertEmergencyScanType(int scanType) {
+        switch (scanType) {
+            case DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE:
+                return android.hardware.radio.network.EmergencyScanType.LIMITED_SERVICE;
+            case DomainSelectionService.SCAN_TYPE_FULL_SERVICE:
+                return android.hardware.radio.network.EmergencyScanType.FULL_SERVICE;
+            default:
+                return android.hardware.radio.network.EmergencyScanType.NO_PREFERENCE;
+        }
+    }
+
+    /**
+     * Convert to EmergencyNetworkScanTrigger
+     * @param accessNetwork The list of access network types
+     * @param scanType The network scan type
+     * @return The converted EmergencyNetworkScanTrigger
+     */
+    public static android.hardware.radio.network.EmergencyNetworkScanTrigger
+            convertEmergencyNetworkScanTrigger(@NonNull int[] accessNetwork, int scanType) {
+        int[] halAccessNetwork = new int[accessNetwork.length];
+        for (int i = 0; i < accessNetwork.length; i++) {
+            halAccessNetwork[i] = convertToHalAccessNetworkAidl(accessNetwork[i]);
+        }
+
+        android.hardware.radio.network.EmergencyNetworkScanTrigger scanRequest =
+                new android.hardware.radio.network.EmergencyNetworkScanTrigger();
+
+        scanRequest.accessNetwork = halAccessNetwork;
+        scanRequest.scanType = convertEmergencyScanType(scanType);
+        return scanRequest;
+    }
+
+    /**
+     * Convert EmergencyRegResult.aidl to EmergencyRegResult.
+     * @param halResult EmergencyRegResult.aidl in HAL.
+     * @return Converted EmergencyRegResult.
+     */
+    public static EmergencyRegResult convertHalEmergencyRegResult(
+            android.hardware.radio.network.EmergencyRegResult halResult) {
+        return new EmergencyRegResult(
+                halResult.accessNetwork,
+                convertHalRegState(halResult.regState),
+                halResult.emcDomain,
+                halResult.isVopsSupported,
+                halResult.isEmcBearerSupported,
+                halResult.nwProvidedEmc,
+                halResult.nwProvidedEmf,
+                halResult.mcc,
+                halResult.mnc,
+                getCountryCodeForMccMnc(halResult.mcc, halResult.mnc));
+    }
+
+    private static @NonNull String getCountryCodeForMccMnc(
+            @NonNull String mcc, @NonNull String mnc) {
+        if (TextUtils.isEmpty(mcc)) return "";
+        if (TextUtils.isEmpty(mnc)) mnc = "000";
+        String operatorNumeric = TextUtils.concat(mcc, mnc).toString();
+
+        MccTable.MccMnc mccMnc = MccTable.MccMnc.fromOperatorNumeric(operatorNumeric);
+        return MccTable.geoCountryCodeForMccMnc(mccMnc);
+    }
+
+    /**
+     * Convert RegResult.aidl to RegistrationState.
+     * @param halRegState RegResult in HAL.
+     * @return Converted RegistrationState.
+     */
+    public static @NetworkRegistrationInfo.RegistrationState int convertHalRegState(
+            int halRegState) {
+        switch (halRegState) {
+            case android.hardware.radio.network.RegState.NOT_REG_MT_NOT_SEARCHING_OP:
+            case android.hardware.radio.network.RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
+            case android.hardware.radio.network.RegState.REG_HOME:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+            case android.hardware.radio.network.RegState.NOT_REG_MT_SEARCHING_OP:
+            case android.hardware.radio.network.RegState.NOT_REG_MT_SEARCHING_OP_EM:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
+            case android.hardware.radio.network.RegState.REG_DENIED:
+            case android.hardware.radio.network.RegState.REG_DENIED_EM:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_DENIED;
+            case android.hardware.radio.network.RegState.UNKNOWN:
+            case android.hardware.radio.network.RegState.UNKNOWN_EM:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
+            case android.hardware.radio.network.RegState.REG_ROAMING:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
+            default:
+                return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
+        }
+    }
+
+    /** Converts the array of network types to readable String array */
+    public static @NonNull String accessNetworkTypesToString(
+            @NonNull @AccessNetworkConstants.RadioAccessNetworkType int[] accessNetworkTypes) {
+        int length = accessNetworkTypes.length;
+        StringBuilder sb = new StringBuilder("{");
+        if (length > 0) {
+            sb.append(Arrays.stream(accessNetworkTypes)
+                    .mapToObj(RILUtils::accessNetworkTypeToString)
+                    .collect(Collectors.joining(",")));
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static @NonNull String accessNetworkTypeToString(
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType) {
+        switch (accessNetworkType) {
+            case AccessNetworkConstants.AccessNetworkType.UNKNOWN: return "UNKNOWN";
+            case AccessNetworkConstants.AccessNetworkType.GERAN: return "GERAN";
+            case AccessNetworkConstants.AccessNetworkType.UTRAN: return "UTRAN";
+            case AccessNetworkConstants.AccessNetworkType.EUTRAN: return "EUTRAN";
+            case AccessNetworkConstants.AccessNetworkType.CDMA2000: return "CDMA2000";
+            case AccessNetworkConstants.AccessNetworkType.IWLAN: return "IWLAN";
+            case AccessNetworkConstants.AccessNetworkType.NGRAN: return "NGRAN";
+            default: return Integer.toString(accessNetworkType);
+        }
+    }
+
+    /** Converts scan type to readable String */
+    public static @NonNull String scanTypeToString(
+            @DomainSelectionService.EmergencyScanType int scanType) {
+        switch (scanType) {
+            case DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE:
+                return "LIMITED_SERVICE";
+            case DomainSelectionService.SCAN_TYPE_FULL_SERVICE:
+                return "FULL_SERVICE";
+            default:
+                return "NO_PREFERENCE";
+        }
+    }
+
+    /** Convert IMS deregistration reason */
+    public static @ImsDeregistrationReason int convertHalDeregistrationReason(int reason) {
+        switch (reason) {
+            case android.hardware.radio.ims.ImsDeregistrationReason.REASON_SIM_REMOVED:
+                return ImsRegistrationImplBase.REASON_SIM_REMOVED;
+            case android.hardware.radio.ims.ImsDeregistrationReason.REASON_SIM_REFRESH:
+                return ImsRegistrationImplBase.REASON_SIM_REFRESH;
+            case android.hardware.radio.ims.ImsDeregistrationReason
+                    .REASON_ALLOWED_NETWORK_TYPES_CHANGED:
+                return ImsRegistrationImplBase.REASON_ALLOWED_NETWORK_TYPES_CHANGED;
+            default:
+                return ImsRegistrationImplBase.REASON_UNKNOWN;
+        }
+    }
+
+    /**
+     * Convert the IMS traffic type.
+     * @param trafficType IMS traffic type like registration, voice, video, SMS, emergency, and etc.
+     * @return The converted IMS traffic type.
+     */
+    public static int convertImsTrafficType(@MmTelFeature.ImsTrafficType int trafficType) {
+        switch (trafficType) {
+            case MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY:
+                return android.hardware.radio.ims.ImsTrafficType.EMERGENCY;
+            case MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY_SMS:
+                return android.hardware.radio.ims.ImsTrafficType.EMERGENCY_SMS;
+            case MmTelFeature.IMS_TRAFFIC_TYPE_VOICE:
+                return android.hardware.radio.ims.ImsTrafficType.VOICE;
+            case MmTelFeature.IMS_TRAFFIC_TYPE_VIDEO:
+                return android.hardware.radio.ims.ImsTrafficType.VIDEO;
+            case MmTelFeature.IMS_TRAFFIC_TYPE_SMS:
+                return android.hardware.radio.ims.ImsTrafficType.SMS;
+            case MmTelFeature.IMS_TRAFFIC_TYPE_REGISTRATION:
+                return android.hardware.radio.ims.ImsTrafficType.REGISTRATION;
+        }
+        return android.hardware.radio.ims.ImsTrafficType.UT_XCAP;
+    }
+
+    /**
+     * Convert the IMS traffic direction.
+     * @param trafficDirection Indicates the traffic direction.
+     * @return The converted IMS traffic direction.
+     */
+    public static int convertImsTrafficDirection(
+            @MmTelFeature.ImsTrafficDirection int trafficDirection) {
+        switch (trafficDirection) {
+            case MmTelFeature.IMS_TRAFFIC_DIRECTION_INCOMING:
+                return android.hardware.radio.ims.ImsCall.Direction.INCOMING;
+            default:
+                return android.hardware.radio.ims.ImsCall.Direction.OUTGOING;
+        }
+    }
+
+    /**
+     * Convert the IMS connection failure reason.
+     * @param halReason  Specifies the reason that IMS connection failed.
+     * @return The converted IMS connection failure reason.
+     */
+    public static @ConnectionFailureInfo.FailureReason int convertHalConnectionFailureReason(
+            int halReason) {
+        switch (halReason) {
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_ACCESS_DENIED:
+                return ConnectionFailureInfo.REASON_ACCESS_DENIED;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_NAS_FAILURE:
+                return ConnectionFailureInfo.REASON_NAS_FAILURE;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_RACH_FAILURE:
+                return ConnectionFailureInfo.REASON_RACH_FAILURE;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_RLC_FAILURE:
+                return ConnectionFailureInfo.REASON_RLC_FAILURE;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_RRC_REJECT:
+                return ConnectionFailureInfo.REASON_RRC_REJECT;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_RRC_TIMEOUT:
+                return ConnectionFailureInfo.REASON_RRC_TIMEOUT;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_NO_SERVICE:
+                return ConnectionFailureInfo.REASON_NO_SERVICE;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_PDN_NOT_AVAILABLE:
+                return ConnectionFailureInfo.REASON_PDN_NOT_AVAILABLE;
+            case android.hardware.radio.ims.ConnectionFailureInfo
+                    .ConnectionFailureReason.REASON_RF_BUSY:
+                return ConnectionFailureInfo.REASON_RF_BUSY;
+        }
+        return ConnectionFailureInfo.REASON_UNSPECIFIED;
+    }
+
     /** Append the data to the end of an ArrayList */
     public static void appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst) {
         for (byte b : src) {
@@ -4983,6 +5265,9 @@
                 return "GET_SIM_PHONEBOOK_RECORDS";
             case RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD:
                 return "UPDATE_SIM_PHONEBOOK_RECORD";
+            case RIL_REQUEST_DEVICE_IMEI:
+                return "DEVICE_IMEI";
+            /* The following requests are not defined in RIL.h */
             case RIL_REQUEST_GET_SLOT_STATUS:
                 return "GET_SLOT_STATUS";
             case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
@@ -5041,6 +5326,36 @@
                 return "SET_USAGE_SETTING";
             case RIL_REQUEST_GET_USAGE_SETTING:
                 return "GET_USAGE_SETTING";
+            case RIL_REQUEST_SET_EMERGENCY_MODE:
+                return "SET_EMERGENCY_MODE";
+            case RIL_REQUEST_TRIGGER_EMERGENCY_NETWORK_SCAN:
+                return "TRIGGER_EMERGENCY_NETWORK_SCAN";
+            case RIL_REQUEST_CANCEL_EMERGENCY_NETWORK_SCAN:
+                return "CANCEL_EMERGENCY_NETWORK_SCAN";
+            case RIL_REQUEST_EXIT_EMERGENCY_MODE:
+                return "EXIT_EMERGENCY_MODE";
+            case RIL_REQUEST_SET_SRVCC_CALL_INFO:
+                return "SET_SRVCC_CALL_INFO";
+            case RIL_REQUEST_UPDATE_IMS_REGISTRATION_INFO:
+                return "UPDATE_IMS_REGISTRATION_INFO";
+            case RIL_REQUEST_START_IMS_TRAFFIC:
+                return "START_IMS_TRAFFIC";
+            case RIL_REQUEST_STOP_IMS_TRAFFIC:
+                return "STOP_IMS_TRAFFIC";
+            case RIL_REQUEST_SEND_ANBR_QUERY:
+                return "SEND_ANBR_QUERY";
+            case RIL_REQUEST_TRIGGER_EPS_FALLBACK:
+                return "TRIGGER_EPS_FALLBACK";
+            case RIL_REQUEST_SET_NULL_CIPHER_AND_INTEGRITY_ENABLED:
+                return "SET_NULL_CIPHER_AND_INTEGRITY_ENABLED";
+            case RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_ENABLED:
+                return "IS_NULL_CIPHER_AND_INTEGRITY_ENABLED";
+            case RIL_REQUEST_UPDATE_IMS_CALL_STATUS:
+                return "UPDATE_IMS_CALL_STATUS";
+            case RIL_REQUEST_SET_N1_MODE_ENABLED:
+                return "SET_N1_MODE_ENABLED";
+            case RIL_REQUEST_IS_N1_MODE_ENABLED:
+                return "IS_N1_MODE_ENABLED";
             default:
                 return "<unknown request " + request + ">";
         }
@@ -5161,6 +5476,9 @@
                 return "UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED";
             case RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED:
                 return "UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED";
+            case RIL_UNSOL_SLICING_CONFIG_CHANGED:
+                return "UNSOL_SLICING_CONFIG_CHANGED";
+            /* The follow unsols are not defined in RIL.h */
             case RIL_UNSOL_ICC_SLOT_STATUS:
                 return "UNSOL_ICC_SLOT_STATUS";
             case RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG:
@@ -5173,8 +5491,16 @@
                 return "UNSOL_REGISTRATION_FAILED";
             case RIL_UNSOL_BARRING_INFO_CHANGED:
                 return "UNSOL_BARRING_INFO_CHANGED";
+            case RIL_UNSOL_EMERGENCY_NETWORK_SCAN_RESULT:
+                return "UNSOL_EMERGENCY_NETWORK_SCAN_RESULT";
+            case RIL_UNSOL_TRIGGER_IMS_DEREGISTRATION:
+                return "UNSOL_TRIGGER_IMS_DEREGISTRATION";
+            case RIL_UNSOL_CONNECTION_SETUP_FAILURE:
+                return "UNSOL_CONNECTION_SETUP_FAILURE";
+            case RIL_UNSOL_NOTIFY_ANBR:
+                return "UNSOL_NOTIFY_ANBR";
             default:
-                return "<unknown response>";
+                return "<unknown response " + response + ">";
         }
     }
 
@@ -5321,6 +5647,302 @@
         return sb.toString();
     }
 
+    /**
+     * Converts the list of call information for Single Radio Voice Call Continuity(SRVCC).
+     *
+     * @param srvccConnections The list of call information for SRVCC.
+     * @return The converted list of call information.
+     */
+    public static android.hardware.radio.ims.SrvccCall[] convertToHalSrvccCall(
+            SrvccConnection[] srvccConnections) {
+        if (srvccConnections == null) {
+            return new android.hardware.radio.ims.SrvccCall[0];
+        }
+
+        int length = srvccConnections.length;
+        android.hardware.radio.ims.SrvccCall[] srvccCalls =
+                new android.hardware.radio.ims.SrvccCall[length];
+
+        for (int i = 0; i < length; i++) {
+            srvccCalls[i] = new android.hardware.radio.ims.SrvccCall();
+            srvccCalls[i].index = i + 1;
+            srvccCalls[i].callType = convertSrvccCallType(srvccConnections[i].getType());
+            srvccCalls[i].callState = convertCallState(srvccConnections[i].getState());
+            srvccCalls[i].callSubstate =
+                    convertSrvccCallSubState(srvccConnections[i].getSubState());
+            srvccCalls[i].ringbackToneType =
+                    convertSrvccCallRingbackToneType(srvccConnections[i].getRingbackToneType());
+            srvccCalls[i].isMpty = srvccConnections[i].isMultiParty();
+            srvccCalls[i].isMT = srvccConnections[i].isIncoming();
+            srvccCalls[i].number = TextUtils.emptyIfNull(srvccConnections[i].getNumber());
+            srvccCalls[i].numPresentation =
+                    convertPresentation(srvccConnections[i].getNumberPresentation());
+            srvccCalls[i].name = TextUtils.emptyIfNull(srvccConnections[i].getName());
+            srvccCalls[i].namePresentation =
+                    convertPresentation(srvccConnections[i].getNamePresentation());
+        }
+
+        return srvccCalls;
+    }
+
+    /**
+     * Converts the call type.
+     *
+     * @param type The call type.
+     * @return The converted call type.
+     */
+    public static int convertSrvccCallType(int type) {
+        switch (type) {
+            case  SrvccConnection.CALL_TYPE_NORMAL:
+                return android.hardware.radio.ims.SrvccCall.CallType.NORMAL;
+            case  SrvccConnection.CALL_TYPE_EMERGENCY:
+                return android.hardware.radio.ims.SrvccCall.CallType.EMERGENCY;
+            default:
+                throw new RuntimeException("illegal call type " + type);
+        }
+    }
+
+    /**
+     * Converts the call state.
+     *
+     * @param state The call state.
+     * @return The converted call state.
+     */
+    public static int convertCallState(Call.State state) {
+        switch (state) {
+            case ACTIVE: return android.hardware.radio.voice.Call.STATE_ACTIVE;
+            case HOLDING: return android.hardware.radio.voice.Call.STATE_HOLDING;
+            case DIALING: return android.hardware.radio.voice.Call.STATE_DIALING;
+            case ALERTING: return android.hardware.radio.voice.Call.STATE_ALERTING;
+            case INCOMING: return android.hardware.radio.voice.Call.STATE_INCOMING;
+            case WAITING: return android.hardware.radio.voice.Call.STATE_WAITING;
+            default:
+                throw new RuntimeException("illegal state " + state);
+        }
+    }
+
+    /**
+     * Converts the substate of a call.
+     *
+     * @param state The substate of a call.
+     * @return The converted substate.
+     */
+    public static int convertSrvccCallSubState(int state) {
+        switch (state) {
+            case SrvccConnection.SUBSTATE_NONE:
+                return android.hardware.radio.ims.SrvccCall.CallSubState.NONE;
+            case SrvccConnection.SUBSTATE_PREALERTING:
+                return android.hardware.radio.ims.SrvccCall.CallSubState.PREALERTING;
+            default:
+                throw new RuntimeException("illegal substate " + state);
+        }
+    }
+
+    /**
+     * Converts the ringback tone type.
+     *
+     * @param type The ringback tone type.
+     * @return The converted ringback tone type.
+     */
+    public static int convertSrvccCallRingbackToneType(int type) {
+        switch (type) {
+            case SrvccConnection.TONE_NONE:
+                return android.hardware.radio.ims.SrvccCall.ToneType.NONE;
+            case SrvccConnection.TONE_LOCAL:
+                return android.hardware.radio.ims.SrvccCall.ToneType.LOCAL;
+            case SrvccConnection.TONE_NETWORK:
+                return android.hardware.radio.ims.SrvccCall.ToneType.NETWORK;
+            default:
+                throw new RuntimeException("illegal ringback tone type " + type);
+        }
+    }
+
+    /**
+     * Converts the number presentation type for caller id display.
+     *
+     * @param presentation The number presentation type.
+     * @return The converted presentation type.
+     */
+    public static int convertPresentation(int presentation) {
+        switch (presentation) {
+            case PhoneConstants.PRESENTATION_ALLOWED:
+                return android.hardware.radio.voice.Call.PRESENTATION_ALLOWED;
+            case PhoneConstants.PRESENTATION_RESTRICTED:
+                return android.hardware.radio.voice.Call.PRESENTATION_RESTRICTED;
+            case PhoneConstants.PRESENTATION_UNKNOWN:
+                return android.hardware.radio.voice.Call.PRESENTATION_UNKNOWN;
+            case PhoneConstants.PRESENTATION_PAYPHONE:
+                return android.hardware.radio.voice.Call.PRESENTATION_PAYPHONE;
+            default:
+                throw new RuntimeException("illegal presentation " + presentation);
+        }
+    }
+
+    /**
+     * Converts IMS registration state.
+     *
+     * @param state The IMS registration state.
+     * @return The converted HAL IMS registration state.
+     */
+    public static int convertImsRegistrationState(int state) {
+        switch (state) {
+            case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED:
+                return android.hardware.radio.ims.ImsRegistrationState.NOT_REGISTERED;
+            case RegistrationManager.REGISTRATION_STATE_REGISTERED:
+                return android.hardware.radio.ims.ImsRegistrationState.REGISTERED;
+            default:
+                throw new RuntimeException("illegal state " + state);
+        }
+    }
+
+    /**
+     * Converts IMS service radio technology.
+     *
+     * @param imsRadioTech The IMS service radio technology.
+     * @return The converted HAL access network type.
+     */
+
+    public static int convertImsRegistrationTech(
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+        switch (imsRadioTech) {
+            case ImsRegistrationImplBase.REGISTRATION_TECH_LTE:
+                return android.hardware.radio.AccessNetwork.EUTRAN;
+            case ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN:
+                return android.hardware.radio.AccessNetwork.IWLAN;
+            case ImsRegistrationImplBase.REGISTRATION_TECH_NR:
+                return android.hardware.radio.AccessNetwork.NGRAN;
+            case ImsRegistrationImplBase.REGISTRATION_TECH_3G:
+                return android.hardware.radio.AccessNetwork.UTRAN;
+            default:
+                return android.hardware.radio.AccessNetwork.UNKNOWN;
+        }
+    }
+
+    /**
+     * Converts IMS capabilities.
+     *
+     * @param capabilities The IMS capabilities.
+     * @return The converted HAL IMS capabilities.
+     */
+    public static int convertImsCapability(int capabilities) {
+        int halCapabilities = android.hardware.radio.ims.ImsRegistration.IMS_MMTEL_CAPABILITY_NONE;
+        if ((capabilities & CommandsInterface.IMS_MMTEL_CAPABILITY_VOICE) > 0) {
+            halCapabilities |=
+                    android.hardware.radio.ims.ImsRegistration.IMS_MMTEL_CAPABILITY_VOICE;
+        }
+        if ((capabilities & CommandsInterface.IMS_MMTEL_CAPABILITY_VIDEO) > 0) {
+            halCapabilities |=
+                    android.hardware.radio.ims.ImsRegistration.IMS_MMTEL_CAPABILITY_VIDEO;
+        }
+        if ((capabilities & CommandsInterface.IMS_MMTEL_CAPABILITY_SMS) > 0) {
+            halCapabilities |= android.hardware.radio.ims.ImsRegistration.IMS_MMTEL_CAPABILITY_SMS;
+        }
+        if ((capabilities & CommandsInterface.IMS_RCS_CAPABILITIES) > 0) {
+            halCapabilities |= android.hardware.radio.ims.ImsRegistration.IMS_RCS_CAPABILITIES;
+        }
+        return halCapabilities;
+    }
+
+    /** Converts the ImsCallInfo instances to HAL ImsCall instances. */
+    public static android.hardware.radio.ims.ImsCall[] convertImsCallInfo(
+            List<ImsCallInfo> imsCallInfos) {
+        if (imsCallInfos == null) {
+            return new android.hardware.radio.ims.ImsCall[0];
+        }
+
+        int length = 0;
+        for (int i = 0; i < imsCallInfos.size(); i++) {
+            if (imsCallInfos.get(i) != null) length++;
+        }
+        if (length == 0) {
+            return new android.hardware.radio.ims.ImsCall[0];
+        }
+
+        android.hardware.radio.ims.ImsCall[] halInfos =
+                new android.hardware.radio.ims.ImsCall[length];
+
+        int index = 0;
+        for (int i = 0; i < imsCallInfos.size(); i++) {
+            ImsCallInfo info = imsCallInfos.get(i);
+            if (info == null) continue;
+
+            halInfos[index] = new android.hardware.radio.ims.ImsCall();
+            halInfos[index].index = info.getIndex();
+            halInfos[index].callState = convertToHalImsCallState(info.getCallState());
+            halInfos[index].callType = info.isEmergencyCall()
+                    ? android.hardware.radio.ims.ImsCall.CallType.EMERGENCY
+                    : android.hardware.radio.ims.ImsCall.CallType.NORMAL;
+            halInfos[index].accessNetwork = convertToHalAccessNetworkAidl(info.getCallRadioTech());
+            halInfos[index].direction = info.isIncoming()
+                    ? android.hardware.radio.ims.ImsCall.Direction.INCOMING
+                    : android.hardware.radio.ims.ImsCall.Direction.OUTGOING;
+            halInfos[index].isHeldByRemote = info.isHeldByRemote();
+            index++;
+        }
+
+        return halInfos;
+    }
+
+    /**
+     * Convert satellite-related errors from CommandException.Error to
+     * SatelliteManager.SatelliteServiceResult.
+     * @param error The satellite error.
+     * @return The converted SatelliteServiceResult.
+     */
+    @SatelliteManager.SatelliteError
+    public static int convertToSatelliteError(
+            CommandException.Error error) {
+        switch (error) {
+            case INTERNAL_ERR:
+                //fallthrough to SYSTEM_ERR
+            case MODEM_ERR:
+                //fallthrough to SYSTEM_ERR
+            case SYSTEM_ERR:
+                return SatelliteManager.SATELLITE_MODEM_ERROR;
+            case INVALID_ARGUMENTS:
+                return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
+            case INVALID_MODEM_STATE:
+                return SatelliteManager.SATELLITE_INVALID_MODEM_STATE;
+            case RADIO_NOT_AVAILABLE:
+                return SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE;
+            case REQUEST_NOT_SUPPORTED:
+                return SatelliteManager.SATELLITE_REQUEST_NOT_SUPPORTED;
+            case NO_MEMORY:
+                //fallthrough to NO_RESOURCES
+            case NO_RESOURCES:
+                return SatelliteManager.SATELLITE_NO_RESOURCES;
+            case NETWORK_ERR:
+                return SatelliteManager.SATELLITE_NETWORK_ERROR;
+            case NO_NETWORK_FOUND:
+                return SatelliteManager.SATELLITE_NOT_REACHABLE;
+            case ABORTED:
+                return SatelliteManager.SATELLITE_REQUEST_ABORTED;
+            case ACCESS_BARRED:
+                return SatelliteManager.SATELLITE_ACCESS_BARRED;
+            default:
+                return SatelliteManager.SATELLITE_ERROR;
+        }
+    }
+
+    /**
+     * Converts the call state to HAL IMS call state.
+     *
+     * @param state The {@link Call.State}.
+     * @return The converted {@link android.hardware.radio.ims.ImsCall.CallState}.
+     */
+    private static int convertToHalImsCallState(Call.State state) {
+        switch (state) {
+            case ACTIVE: return android.hardware.radio.ims.ImsCall.CallState.ACTIVE;
+            case HOLDING: return android.hardware.radio.ims.ImsCall.CallState.HOLDING;
+            case DIALING: return android.hardware.radio.ims.ImsCall.CallState.DIALING;
+            case ALERTING: return android.hardware.radio.ims.ImsCall.CallState.ALERTING;
+            case INCOMING: return android.hardware.radio.ims.ImsCall.CallState.INCOMING;
+            case WAITING: return android.hardware.radio.ims.ImsCall.CallState.WAITING;
+            case DISCONNECTING: return android.hardware.radio.ims.ImsCall.CallState.DISCONNECTING;
+            default: return android.hardware.radio.ims.ImsCall.CallState.DISCONNECTED;
+        }
+    }
+
     private static void logd(String log) {
         Rlog.d("RILUtils", log);
     }
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index e455ecb..3e2be1d 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -358,7 +358,7 @@
 
             if (rr != null) {
                 Trace.asyncTraceForTrackEnd(
-                        Trace.TRACE_TAG_NETWORK, "RIL", "" /* unused */, rr.mSerial);
+                        Trace.TRACE_TAG_NETWORK, "RIL", rr.mSerial);
                 mRequestList.remove(serial);
             }
         }
@@ -642,4 +642,9 @@
     private static void loge(String log) {
         Rlog.e(TAG, log);
     }
+
+    @Override
+    public String toString() {
+        return "RadioConfig[" + "mRadioConfigProxy=" + mRadioConfigProxy + ']';
+    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioConfigProxy.java b/src/java/com/android/internal/telephony/RadioConfigProxy.java
index a8601f1..edeb558 100644
--- a/src/java/com/android/internal/telephony/RadioConfigProxy.java
+++ b/src/java/com/android/internal/telephony/RadioConfigProxy.java
@@ -336,4 +336,11 @@
                     mRadioConfig.obtainMessage(RadioConfig.EVENT_AIDL_SERVICE_DEAD));
         }
     }
+
+    @Override
+    public String toString() {
+        return "RadioConfigProxy["
+                + "mRadioHalVersion=" + mRadioHalVersion
+                + ", mRadioConfigHalVersion=" + mRadioConfigHalVersion + ']';
+    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioDataProxy.java b/src/java/com/android/internal/telephony/RadioDataProxy.java
index cbc762a..9671077 100644
--- a/src/java/com/android/internal/telephony/RadioDataProxy.java
+++ b/src/java/com/android/internal/telephony/RadioDataProxy.java
@@ -45,12 +45,22 @@
      * Set IRadioData as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param data IRadioData implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.data.IRadioData data) {
-        mHalVersion = halVersion;
+    public HalVersion setAidl(HalVersion halVersion, android.hardware.radio.data.IRadioData data) {
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(data.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mDataProxy = data;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/RadioImsProxy.java b/src/java/com/android/internal/telephony/RadioImsProxy.java
new file mode 100644
index 0000000..cde2e06
--- /dev/null
+++ b/src/java/com/android/internal/telephony/RadioImsProxy.java
@@ -0,0 +1,194 @@
+/*
+ * 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;
+
+import android.os.RemoteException;
+import android.telephony.Rlog;
+
+/**
+ * A holder for IRadioIms.
+ * Use getAidl to get IRadioIms and call the AIDL implementations of the HAL APIs.
+ */
+public class RadioImsProxy extends RadioServiceProxy {
+    private static final String TAG = "RadioImsProxy";
+    private volatile android.hardware.radio.ims.IRadioIms mImsProxy = null;
+
+    /**
+     * Sets IRadioIms as the AIDL implementation for RadioServiceProxy.
+     * @param halVersion Radio HAL version.
+     * @param ims IRadioIms implementation.
+     *
+     * @return updated HAL version.
+     */
+    public HalVersion setAidl(HalVersion halVersion, android.hardware.radio.ims.IRadioIms ims) {
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(ims.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
+        mImsProxy = ims;
+        mIsAidl = true;
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
+    }
+
+    /**
+     * Gets the AIDL implementation of RadioImsProxy.
+     * @return IRadioIms implementation.
+     */
+    public android.hardware.radio.ims.IRadioIms getAidl() {
+        return mImsProxy;
+    }
+
+    /**
+     * Resets RadioImsProxy.
+     */
+    @Override
+    public void clear() {
+        super.clear();
+        mImsProxy = null;
+    }
+
+    /**
+     * Checks whether a RadioIms implementation exists.
+     * @return true if there is neither a HIDL nor AIDL implementation.
+     */
+    @Override
+    public boolean isEmpty() {
+        return mRadioProxy == null && mImsProxy == null;
+    }
+
+    /**
+     * No implementation in IRadioIms.
+     * @throws RemoteException.
+     */
+    @Override
+    public void responseAcknowledgement() throws RemoteException {
+        /* Currently, IRadioIms doesn't support the following response types:
+         * - RadioIndicationType.UNSOLICITED_ACK_EXP
+         * - RadioResponseType.SOLICITED_ACK_EXP */
+        // no-op
+    }
+
+    /**
+     * Calls IRadioIms#setSrvccCallInfo.
+     * @param serial Serial number of request.
+     * @param srvccCalls The list of call information.
+     * @throws RemoteException.
+     */
+    public void setSrvccCallInfo(int serial,
+            android.hardware.radio.ims.SrvccCall[] srvccCalls) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.setSrvccCallInfo(serial, srvccCalls);
+        }
+    }
+
+    /**
+     * Calls IRadioIms#updateImsRegistrationInfo.
+     * @param serial Serial number of request.
+     * @param registrationInfo The registration state information.
+     * @throws RemoteException.
+     */
+    public void updateImsRegistrationInfo(int serial,
+            android.hardware.radio.ims.ImsRegistration registrationInfo) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.updateImsRegistrationInfo(serial, registrationInfo);
+        }
+    }
+
+    /**
+     * Calls IRadioIms#startImsTraffic.
+     * @param serial Serial number of request.
+     * @param token A nonce to identify the request.
+     * @param trafficType IMS traffic type like registration, voice, video, SMS, emergency, and etc.
+     * @param accessNetworkType The type of underlying radio access network used.
+     * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+     *        mobile terminated use case eg. MO/MT call/SMS etc.
+     * @throws RemoteException.
+     */
+    public void startImsTraffic(int serial, int token, int trafficType, int accessNetworkType,
+            int trafficDirection) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.startImsTraffic(serial,
+                    token, trafficType, accessNetworkType, trafficDirection);
+        }
+    }
+
+    /**
+     * Calls IRadioIms#stopImsTraffic.
+     * @param serial Serial number of request.
+     * @param token The token assigned by startImsTraffic.
+     * @throws RemoteException.
+     */
+    public void stopImsTraffic(int serial, int token)
+            throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.stopImsTraffic(serial, token);
+        }
+    }
+
+    /**
+     * Calls IRadioIms#triggerEpsFallback.
+     * @param serial Serial number of request.
+     * @param reason Specifies the reason for EPS fallback.
+     * @throws RemoteException.
+     */
+    public void triggerEpsFallback(int serial, int reason)
+            throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.triggerEpsFallback(serial, reason);
+        }
+    }
+
+    /**
+     * Calls IRadioIms#sendAnbrQuery.
+     * @param serial Serial number of request.
+     * @param mediaType Media type is used to identify media stream such as audio or video.
+     * @param direction Direction of this packet stream (e.g. uplink or downlink).
+     * @param bitsPerSecond The bit rate requested by the opponent UE.
+     * @throws RemoteException.
+     */
+    public void sendAnbrQuery(int serial, int mediaType, int direction, int bitsPerSecond)
+            throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.sendAnbrQuery(serial, mediaType, direction, bitsPerSecond);
+        }
+    }
+
+    /**
+     * Call IRadioIms#updateImsCallStatus
+     * @param serial Serial number of request.
+     * @param imsCalls The list of call status information.
+     * @throws RemoteException.
+     */
+    public void updateImsCallStatus(int serial,
+            android.hardware.radio.ims.ImsCall[] imsCalls) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mImsProxy.updateImsCallStatus(serial, imsCalls);
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index d947d53..4f75412 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
+import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
 
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION;
@@ -136,7 +136,7 @@
      * @param radioState android.hardware.radio.V1_0.RadioState
      */
     public void radioStateChanged(int indicationType, int radioState) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int state = RILUtils.convertHalRadioState(radioState);
         if (mRil.isLogOrTrace()) {
@@ -148,7 +148,7 @@
     }
 
     public void callStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
 
@@ -160,7 +160,7 @@
      * @param indicationType RadioIndicationType
      */
     public void networkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED);
 
@@ -168,7 +168,7 @@
     }
 
     public void newSms(int indicationType, ArrayList<Byte> pdu) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         byte[] pduArray = RILUtils.arrayListToPrimitiveArray(pdu);
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
@@ -181,7 +181,7 @@
     }
 
     public void newSmsStatusReport(int indicationType, ArrayList<Byte> pdu) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         byte[] pduArray = RILUtils.arrayListToPrimitiveArray(pdu);
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT);
@@ -192,7 +192,7 @@
     }
 
     public void newSmsOnSim(int indicationType, int recordNumber) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM);
 
@@ -202,7 +202,7 @@
     }
 
     public void onUssd(int indicationType, int ussdModeType, String msg) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
 
@@ -216,7 +216,7 @@
     }
 
     public void nitzTimeReceived(int indicationType, String nitzTime, long receivedTime) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
 
@@ -241,7 +241,7 @@
 
     public void currentSignalStrength(int indicationType,
                                       android.hardware.radio.V1_0.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         SignalStrength ssInitial = RILUtils.convertHalSignalStrength(signalStrength);
 
@@ -259,7 +259,7 @@
      */
     public void currentLinkCapacityEstimate(int indicationType,
                                             android.hardware.radio.V1_2.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
 
@@ -275,7 +275,7 @@
      */
     public void currentLinkCapacityEstimate_1_6(int indicationType,
             android.hardware.radio.V1_6.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
 
@@ -291,7 +291,7 @@
      */
     public void currentSignalStrength_1_2(int indicationType,
                                       android.hardware.radio.V1_2.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
         // Note this is set to "verbose" because it happens frequently
@@ -308,7 +308,7 @@
     public void currentSignalStrength_1_4(int indicationType,
             android.hardware.radio.V1_4.SignalStrength signalStrength) {
 
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
 
@@ -325,7 +325,7 @@
     public void currentSignalStrength_1_6(int indicationType,
             android.hardware.radio.V1_6.SignalStrength signalStrength) {
 
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
 
@@ -341,7 +341,7 @@
      */
     public void currentPhysicalChannelConfigs_1_4(int indicationType,
             ArrayList<android.hardware.radio.V1_4.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -350,7 +350,7 @@
      */
     public void currentPhysicalChannelConfigs_1_6(int indicationType,
             ArrayList<android.hardware.radio.V1_6.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -359,7 +359,7 @@
      */
     public void currentPhysicalChannelConfigs(int indicationType,
             ArrayList<android.hardware.radio.V1_2.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -368,7 +368,7 @@
      */
     public void currentEmergencyNumberList(int indicationType,
             ArrayList<android.hardware.radio.V1_4.EmergencyNumber> emergencyNumberList) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.size());
 
         for (android.hardware.radio.V1_4.EmergencyNumber emergencyNumberHal
@@ -422,7 +422,7 @@
     }
 
     public void suppSvcNotify(int indicationType, SuppSvcNotification suppSvcNotification) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         SuppServiceNotification notification = new SuppServiceNotification();
         notification.notificationType = suppSvcNotification.isMT ? 1 : 0;
@@ -441,7 +441,7 @@
     }
 
     public void stkSessionEnd(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_SESSION_END);
 
@@ -451,7 +451,7 @@
     }
 
     public void stkProactiveCommand(int indicationType, String cmd) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_PROACTIVE_COMMAND);
 
@@ -461,7 +461,7 @@
     }
 
     public void stkEventNotify(int indicationType, String cmd) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_EVENT_NOTIFY);
 
@@ -471,7 +471,7 @@
     }
 
     public void stkCallSetup(int indicationType, long timeout) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
 
@@ -481,7 +481,7 @@
     }
 
     public void simSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_SIM_SMS_STORAGE_FULL);
 
@@ -491,7 +491,7 @@
     }
 
     public void simRefresh(int indicationType, SimRefreshResult refreshResult) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         IccRefreshResponse response = new IccRefreshResponse();
         response.refreshResult = refreshResult.type;
@@ -504,7 +504,7 @@
     }
 
     public void callRing(int indicationType, boolean isGsm, CdmaSignalInfoRecord record) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         char response[] = null;
 
@@ -527,7 +527,7 @@
     }
 
     public void simStatusChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
 
@@ -535,7 +535,7 @@
     }
 
     public void cdmaNewSms(int indicationType, CdmaSmsMessage msg) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);
 
@@ -546,7 +546,7 @@
     }
 
     public void newBroadcastSms(int indicationType, ArrayList<Byte> data) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         byte[] response = RILUtils.arrayListToPrimitiveArray(data);
         if (mRil.isLogOrTrace()) {
@@ -560,7 +560,7 @@
     }
 
     public void cdmaRuimSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL);
 
@@ -570,7 +570,7 @@
     }
 
     public void restrictedStateChanged(int indicationType, int state) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogvRet(RIL_UNSOL_RESTRICTED_STATE_CHANGED, state);
 
@@ -580,7 +580,7 @@
     }
 
     public void enterEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
 
@@ -590,7 +590,7 @@
     }
 
     public void cdmaCallWaiting(int indicationType, CdmaCallWaiting callWaitingRecord) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         // todo: create a CdmaCallWaitingNotification constructor that takes in these fields to make
         // sure no fields are missing
@@ -614,7 +614,7 @@
     }
 
     public void cdmaOtaProvisionStatus(int indicationType, int status) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = status;
@@ -628,7 +628,7 @@
 
     public void cdmaInfoRec(int indicationType,
                             android.hardware.radio.V1_0.CdmaInformationRecords records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int numberOfInfoRecs = records.infoRec.size();
         for (int i = 0; i < numberOfInfoRecs; i++) {
@@ -724,7 +724,7 @@
     }
 
     public void indicateRingbackTone(int indicationType, boolean start) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
 
@@ -732,7 +732,7 @@
     }
 
     public void resendIncallMute(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
 
@@ -740,7 +740,7 @@
     }
 
     public void cdmaSubscriptionSourceChanged(int indicationType, int cdmaSource) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = cdmaSource;
@@ -754,7 +754,7 @@
     }
 
     public void cdmaPrlChanged(int indicationType, int version) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = version;
@@ -766,7 +766,7 @@
     }
 
     public void exitEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
 
@@ -774,7 +774,7 @@
     }
 
     public void rilConnected(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RIL_CONNECTED);
 
@@ -787,7 +787,7 @@
     }
 
     public void voiceRadioTechChanged(int indicationType, int rat) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = rat;
@@ -803,35 +803,35 @@
     /** Get unsolicited message for cellInfoList */
     public void cellInfoList(int indicationType,
             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         responseCellInfoList(records);
     }
 
     /** 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);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         responseCellInfoList(records);
     }
 
     /** 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);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         responseCellInfoList(records);
     }
 
     /** 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);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         responseCellInfoList(records);
     }
 
     /** 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);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         responseCellInfoList(records);
     }
 
@@ -843,7 +843,7 @@
 
     /** Get unsolicited message for uicc applications enablement changes. */
     public void uiccApplicationsEnablementChanged(int indicationType, boolean enabled) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED, enabled);
@@ -883,7 +883,7 @@
     }
 
     public void imsNetworkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED);
 
@@ -891,7 +891,7 @@
     }
 
     public void subscriptionStatusChanged(int indicationType, boolean activate) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = activate ? 1 : 0;
@@ -905,7 +905,7 @@
     }
 
     public void srvccStateNotify(int indicationType, int state) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int response[] = new int[1];
         response[0] = state;
@@ -921,7 +921,7 @@
     public void hardwareConfigChanged(
             int indicationType,
             ArrayList<android.hardware.radio.V1_0.HardwareConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<HardwareConfig> response = RILUtils.convertHalHardwareConfigList(configs);
 
@@ -933,7 +933,7 @@
 
     public void radioCapabilityIndication(int indicationType,
                                           android.hardware.radio.V1_0.RadioCapability rc) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         RadioCapability response = RILUtils.convertHalRadioCapability(rc, mRil);
 
@@ -944,7 +944,7 @@
     }
 
     public void onSupplementaryServiceIndication(int indicationType, StkCcUnsolSsResult ss) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         int num;
         SsData ssData = new SsData();
@@ -992,7 +992,7 @@
     }
 
     public void stkCallControlAlphaNotify(int indicationType, String alpha) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
 
@@ -1002,7 +1002,7 @@
     }
 
     public void lceData(int indicationType, LceDataInfo lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
 
@@ -1014,7 +1014,7 @@
     }
 
     public void pcoData(int indicationType, PcoDataInfo pco) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         PcoData response = new PcoData(pco.cid, pco.bearerProto, pco.pcoId,
                 RILUtils.arrayListToPrimitiveArray(pco.contents));
@@ -1025,7 +1025,7 @@
     }
 
     public void modemReset(int indicationType, String reason) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_MODEM_RESTART, reason);
 
@@ -1038,7 +1038,7 @@
      * @param indicationType RadioIndicationType
      */
     public void carrierInfoForImsiEncryption(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, null);
@@ -1055,7 +1055,7 @@
      */
     public void keepaliveStatus(
             int indicationType, android.hardware.radio.V1_1.KeepaliveStatus halStatus) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(
@@ -1074,7 +1074,7 @@
      * @param indicationType RadioIndicationType
      */
     public void simPhonebookChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED);
@@ -1091,7 +1091,7 @@
      */
     public void simPhonebookRecordsReceived(int indicationType, byte status,
             ArrayList<PhonebookRecordInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         List<SimPhonebookRecord> simPhonebookRecords = new ArrayList<>();
 
@@ -1124,7 +1124,7 @@
             android.hardware.radio.V1_5.CellIdentity cellIdentity, String chosenPlmn,
             @NetworkRegistrationInfo.Domain int domain,
             int causeCode, int additionalCauseCode) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
         CellIdentity ci = RILUtils.convertHalCellIdentity(cellIdentity);
         if (ci == null
                 || TextUtils.isEmpty(chosenPlmn)
@@ -1132,7 +1132,7 @@
                 || (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");
 
@@ -1155,10 +1155,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(HAL_SERVICE_RADIO, indicationType);
 
         if (cellIdentity == null || barringInfos == null) {
-            reportAnomaly(
+            AnomalyReporter.reportAnomaly(
                     UUID.fromString("645b16bb-c930-4c1c-9c5d-568696542e05"),
                             "Invalid barringInfoChanged indication");
 
@@ -1224,22 +1224,29 @@
                     android.hardware.radio.V1_6.PhysicalChannelConfig config =
                             (android.hardware.radio.V1_6.PhysicalChannelConfig) obj;
                     PhysicalChannelConfig.Builder builder = new PhysicalChannelConfig.Builder();
+                    int band = PhysicalChannelConfig.BAND_UNKNOWN;
                     switch (config.band.getDiscriminator()) {
                         case Band.hidl_discriminator.geranBand:
-                            builder.setBand(config.band.geranBand());
+                            band = config.band.geranBand();
                             break;
                         case Band.hidl_discriminator.utranBand:
-                            builder.setBand(config.band.utranBand());
+                            band = config.band.utranBand();
                             break;
                         case Band.hidl_discriminator.eutranBand:
-                            builder.setBand(config.band.eutranBand());
+                            band = config.band.eutranBand();
                             break;
                         case Band.hidl_discriminator.ngranBand:
-                            builder.setBand(config.band.ngranBand());
+                            band = config.band.ngranBand();
                             break;
                         default:
                             mRil.riljLoge("Unsupported band " + config.band.getDiscriminator());
                     }
+                    if (band == PhysicalChannelConfig.BAND_UNKNOWN) {
+                        mRil.riljLoge("Unsupported unknown band.");
+                        return;
+                    } else {
+                        builder.setBand(band);
+                    }
                     response.add(builder.setCellConnectionStatus(
                             RILUtils.convertHalCellConnectionStatus(config.status))
                             .setDownlinkChannelNumber(config.downlinkChannelNumber)
@@ -1256,8 +1263,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"),
+                            "RIL reported invalid PCC (HIDL)");
             mRil.riljLoge("Invalid PhysicalChannelConfig " + iae);
             return;
         }
@@ -1270,7 +1278,7 @@
 
     private void responseNetworkScan(int indicationType,
             android.hardware.radio.V1_1.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<CellInfo> cellInfos =
                 RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
@@ -1281,7 +1289,7 @@
 
     private void responseNetworkScan_1_2(int indicationType,
             android.hardware.radio.V1_2.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<CellInfo> cellInfos =
                 RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
@@ -1292,7 +1300,7 @@
 
     private void responseNetworkScan_1_4(int indicationType,
             android.hardware.radio.V1_4.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<CellInfo> cellInfos =
                 RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
@@ -1303,7 +1311,7 @@
 
     private void responseNetworkScan_1_5(int indicationType,
             android.hardware.radio.V1_5.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<CellInfo> cellInfos =
                 RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
@@ -1314,7 +1322,7 @@
 
     private void responseNetworkScan_1_6(int indicationType,
             android.hardware.radio.V1_6.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         ArrayList<CellInfo> cellInfos =
                 RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
@@ -1324,7 +1332,7 @@
     }
 
     private void responseDataCallListChanged(int indicationType, List<?> dcList) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, dcList);
 
@@ -1334,17 +1342,11 @@
     }
 
     private void responseApnUnthrottled(int indicationType, String apn) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_RADIO, indicationType);
 
         if (mRil.isLogOrTrace()) 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..bab4d12 100644
--- a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
+++ b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
@@ -28,6 +28,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.telephony.Rlog;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.Set;
 
@@ -164,6 +166,13 @@
         }
     }
 
+    /**
+     * Dump the fields of the instance
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("mRadioConfig=" + mRadioConfig);
+    }
+
     private static void log(final String s) {
         Rlog.d(LOG_TAG, s);
     }
diff --git a/src/java/com/android/internal/telephony/RadioMessagingProxy.java b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
index e68e957..69ccf36 100644
--- a/src/java/com/android/internal/telephony/RadioMessagingProxy.java
+++ b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
@@ -36,13 +36,23 @@
      * Set IRadioMessaging as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param messaging IRadioMessaging implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion,
+    public HalVersion setAidl(HalVersion halVersion,
             android.hardware.radio.messaging.IRadioMessaging messaging) {
-        mHalVersion = halVersion;
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(messaging.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mMessagingProxy = messaging;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/RadioModemProxy.java b/src/java/com/android/internal/telephony/RadioModemProxy.java
index 7aaf727..4178293 100644
--- a/src/java/com/android/internal/telephony/RadioModemProxy.java
+++ b/src/java/com/android/internal/telephony/RadioModemProxy.java
@@ -31,13 +31,23 @@
      * Set IRadioModem as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param modem IRadioModem implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion,
+    public HalVersion setAidl(HalVersion halVersion,
             android.hardware.radio.modem.IRadioModem modem) {
-        mHalVersion = halVersion;
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(modem.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mModemProxy = modem;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
@@ -110,6 +120,19 @@
     }
 
     /**
+     * Call IRadioModem#getImei
+     *
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getImei(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getImei(serial);
+        }
+    }
+
+    /**
      * Call IRadioModem#getHardwareConfig
      * @param serial Serial number of request
      * @throws RemoteException
diff --git a/src/java/com/android/internal/telephony/RadioNetworkProxy.java b/src/java/com/android/internal/telephony/RadioNetworkProxy.java
index b881035..246c2e0 100644
--- a/src/java/com/android/internal/telephony/RadioNetworkProxy.java
+++ b/src/java/com/android/internal/telephony/RadioNetworkProxy.java
@@ -65,13 +65,23 @@
      * Set IRadioNetwork as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param network IRadioNetwork implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion,
+    public HalVersion setAidl(HalVersion halVersion,
             android.hardware.radio.network.IRadioNetwork network) {
-        mHalVersion = halVersion;
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(network.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mNetworkProxy = network;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
@@ -828,4 +838,127 @@
         }
         // Only supported on AIDL.
     }
+
+    /**
+     * Set the Emergency Mode
+     *
+     * @param serial Serial number of the request.
+     * @param emcModeType Defines the radio emergency mode type.
+     * @throws RemoteException
+     */
+    public void setEmergencyMode(int serial, int emcModeType) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.setEmergencyMode(serial, emcModeType);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Triggers an Emergency network scan.
+     *
+     * @param serial Serial number of the request.
+     * @param scanRequest Contains the preferred networks and type of service to be scanned.
+     * @throws RemoteException
+     */
+    public void triggerEmergencyNetworkScan(int serial,
+            android.hardware.radio.network.EmergencyNetworkScanTrigger scanRequest)
+            throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.triggerEmergencyNetworkScan(serial, scanRequest);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Cancels ongoing Emergency network scan
+     *
+     * @param serial Serial number of the request.
+     * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
+     *        If {@code true}, then the modem shall start the new scan from the beginning,
+     *        otherwise the modem shall resume from the last search.
+     *
+     * @throws RemoteException
+     */
+    public void cancelEmergencyNetworkScan(int serial, boolean resetScan) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.cancelEmergencyNetworkScan(serial, resetScan);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Exits ongoing Emergency Mode
+     *
+     * @param serial Serial number of the request.
+     * @throws RemoteException
+     */
+    public void exitEmergencyMode(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.exitEmergencyMode(serial);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Set if null ciphering / null integrity is permitted.
+     *
+     * @param serial Serial number of the request.
+     * @param enabled true if null modes are allowed, false otherwise
+     * @throws RemoteException
+     */
+    public void setNullCipherAndIntegrityEnabled(int serial,
+            boolean enabled) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.setNullCipherAndIntegrityEnabled(serial, enabled);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Get if null ciphering / null integrity is permitted.
+     * @param serial Serial number of the request.
+     * @throws RemoteException
+     *
+     */
+    public void isNullCipherAndIntegrityEnabled(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.isNullCipherAndIntegrityEnabled(serial);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Checks whether N1 mode is enabled.
+     *
+     * @param serial Serial number of the request.
+     * @throws RemoteException
+     */
+    public void isN1ModeEnabled(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.isN1ModeEnabled(serial);
+        }
+        // Only supported on AIDL.
+    }
+
+    /**
+     * Enables or disables N1 mode.
+     *
+     * @param serial Serial number of request.
+     * @param enable Indicates whether to enable N1 mode or not.
+     * @throws RemoteException
+     */
+    public void setN1ModeEnabled(int serial, boolean enable) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mNetworkProxy.setN1ModeEnabled(serial, enable);
+        }
+        // Only supported on AIDL.
+    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioServiceProxy.java b/src/java/com/android/internal/telephony/RadioServiceProxy.java
index 8650dd0..4257327 100644
--- a/src/java/com/android/internal/telephony/RadioServiceProxy.java
+++ b/src/java/com/android/internal/telephony/RadioServiceProxy.java
@@ -78,4 +78,9 @@
         if (isEmpty()) return;
         if (!isAidl()) mRadioProxy.responseAcknowledgement();
     }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[mHalVersion=" + mHalVersion + ']';
+    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioSimProxy.java b/src/java/com/android/internal/telephony/RadioSimProxy.java
index da5b660..7c8ee7b 100644
--- a/src/java/com/android/internal/telephony/RadioSimProxy.java
+++ b/src/java/com/android/internal/telephony/RadioSimProxy.java
@@ -41,12 +41,22 @@
      * Set IRadioSim as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param sim IRadioSim implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.sim.IRadioSim sim) {
-        mHalVersion = halVersion;
+    public HalVersion setAidl(HalVersion halVersion, android.hardware.radio.sim.IRadioSim sim) {
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(sim.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mSimProxy = sim;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
@@ -262,14 +272,24 @@
     }
 
     /**
-     * Call IRadioSim#iccCloseLogicalChannel
+     * Call IRadioSim#iccCloseLogicalChannelWithSessionInfo
      * @param serial Serial number of request
      * @param channelId Channel ID of the channel to be closed
+     * @param isEs10 Whether the logical channel is opened for performing ES10 operations.
      * @throws RemoteException
      */
-    public void iccCloseLogicalChannel(int serial, int channelId) throws RemoteException {
+    public void iccCloseLogicalChannel(int serial,
+            int channelId, boolean isEs10) throws RemoteException {
         if (isEmpty()) return;
         if (isAidl()) {
+            if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_2_1)) {
+                android.hardware.radio.sim.SessionInfo info =
+                        new android.hardware.radio.sim.SessionInfo();
+                info.sessionId = channelId;
+                info.isEs10 = isEs10;
+                mSimProxy.iccCloseLogicalChannelWithSessionInfo(serial, info);
+                return;
+            }
             mSimProxy.iccCloseLogicalChannel(serial, channelId);
         } else {
             mRadioProxy.iccCloseLogicalChannel(serial, channelId);
@@ -352,7 +372,8 @@
         if (isEmpty()) return;
         if (isAidl()) {
             mSimProxy.iccTransmitApduBasicChannel(serial,
-                    RILUtils.convertToHalSimApduAidl(0, cla, instruction, p1, p2, p3, data));
+                    RILUtils.convertToHalSimApduAidl(0, cla, instruction, p1, p2, p3, data,
+                            false, mHalVersion));
         } else {
             mRadioProxy.iccTransmitApduBasicChannel(serial,
                     RILUtils.convertToHalSimApdu(0, cla, instruction, p1, p2, p3, data));
@@ -373,10 +394,29 @@
      */
     public void iccTransmitApduLogicalChannel(int serial, int channel, int cla, int instruction,
             int p1, int p2, int p3, String data) throws RemoteException {
+        iccTransmitApduLogicalChannel(serial, channel, cla, instruction, p1, p2, p3, data, false);
+    }
+
+    /**
+     * 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
+     * @param isEs10Command APDU is an isEs10 command or not
+     * @throws RemoteException
+     */
+    public void iccTransmitApduLogicalChannel(int serial, int channel, int cla, int instruction,
+            int p1, int p2, int p3, String data, boolean isEs10Command) throws RemoteException {
         if (isEmpty()) return;
         if (isAidl()) {
             mSimProxy.iccTransmitApduLogicalChannel(serial,
-                    RILUtils.convertToHalSimApduAidl(channel, cla, instruction, p1, p2, p3, data));
+                    RILUtils.convertToHalSimApduAidl(channel, cla, instruction, p1, p2, p3, data,
+                            isEs10Command, mHalVersion));
         } else {
             mRadioProxy.iccTransmitApduLogicalChannel(serial,
                     RILUtils.convertToHalSimApdu(channel, cla, instruction, p1, p2, p3, data));
diff --git a/src/java/com/android/internal/telephony/RadioVoiceProxy.java b/src/java/com/android/internal/telephony/RadioVoiceProxy.java
index 6ac603b..7f46424 100644
--- a/src/java/com/android/internal/telephony/RadioVoiceProxy.java
+++ b/src/java/com/android/internal/telephony/RadioVoiceProxy.java
@@ -35,12 +35,23 @@
      * Set IRadioVoice as the AIDL implementation for RadioServiceProxy
      * @param halVersion Radio HAL version
      * @param voice IRadioVoice implementation
+     *
+     * @return updated HAL version
      */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.voice.IRadioVoice voice) {
-        mHalVersion = halVersion;
+    public HalVersion setAidl(HalVersion halVersion,
+            android.hardware.radio.voice.IRadioVoice voice) {
+        HalVersion version = halVersion;
+        try {
+            version = RIL.getServiceHalVersion(voice.getInterfaceVersion());
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "setAidl: " + e);
+        }
+        mHalVersion = version;
         mVoiceProxy = voice;
         mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
+
+        Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
+        return mHalVersion;
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index 24a8ac5..aff62ae 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -16,13 +16,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.os.PersistableBundle;
-import android.os.UserHandle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.CarrierConfigManager;
@@ -80,16 +74,11 @@
     /** Constructor */
     public RatRatcheter(Phone phone) {
         mPhone = phone;
-
-        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) {
-            Rlog.e(LOG_TAG, "Package name not found: " + e.getMessage());
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        if (ccm != null) {
+            ccm.registerCarrierConfigChangeListener(
+                    mPhone.getContext().getMainExecutor(),
+                    (slotIndex, subId, carrierId, specificCarrierId) -> resetRatFamilyMap());
         }
         resetRatFamilyMap();
     }
@@ -152,15 +141,24 @@
         synchronized (mRatFamilyMap) {
             // Either the two technologies are the same or their families must be non-null
             // and the same.
+            // To Fix Missing Null check
+            if (ss1.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN) == null
+                    || ss2.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN) == null) {
+                return false;
+            }
+
             int dataRat1 = ServiceState.networkTypeToRilRadioTechnology(
                     ss1.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
-                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                           AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                             .getAccessNetworkTechnology());
             int dataRat2 = ServiceState.networkTypeToRilRadioTechnology(
                     ss2.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
-                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                           AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                             .getAccessNetworkTechnology());
 
+
             // The api getAccessNetworkTechnology@NetworkRegistrationInfo always returns LTE though
             // data rat is LTE CA. Because it uses mIsUsingCarrierAggregation to indicate whether
             // it is LTE CA or not. However, we need its actual data rat to check if they are the
@@ -183,25 +181,16 @@
         }
     }
 
-    private 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)) {
-                resetRatFamilyMap();
-            }
-        }
-    };
-
     private void resetRatFamilyMap() {
         synchronized(mRatFamilyMap) {
             mRatFamilyMap.clear();
 
-            final CarrierConfigManager configManager = (CarrierConfigManager)
-                    mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            if (configManager == null) return;
-            PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
-            if (b == null) return;
+            PersistableBundle b =
+                    CarrierConfigManager.getCarrierConfigSubset(
+                            mPhone.getContext(),
+                            mPhone.getSubId(),
+                            CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES);
+            if (b == null || b.isEmpty()) return;
 
             // Reads an array of strings, eg:
             // ["GPRS, EDGE", "EVDO, EVDO_A, EVDO_B", "HSPA, HSDPA, HSUPA, HSPAP"]
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index f1afddd..a78242a 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -27,6 +27,9 @@
 import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -39,6 +42,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -86,6 +90,7 @@
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.IccRecords;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
@@ -145,6 +150,8 @@
     /** New status report received. */
     protected static final int EVENT_NEW_SMS_STATUS_REPORT = 10;
 
+    /** Retry Sending RP-SMMA Notification */
+    protected static final int EVENT_RETRY_SMMA = 11;
     // other
     protected static final int EVENT_NEW_ICC_SMS = 14;
     protected static final int EVENT_ICC_CHANGED = 15;
@@ -156,6 +163,17 @@
     /** Handle SIM loaded  */
     private static final int EVENT_SIM_LOADED = 18;
 
+    /**
+     * When this change is enabled, more specific values of SMS sending error code
+     * {@link SmsManager#Result} will be returned to the SMS Apps.
+     *
+     * Refer to {@link SMSDispatcher#rilErrorToSmsManagerResult} fore more details of the new values
+     * of SMS sending error code that will be returned.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    static final long ADD_MORE_SMS_SENDING_ERROR_CODES = 250017070L;
+
     @UnsupportedAppUsage
     protected Phone mPhone;
     @UnsupportedAppUsage
@@ -167,9 +185,18 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected final TelephonyManager mTelephonyManager;
     protected final LocalLog mLocalLog = new LocalLog(16);
+    protected final LocalLog mSmsOutgoingErrorCodes = new LocalLog(10);
 
     /** Maximum number of times to retry sending a failed SMS. */
     protected static final int MAX_SEND_RETRIES = 3;
+
+    /** Retransmitted Flag as specified in section 6.3.1.2 in TS 124011
+     * true:  RP-SMMA Retried once and no more transmissions are permitted
+     * false: not retried at all and at least another transmission of the RP-SMMA message
+     * is currently permitted
+     */
+    protected boolean mRPSmmaRetried = false;
+
     /** Delay before next send attempt on a failed SMS, in milliseconds. */
     @VisibleForTesting
     public static final int SEND_RETRY_DELAY = 2000;
@@ -300,6 +327,26 @@
     protected abstract String getFormat();
 
     /**
+     * Gets the maximum number of times the SMS can be retried upon Failure,
+     * from the {@link android.telephony.CarrierConfigManager}
+     *
+     * @return the default maximum number of times SMS can be sent
+     */
+    protected int getMaxSmsRetryCount() {
+        return MAX_SEND_RETRIES;
+    }
+
+    /**
+     * Gets the Time delay before next send attempt on a failed SMS,
+     * from the {@link android.telephony.CarrierConfigManager}
+     *
+     * @return the Time in miiliseconds for delay before next send attempt on a failed SMS
+     */
+    protected int getSmsRetryDelayValue() {
+        return SEND_RETRY_DELAY;
+    }
+
+    /**
      * Called when a status report is received. This should correspond to a previously successful
      * SEND.
      *
@@ -400,14 +447,10 @@
                  */
                 mMessageRef = getTpmrValueFromSIM();
                 if (mMessageRef == -1) {
-                    if (mPhone.isSubscriptionManagerServiceEnabled()) {
-                        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                                .getSubscriptionInfoInternal(msg.arg1);
-                        if (subInfo != null) {
-                            mMessageRef = subInfo.getLastUsedTPMessageReference();
-                        }
-                    } else {
-                        mMessageRef = SubscriptionController.getInstance().getMessageRef(msg.arg1);
+                    SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                            .getSubscriptionInfoInternal(msg.arg1);
+                    if (subInfo != null) {
+                        mMessageRef = subInfo.getLastUsedTPMessageReference();
                     }
                 }
                 break;
@@ -430,12 +473,8 @@
         updateSIMLastTPMRValue(mMessageRef);
         final long identity = Binder.clearCallingIdentity();
         try {
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                SubscriptionManagerService.getInstance()
-                        .setLastUsedTPMessageReference(getSubId(), mMessageRef);
-            } else {
-                SubscriptionController.getInstance().updateMessageRef(getSubId(), mMessageRef);
-            }
+            SubscriptionManagerService.getInstance()
+                    .setLastUsedTPMessageReference(getSubId(), mMessageRef);
         } catch (SecurityException e) {
             Rlog.e(TAG, "Security Exception caused on messageRef updation to DB " + e.getMessage());
         } finally {
@@ -467,18 +506,43 @@
     }
 
     /**
-     *  Returns the next TP message Reference value incremented by 1 for every sms sent .
-     *  once a max of 255 is reached TP message Reference is reset to 0.
+     * Returns the next TP message Reference value incremented by 1 for every sms sent .
+     * once a max of 255 is reached TP message Reference is reset to 0.
      *
-     *  @return messageRef TP message Reference value
+     * @return messageRef TP message Reference value
      */
     public int nextMessageRef() {
+        if (!isMessageRefIncrementViaTelephony()) {
+            return 0;
+        }
+
         mMessageRef = (mMessageRef + 1) % 256;
         updateTPMessageReference();
         return mMessageRef;
     }
 
     /**
+     * As modem is using the last used TP-MR value present in SIM card, increment of
+     * messageRef(TP-MR) value should be prevented (config_stk_sms_send_support set to false)
+     * at telephony framework. In future, config_stk_sms_send_support flag will be enabled
+     * so that messageRef(TP-MR) increment will be done at framework side only.
+     *
+     * TODO:- Need to have new flag to control writing TP-MR value to SIM or shared prefrence.
+     */
+    public boolean isMessageRefIncrementViaTelephony() {
+        boolean isMessageRefIncrementEnabled = false;
+        try {
+            isMessageRefIncrementEnabled = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_stk_sms_send_support);
+        } catch (NotFoundException e) {
+            Rlog.e(TAG, "isMessageRefIncrementViaTelephony NotFoundException Exception");
+        }
+
+        Rlog.i(TAG, "bool.config_stk_sms_send_support= " + isMessageRefIncrementEnabled);
+        return isMessageRefIncrementEnabled;
+    }
+
+    /**
      * Use the carrier messaging service to send a data or text SMS.
      */
     protected abstract class SmsSender extends Handler {
@@ -688,26 +752,50 @@
         @Override
         public void onSendSmsComplete(int result, int messageRef) {
             Rlog.d(TAG, "onSendSmsComplete: result=" + result + " messageRef=" + messageRef);
-            if (mCallbackCalled) {
-                logWithLocalLog("onSendSmsComplete: unexpected call");
-                AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
-                        "Unexpected onSendSmsComplete", mPhone.getCarrierId());
+            if (cleanupOnSendSmsComplete("onSendSmsComplete")) {
                 return;
             }
-            mCallbackCalled = true;
+
             final long identity = Binder.clearCallingIdentity();
             try {
-                mSmsSender.mCarrierMessagingServiceWrapper.disconnect();
                 processSendSmsResponse(mSmsSender.getSmsTracker(), result, messageRef);
-                mSmsSender.removeTimeout();
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
         }
 
+        /**
+         * This method should be called only once.
+         */
         @Override
         public void onSendMultipartSmsComplete(int result, int[] messageRefs) {
-            Rlog.e(TAG, "Unexpected onSendMultipartSmsComplete call with result: " + result);
+            Rlog.d(TAG, "onSendMultipartSmsComplete: result=" + result + " messageRefs="
+                    + Arrays.toString(messageRefs));
+            if (cleanupOnSendSmsComplete("onSendMultipartSmsComplete")) {
+                return;
+            }
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                processSendMultipartSmsResponse(mSmsSender.getSmsTrackers(), result, messageRefs);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        private boolean cleanupOnSendSmsComplete(String callingFunction) {
+            if (mCallbackCalled) {
+                logWithLocalLog(callingFunction + ": unexpected call");
+                AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
+                        "Unexpected " + callingFunction, mPhone.getCarrierId());
+                return true;
+            }
+
+            mCallbackCalled = true;
+            mSmsSender.removeTimeout();
+            mSmsSender.mCarrierMessagingServiceWrapper.disconnect();
+
+            return false;
         }
 
         @Override
@@ -782,8 +870,7 @@
         }
 
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        void sendSmsByCarrierApp(String carrierPackageName,
-                                 MultipartSmsSenderCallback senderCallback) {
+        void sendSmsByCarrierApp(String carrierPackageName, SmsSenderCallback senderCallback) {
             super.sendSmsByCarrierApp(carrierPackageName, senderCallback);
         }
 
@@ -831,69 +918,6 @@
         }
     }
 
-    /**
-     * Callback for MultipartSmsSender from the carrier messaging service.
-     * Once the result is ready, the carrier messaging service connection is disposed.
-     */
-    private final class MultipartSmsSenderCallback implements CarrierMessagingCallback {
-        private final MultipartSmsSender mSmsSender;
-        private boolean mCallbackCalled = false;
-
-        MultipartSmsSenderCallback(MultipartSmsSender smsSender) {
-            mSmsSender = smsSender;
-        }
-
-        @Override
-        public void onSendSmsComplete(int result, int messageRef) {
-            Rlog.e(TAG, "Unexpected onSendSmsComplete call with result: " + result);
-        }
-
-        /**
-         * This method should be called only once.
-         */
-        @Override
-        public void onSendMultipartSmsComplete(int result, int[] messageRefs) {
-            Rlog.d(TAG, "onSendMultipartSmsComplete: result=" + result + " messageRefs="
-                    + Arrays.toString(messageRefs));
-            if (mCallbackCalled) {
-                logWithLocalLog("onSendMultipartSmsComplete: unexpected call");
-                AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
-                        "Unexpected onSendMultipartSmsComplete", mPhone.getCarrierId());
-                return;
-            }
-            mCallbackCalled = true;
-            mSmsSender.removeTimeout();
-            mSmsSender.mCarrierMessagingServiceWrapper.disconnect();
-
-            if (mSmsSender.mTrackers == null) {
-                Rlog.e(TAG, "Unexpected onSendMultipartSmsComplete call with null trackers.");
-                return;
-            }
-
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                processSendMultipartSmsResponse(mSmsSender.mTrackers, result, messageRefs);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-
-        @Override
-        public void onReceiveSmsComplete(int result) {
-            Rlog.e(TAG, "Unexpected onReceiveSmsComplete call with result: " + result);
-        }
-
-        @Override
-        public void onSendMmsComplete(int result, byte[] sendConfPdu) {
-            Rlog.e(TAG, "Unexpected onSendMmsComplete call with result: " + result);
-        }
-
-        @Override
-        public void onDownloadMmsComplete(int result) {
-            Rlog.e(TAG, "Unexpected onDownloadMmsComplete call with result: " + result);
-        }
-    }
-
     private void processSendMultipartSmsResponse(
             SmsTracker[] trackers, int result, int[] messageRefs) {
         if (trackers == null) {
@@ -1038,7 +1062,7 @@
                 // This is retry after failure over IMS but voice is not available.
                 // Set retry to max allowed, so no retry is sent and cause
                 // SmsManager.RESULT_ERROR_GENERIC_FAILURE to be returned to app.
-                tracker.mRetryCount = MAX_SEND_RETRIES;
+                tracker.mRetryCount = getMaxSmsRetryCount();
 
                 Rlog.d(TAG, "handleSendComplete: Skipping retry: "
                         + " isIms()=" + isIms()
@@ -1061,7 +1085,7 @@
                         tracker.isFromDefaultSmsApplication(mContext),
                         tracker.getInterval());
             } else if (error == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY
-                    && tracker.mRetryCount < MAX_SEND_RETRIES) {
+                    && tracker.mRetryCount < getMaxSmsRetryCount()) {
                 // Retry after a delay if needed.
                 // TODO: According to TS 23.040, 9.2.3.6, we should resend
                 //       with the same TP-MR as the failed message, and
@@ -1073,7 +1097,7 @@
                 tracker.mRetryCount++;
                 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE;
                 Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
-                sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
+                sendMessageDelayed(retryMsg, getSmsRetryDelayValue());
                 mPhone.getSmsStats().onOutgoingSms(
                         tracker.mImsRetry > 0 /* isOverIms */,
                         SmsConstants.FORMAT_3GPP2.equals(getFormat()),
@@ -1100,8 +1124,31 @@
     }
 
     @SmsManager.Result
-    private static int rilErrorToSmsManagerResult(CommandException.Error rilError,
+    private int rilErrorToSmsManagerResult(CommandException.Error rilError,
             SmsTracker tracker) {
+        mSmsOutgoingErrorCodes.log("rilError: " + rilError
+                + ", MessageId: " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
+
+        ApplicationInfo appInfo = tracker.getAppInfo();
+        if (appInfo == null
+                || !CompatChanges.isChangeEnabled(ADD_MORE_SMS_SENDING_ERROR_CODES, appInfo.uid)) {
+            if (rilError == CommandException.Error.INVALID_RESPONSE
+                    || rilError == CommandException.Error.SIM_PIN2
+                    || rilError == CommandException.Error.SIM_PUK2
+                    || rilError == CommandException.Error.SUBSCRIPTION_NOT_AVAILABLE
+                    || rilError == CommandException.Error.SIM_ERR
+                    || rilError == CommandException.Error.INVALID_SIM_STATE
+                    || rilError == CommandException.Error.NO_SMS_TO_ACK
+                    || rilError == CommandException.Error.SIM_BUSY
+                    || rilError == CommandException.Error.SIM_FULL
+                    || rilError == CommandException.Error.NO_SUBSCRIPTION
+                    || rilError == CommandException.Error.NO_NETWORK_FOUND
+                    || rilError == CommandException.Error.DEVICE_IN_USE
+                    || rilError == CommandException.Error.ABORTED) {
+                return SmsManager.RESULT_ERROR_GENERIC_FAILURE;
+            }
+        }
+
         switch (rilError) {
             case RADIO_NOT_AVAILABLE:
                 return SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE;
@@ -1151,6 +1198,34 @@
                 return SmsManager.RESULT_RIL_ACCESS_BARRED;
             case BLOCKED_DUE_TO_CALL:
                 return SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL;
+            case INVALID_SMSC_ADDRESS:
+                return SmsManager.RESULT_INVALID_SMSC_ADDRESS;
+            case INVALID_RESPONSE:
+                return SmsManager.RESULT_RIL_INVALID_RESPONSE;
+            case SIM_PIN2:
+                return SmsManager.RESULT_RIL_SIM_PIN2;
+            case SIM_PUK2:
+                return SmsManager.RESULT_RIL_SIM_PUK2;
+            case SUBSCRIPTION_NOT_AVAILABLE:
+                return SmsManager.RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE;
+            case SIM_ERR:
+                return SmsManager.RESULT_RIL_SIM_ERROR;
+            case INVALID_SIM_STATE:
+                return SmsManager.RESULT_RIL_INVALID_SIM_STATE;
+            case NO_SMS_TO_ACK:
+                return SmsManager.RESULT_RIL_NO_SMS_TO_ACK;
+            case SIM_BUSY:
+                return SmsManager.RESULT_RIL_SIM_BUSY;
+            case SIM_FULL:
+                return SmsManager.RESULT_RIL_SIM_FULL;
+            case NO_SUBSCRIPTION:
+                return SmsManager.RESULT_RIL_NO_SUBSCRIPTION;
+            case NO_NETWORK_FOUND:
+                return SmsManager.RESULT_RIL_NO_NETWORK_FOUND;
+            case DEVICE_IN_USE:
+                return SmsManager.RESULT_RIL_DEVICE_IN_USE;
+            case ABORTED:
+                return SmsManager.RESULT_RIL_ABORTED;
             default:
                 Rlog.d(TAG, "rilErrorToSmsManagerResult: " + rilError + " "
                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
@@ -1372,10 +1447,120 @@
      *                 Used for logging and diagnostics purposes. The id may be NULL.
      */
     public void sendText(String destAddr, String scAddr, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
+            String callingPkg, boolean persistMessage, int priority,
+            boolean expectMore, int validityPeriod, boolean isForVvm,
+            long messageId) {
+        sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, messageUri, callingPkg,
+                persistMessage, priority, expectMore, validityPeriod, isForVvm, messageId, false);
+    }
+
+    /**
+     * Send a text based SMS.
+     *
+     * @param destAddr the address to send the message to
+     * @param scAddr is the service center address or null to use
+     *  the current default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is successfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK<code> for success,
+     *  or one of these errors:<br>
+     *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
+     *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
+     *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
+     *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
+     *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
+     *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
+     *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
+     *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
+     *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
+     *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
+     *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
+     *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
+     *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
+     *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
+     *  <code>SmsManager.RESULT_CANCELLED</code><br>
+     *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
+     *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
+     *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
+     *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
+     *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
+     *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
+     *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
+     *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
+     *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
+     *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
+     *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
+     *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
+     *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
+     *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
+     *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
+     *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
+     *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
+     *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
+     *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
+     *  the sentIntent may include the extra "errorCode" containing a radio technology specific
+     *  value, generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     * @param messageUri optional URI of the message if it is already stored in the system
+     * @param callingPkg the calling package name
+     * @param persistMessage whether to save the sent message into SMS DB for a
+     *  non-default SMS app.
+     *
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     *                 Used for logging and diagnostics purposes. The id may be NULL.
+     * @param skipShortCodeCheck Skip check for short code type destination address.
+     */
+    public void sendText(String destAddr, String scAddr, String text,
                          PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
                          String callingPkg, boolean persistMessage, int priority,
                          boolean expectMore, int validityPeriod, boolean isForVvm,
-                         long messageId) {
+                         long messageId, boolean skipShortCodeCheck) {
         Rlog.d(TAG, "sendText id: " + SmsController.formatCrossStackMessageId(messageId));
         int messageRef = nextMessageRef();
         SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
@@ -1385,7 +1570,8 @@
             HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu);
             SmsTracker tracker = getSmsTracker(callingPkg, map, sentIntent, deliveryIntent,
                     getFormat(), messageUri, expectMore, text, true /*isText*/,
-                    persistMessage, priority, validityPeriod, isForVvm, messageId, messageRef);
+                    persistMessage, priority, validityPeriod, isForVvm, messageId, messageRef,
+                    skipShortCodeCheck);
 
             if (!sendSmsByCarrierApp(false /* isDataSms */, tracker)) {
                 sendSubmitPdu(tracker);
@@ -1640,12 +1826,10 @@
 
         String carrierPackage = getCarrierAppPackageName();
         if (carrierPackage != null) {
-            Rlog.d(TAG, "Found carrier package " + carrierPackage
-                    + " "
+            Rlog.d(TAG, "Found carrier package " + carrierPackage + " "
                     + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
             MultipartSmsSender smsSender = new MultipartSmsSender(parts, trackers);
-            smsSender.sendSmsByCarrierApp(carrierPackage,
-                    new MultipartSmsSenderCallback(smsSender));
+            smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender));
         } else {
             Rlog.v(TAG, "No carrier package. "
                     + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
@@ -1698,7 +1882,7 @@
                         getFormat(), unsentPartCount, anyPartFailed, messageUri, smsHeader,
                         (!lastPart || expectMore), fullMessageText, true /*isText*/,
                         true /*persistMessage*/, priority, validityPeriod, false /* isForVvm */,
-                        messageId, messageRef);
+                        messageId, messageRef, false);
             } else {
                 Rlog.e(TAG, "CdmaSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
                         + "null " + SmsController.formatCrossStackMessageId(messageId));
@@ -1711,13 +1895,12 @@
                             SmsHeader.toByteArray(smsHeader), encoding, smsHeader.languageTable,
                             smsHeader.languageShiftTable, validityPeriod, messageRef);
             if (pdu != null) {
-                HashMap map =  getSmsTrackerMap(destinationAddress, scAddress,
-                        message, pdu);
+                HashMap map = getSmsTrackerMap(destinationAddress, scAddress, message, pdu);
                 return getSmsTracker(callingPackage, map, sentIntent,
                         deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri,
                         smsHeader, (!lastPart || expectMore), fullMessageText, true /*isText*/,
                         false /*persistMessage*/, priority, validityPeriod, false /* isForVvm */,
-                        messageId, messageRef);
+                        messageId, messageRef, false);
             } else {
                 Rlog.e(TAG, "GsmSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
                         + "null " + SmsController.formatCrossStackMessageId(messageId));
@@ -1875,7 +2058,8 @@
      */
     boolean checkDestination(SmsTracker[] trackers) {
         if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION)
-                == PackageManager.PERMISSION_GRANTED || trackers[0].mIsForVvm) {
+                == PackageManager.PERMISSION_GRANTED || trackers[0].mIsForVvm
+                || trackers[0].mSkipShortCodeDestAddrCheck) {
             return true;            // app is pre-approved to send to short codes
         } else {
             int rule = mPremiumSmsRule.get();
@@ -1916,6 +2100,12 @@
                                                 trackers[0].mDestAddress, networkCountryIso));
             }
 
+            if (smsCategory != SmsManager.SMS_CATEGORY_NOT_SHORT_CODE) {
+                int xmlVersion = mSmsDispatchersController.getUsageMonitor()
+                        .getShortCodeXmlFileVersion();
+                mPhone.getSmsStats().onOutgoingShortCodeSms(smsCategory, xmlVersion);
+            }
+
             if (smsCategory == SmsManager.SMS_CATEGORY_NOT_SHORT_CODE
                     || smsCategory == SmsManager.SMS_CATEGORY_FREE_SHORT_CODE
                     || smsCategory == SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE) {
@@ -2213,6 +2403,7 @@
         private Boolean mIsFromDefaultSmsApplication;
 
         private int mCarrierId;
+        private boolean mSkipShortCodeDestAddrCheck;
         // SMS anomaly uuid -- unexpected error from RIL
         private final UUID mAnomalyUnexpectedErrorFromRilUUID =
                 UUID.fromString("43043600-ea7a-44d2-9ae6-a58567ac7886");
@@ -2223,7 +2414,7 @@
                 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 messageRef) {
+                int messageRef, boolean skipShortCodeDestAddrCheck) {
             mData = data;
             mSentIntent = sentIntent;
             mDeliveryIntent = deliveryIntent;
@@ -2249,6 +2440,7 @@
             mIsForVvm = isForVvm;
             mMessageId = messageId;
             mCarrierId = carrierId;
+            mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck;
         }
 
         public HashMap<String, Object> getData() {
@@ -2263,12 +2455,21 @@
             return mAppInfo != null ? mAppInfo.packageName : null;
         }
 
+        /**
+         * Get the calling Application Info
+         * @return Application Info
+         */
+        public ApplicationInfo getAppInfo() {
+            return mAppInfo == null ? null : mAppInfo.applicationInfo;
+        }
+
         /** Return if the SMS was originated from the default SMS application. */
         public boolean isFromDefaultSmsApplication(Context context) {
             if (mIsFromDefaultSmsApplication == null) {
+                UserHandle userHandle = TelephonyUtils.getSubscriptionUserHandle(context, mSubId);
                 // Perform a lazy initialization, due to the cost of the operation.
-                mIsFromDefaultSmsApplication =
-                        SmsApplication.isDefaultSmsApplication(context, getAppPackageName());
+                mIsFromDefaultSmsApplication = SmsApplication.isDefaultSmsApplicationAsUser(context,
+                                    getAppPackageName(), userHandle);
             }
             return mIsFromDefaultSmsApplication;
         }
@@ -2516,7 +2717,7 @@
             AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
             SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText,
             boolean persistMessage, int priority, int validityPeriod, boolean isForVvm,
-            long messageId, int messageRef) {
+            long messageId, int messageRef, boolean skipShortCodeCheck) {
         // Get package info via packagemanager
         UserHandle callingUser = UserHandle.getUserHandleForUid(Binder.getCallingUid());
         final int userId = callingUser.getIdentifier();
@@ -2533,7 +2734,8 @@
         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(), messageRef);
+                validityPeriod, isForVvm, messageId, mPhone.getCarrierId(), messageRef,
+                skipShortCodeCheck);
     }
 
     protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
@@ -2544,17 +2746,18 @@
                 null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
                 expectMore, fullMessageText, isText, persistMessage,
                 SMS_MESSAGE_PRIORITY_NOT_SPECIFIED, SMS_MESSAGE_PERIOD_NOT_SPECIFIED, isForVvm,
-                messageId, messageRef);
+                messageId, messageRef, false);
     }
 
     protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
             PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri,
             boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage,
-            int priority, int validityPeriod, boolean isForVvm, long messageId, int messageRef) {
+            int priority, int validityPeriod, boolean isForVvm, long messageId, int messageRef,
+            boolean skipShortCodeCheck) {
         return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format,
                 null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/,
                 expectMore, fullMessageText, isText, persistMessage, priority, validityPeriod,
-                isForVvm, messageId, messageRef);
+                isForVvm, messageId, messageRef, skipShortCodeCheck);
     }
 
     protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
@@ -2773,10 +2976,17 @@
         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println(TAG);
         pw.increaseIndent();
+
         pw.println("mLocalLog:");
         pw.increaseIndent();
         mLocalLog.dump(fd, pw, args);
         pw.decreaseIndent();
+
+        pw.println("mSmsOutgoingErrorCodes:");
+        pw.increaseIndent();
+        mSmsOutgoingErrorCodes.dump(fd, pw, args);
+        pw.decreaseIndent();
+
         pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
old mode 100755
new mode 100644
index 32e29a9..29b1aca
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -71,7 +71,6 @@
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.ServiceState.RilRadioTechnology;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
@@ -92,6 +91,7 @@
 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.AccessNetworksManager.AccessNetworksManagerCallback;
 import com.android.internal.telephony.data.DataNetwork;
 import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
 import com.android.internal.telephony.imsphone.ImsPhone;
@@ -147,7 +147,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private UiccController mUiccController = null;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private UiccCardApplication mUiccApplcation = null;
+    private UiccCardApplication mUiccApplication = null;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private IccRecords mIccRecords = null;
 
@@ -180,16 +180,16 @@
     private long mLastCellInfoReqTime;
     private List<CellInfo> mLastCellInfoList = null;
     private List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = null;
+    private int mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
 
     private final Set<Integer> mRadioPowerOffReasons = new HashSet();
 
-    // TODO - this should not be public, right now used externally GsmConnetion.
+    // TODO - this should not be public, right now used externally GsmConnection.
     public RestrictedState mRestrictedState;
 
     /**
-     * A unique identifier to track requests associated with a poll
-     * and ignore stale responses.  The value is a count-down of
-     * expected responses in this pollingContext.
+     * A unique identifier to track requests associated with a poll and ignore stale responses.
+     * The value is a count-down of expected responses in this pollingContext.
      */
     @VisibleForTesting
     public int[] mPollingContext;
@@ -218,7 +218,6 @@
     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();
 
@@ -281,7 +280,6 @@
     protected static final int EVENT_RADIO_POWER_OFF_DONE              = 54;
     protected static final int EVENT_PHYSICAL_CHANNEL_CONFIG           = 55;
     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;
     // 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;
@@ -312,7 +310,7 @@
     // Show PLMN only and only if this bit is set.
     public static final int CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN = 1 << 1;
 
-    private List<Message> mPendingCellInfoRequests = new LinkedList<Message>();
+    private List<Message> mPendingCellInfoRequests = new LinkedList<>();
     // @GuardedBy("mPendingCellInfoRequests")
     private boolean mIsPendingCellInfoRequest = false;
 
@@ -323,14 +321,10 @@
     private CarrierDisplayNameResolver mCdnr;
 
     private boolean mImsRegistrationOnOff = false;
-    /** Radio is disabled by carrier. Radio power will not be override if this field is set */
-    private boolean mRadioDisabledByCarrier = false;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private boolean mDeviceShuttingDown = false;
     /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private boolean mSpnUpdatePending = false;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private String mCurSpn = null;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private String mCurDataSpn = null;
@@ -349,14 +343,11 @@
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private SubscriptionManager mSubscriptionManager;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private SubscriptionController mSubscriptionController;
     private SubscriptionManagerService mSubscriptionManagerService;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private final SstSubscriptionsChangedListener mOnSubscriptionsChangedListener =
         new SstSubscriptionsChangedListener();
 
-
     private final RatRatcheter mRatRatcheter;
 
     private final LocaleTracker mLocaleTracker;
@@ -369,6 +360,7 @@
     private final LocalLog mCdnrLogs = new LocalLog(64);
 
     private Pattern mOperatorNameStringPattern;
+    private PersistableBundle mCarrierConfig;
 
     private class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener {
 
@@ -388,7 +380,6 @@
             // If not, then the subId has changed, so we need to remember the old subId,
             // even if the new subId is invalid (likely).
             mPrevSubId = mSubId;
-            mSubId = curSubId;
 
             // Update voicemail count and notify message waiting changed regardless of
             // whether the new subId is valid. This is an exception to the general logic
@@ -397,72 +388,64 @@
             // which seems desirable.
             mPhone.updateVoiceMail();
 
-            if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            if (!SubscriptionManager.isValidSubscriptionId(curSubId)) {
                 if (SubscriptionManager.isValidSubscriptionId(mPrevSubId)) {
                     // just went from valid to invalid subId, so notify phone state listeners
                     // with final broadcast
                     mPhone.notifyServiceStateChangedForSubId(mOutOfServiceSS,
                             ServiceStateTracker.this.mPrevSubId);
                 }
-                // If the new subscription ID isn't valid, then we don't need to do all the
-                // UI updating, so we're done.
-                return;
+            } else {
+                Context context = mPhone.getContext();
+
+                mPhone.notifyPhoneStateChanged();
+
+                if (!SubscriptionManager.isValidSubscriptionId(mPrevSubId)) {
+                    // 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());
+                }
+
+                boolean restoreSelection = !context.getResources().getBoolean(
+                        com.android.internal.R.bool.skip_restoring_network_selection);
+                mPhone.sendSubscriptionSettings(restoreSelection);
+
+                setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology());
+
+                // Remove old network selection sharedPreferences since SP key names are now
+                // changed to include subId. This will be done only once when upgrading from an
+                // older build that did not include subId in the names.
+                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+                        context);
+                String oldNetworkSelection = sp.getString(
+                        Phone.NETWORK_SELECTION_KEY, "");
+                String oldNetworkSelectionName = sp.getString(
+                        Phone.NETWORK_SELECTION_NAME_KEY, "");
+                String oldNetworkSelectionShort = sp.getString(
+                        Phone.NETWORK_SELECTION_SHORT_KEY, "");
+                if (!TextUtils.isEmpty(oldNetworkSelection)
+                        || !TextUtils.isEmpty(oldNetworkSelectionName)
+                        || !TextUtils.isEmpty(oldNetworkSelectionShort)) {
+                    SharedPreferences.Editor editor = sp.edit();
+                    editor.putString(Phone.NETWORK_SELECTION_KEY + curSubId,
+                            oldNetworkSelection);
+                    editor.putString(Phone.NETWORK_SELECTION_NAME_KEY + curSubId,
+                            oldNetworkSelectionName);
+                    editor.putString(Phone.NETWORK_SELECTION_SHORT_KEY + curSubId,
+                            oldNetworkSelectionShort);
+                    editor.remove(Phone.NETWORK_SELECTION_KEY);
+                    editor.remove(Phone.NETWORK_SELECTION_NAME_KEY);
+                    editor.remove(Phone.NETWORK_SELECTION_SHORT_KEY);
+                    editor.commit();
+                }
+
+                // Once sub id becomes valid, we need to update the service provider name
+                // displayed on the UI again. The old SPN update intents sent to
+                // MobileSignalController earlier were actually ignored due to invalid sub id.
+                updateSpnDisplay();
             }
-
-            Context context = mPhone.getContext();
-
-            mPhone.notifyPhoneStateChanged();
-
-            if (!SubscriptionManager.isValidSubscriptionId(mPrevSubId)) {
-                // 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());
-            }
-
-            boolean restoreSelection = !context.getResources().getBoolean(
-                    com.android.internal.R.bool.skip_restoring_network_selection);
-            mPhone.sendSubscriptionSettings(restoreSelection);
-
-            setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology());
-
-            if (mSpnUpdatePending) {
-                mSubscriptionController.setPlmnSpn(mPhone.getPhoneId(), mCurShowPlmn,
-                        mCurPlmn, mCurShowSpn, mCurSpn);
-                mSpnUpdatePending = false;
-            }
-
-            // Remove old network selection sharedPreferences since SP key names are now
-            // changed to include subId. This will be done only once when upgrading from an
-            // older build that did not include subId in the names.
-            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
-                    context);
-            String oldNetworkSelection = sp.getString(
-                    Phone.NETWORK_SELECTION_KEY, "");
-            String oldNetworkSelectionName = sp.getString(
-                    Phone.NETWORK_SELECTION_NAME_KEY, "");
-            String oldNetworkSelectionShort = sp.getString(
-                    Phone.NETWORK_SELECTION_SHORT_KEY, "");
-            if (!TextUtils.isEmpty(oldNetworkSelection)
-                    || !TextUtils.isEmpty(oldNetworkSelectionName)
-                    || !TextUtils.isEmpty(oldNetworkSelectionShort)) {
-                SharedPreferences.Editor editor = sp.edit();
-                editor.putString(Phone.NETWORK_SELECTION_KEY + mSubId,
-                        oldNetworkSelection);
-                editor.putString(Phone.NETWORK_SELECTION_NAME_KEY + mSubId,
-                        oldNetworkSelectionName);
-                editor.putString(Phone.NETWORK_SELECTION_SHORT_KEY + mSubId,
-                        oldNetworkSelectionShort);
-                editor.remove(Phone.NETWORK_SELECTION_KEY);
-                editor.remove(Phone.NETWORK_SELECTION_NAME_KEY);
-                editor.remove(Phone.NETWORK_SELECTION_SHORT_KEY);
-                editor.commit();
-            }
-
-            // Once sub id becomes valid, we need to update the service provider name
-            // displayed on the UI again. The old SPN update intents sent to
-            // MobileSignalController earlier were actually ignored due to invalid sub id.
-            updateSpnDisplay();
+            mSubId = curSubId;
         }
     };
 
@@ -561,15 +544,13 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            if (action.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)) {
+            if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
+                log("ACTION_LOCALE_CHANGED");
                 // Update emergency string or operator name, polling service state.
                 pollState();
+                // Depends on modem, ServiceState is not necessarily updated, so make sure updating
+                // SPN.
+                updateSpnDisplay();
             } else if (action.equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
                 String lastKnownNetworkCountry = intent.getStringExtra(
                         TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY);
@@ -580,6 +561,10 @@
         }
     };
 
+    private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            (slotIndex, subId, carrierId, specificCarrierId) ->
+                    onCarrierConfigurationChanged(slotIndex);
+
     //CDMA
     // Min values used to by getOtasp()
     public static final String UNACTIVATED_MIN2_VALUE = "000000";
@@ -627,6 +612,12 @@
      */
     private DataNetworkControllerCallback mDataDisconnectedCallback;
 
+    /**
+     * AccessNetworksManagerCallback is used for preferred on the IWLAN when preferred transport
+     * type changed in AccessNetworksManager.
+     */
+    private AccessNetworksManagerCallback mAccessNetworksManagerCallback = null;
+
     public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {
         mNitzState = TelephonyComponentFactory.getInstance()
                 .inject(NitzStateMachine.class.getName())
@@ -656,20 +647,20 @@
         mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
         mCi.registerForPhysicalChannelConfiguration(this, EVENT_PHYSICAL_CHANNEL_CONFIG, null);
 
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService = SubscriptionManagerService.getInstance();
-        } else {
-            mSubscriptionController = SubscriptionController.getInstance();
-        }
-
+        mSubscriptionManagerService = SubscriptionManagerService.getInstance();
         mSubscriptionManager = SubscriptionManager.from(phone.getContext());
         mSubscriptionManager.addOnSubscriptionsChangedListener(
                 new android.os.HandlerExecutor(this), mOnSubscriptionsChangedListener);
         mRestrictedState = new RestrictedState();
 
+        mCarrierConfig = getCarrierConfig();
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        // Callback which directly handle config change should be executed in handler thread
+        ccm.registerCarrierConfigChangeListener(this::post, mCarrierConfigChangeListener);
+
         mAccessNetworksManager = mPhone.getAccessNetworksManager();
         mOutOfServiceSS = new ServiceState();
-        mOutOfServiceSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mOutOfServiceSS.setOutOfService(false);
 
         for (int transportType : mAccessNetworksManager.getAvailableTransports()) {
             mRegStateManagers.append(transportType, new NetworkRegistrationManager(
@@ -692,12 +683,11 @@
                 Settings.Global.ENABLE_CELLULAR_ON_BOOT, 1);
         mDesiredPowerState = (enableCellularOnBoot > 0) && ! (airplaneMode > 0);
         if (!mDesiredPowerState) {
-            mRadioPowerOffReasons.add(Phone.RADIO_POWER_REASON_USER);
+            mRadioPowerOffReasons.add(TelephonyManager.RADIO_POWER_REASON_USER);
         }
         mRadioPowerLog.log("init : airplane mode = " + airplaneMode + " enableCellularOnBoot = " +
                 enableCellularOnBoot);
 
-
         mPhone.getCarrierActionAgent().registerForCarrierAction(CARRIER_ACTION_SET_RADIO_ENABLED,
                 this, EVENT_RADIO_POWER_FROM_CARRIER, null, false);
 
@@ -705,7 +695,6 @@
         Context context = mPhone.getContext();
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_LOCALE_CHANGED);
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
         context.registerReceiver(mIntentReceiver, filter);
 
@@ -736,6 +725,23 @@
                 }
             }
         };
+
+        mAccessNetworksManagerCallback = new AccessNetworksManagerCallback(this::post) {
+            @Override
+            public void onPreferredTransportChanged(int networkCapability) {
+                // Check if preferred on IWLAN was changed in ServiceState.
+                boolean isIwlanPreferred = mAccessNetworksManager.isAnyApnOnIwlan();
+                if (mSS.isIwlanPreferred() != isIwlanPreferred) {
+                    log("onPreferredTransportChanged: IwlanPreferred is changed to "
+                            + isIwlanPreferred);
+                    mSS.setIwlanPreferred(isIwlanPreferred);
+                    mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+                }
+            }
+        };
+        if (mAccessNetworksManagerCallback != null) {
+            mAccessNetworksManager.registerCallback(mAccessNetworksManagerCallback);
+        }
     }
 
     @VisibleForTesting
@@ -771,9 +777,9 @@
         }
 
         mSS = new ServiceState();
-        mSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mSS.setOutOfService(false);
         mNewSS = new ServiceState();
-        mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mNewSS.setOutOfService(false);
         mLastCellInfoReqTime = 0;
         mLastCellInfoList = null;
         mStartedGprsRegCheck = false;
@@ -866,17 +872,28 @@
         mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
                 CARRIER_ACTION_SET_RADIO_ENABLED);
         mPhone.getContext().unregisterReceiver(mIntentReceiver);
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        if (ccm != null && mCarrierConfigChangeListener != null) {
+            ccm.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+        }
         if (mCSST != null) {
             mCSST.dispose();
             mCSST = null;
         }
+        if (mAccessNetworksManagerCallback != null) {
+            mAccessNetworksManager.unregisterCallback(mAccessNetworksManagerCallback);
+            mAccessNetworksManagerCallback = null;
+        }
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean getDesiredPowerState() {
         return mDesiredPowerState;
     }
-    public boolean getPowerStateFromCarrier() { return !mRadioDisabledByCarrier; }
+
+    public boolean getPowerStateFromCarrier() {
+        return !mRadioPowerOffReasons.contains(TelephonyManager.RADIO_POWER_REASON_CARRIER);
+    }
 
     public List<PhysicalChannelConfig> getPhysicalChannelConfigList() {
         return mLastPhysicalChannelConfigList;
@@ -1066,7 +1083,7 @@
      * @return the current reasons for which the radio is off.
      */
     public Set<Integer> getRadioPowerOffReasons() {
-        return mRadioPowerOffReasons;
+        return Set.copyOf(mRadioPowerOffReasons);
     }
 
     /**
@@ -1092,14 +1109,14 @@
     public void setRadioPower(boolean power, boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply) {
         setRadioPowerForReason(power, forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply,
-                Phone.RADIO_POWER_REASON_USER);
+                TelephonyManager.RADIO_POWER_REASON_USER);
     }
 
     /**
      * Turn on or off radio power with option to specify whether it's for emergency call and specify
      * a reason for setting the power state.
-     * More details check {@link PhoneInternalInterface#setRadioPower(
-     * boolean, boolean, boolean, boolean, int)}.
+     * More details check {@link
+     * PhoneInternalInterface#setRadioPowerForReason(boolean, boolean, boolean, boolean, int)}.
      */
     public void setRadioPowerForReason(boolean power, boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply, int reason) {
@@ -1133,23 +1150,6 @@
     }
 
     /**
-     * Radio power set from carrier action. if set to false means carrier desire to turn radio off
-     * and radio wont be re-enabled unless carrier explicitly turn it back on.
-     * @param enable indicate if radio power is enabled or disabled from carrier action.
-     */
-    public void setRadioPowerFromCarrier(boolean enable) {
-        boolean disableByCarrier = !enable;
-        if (mRadioDisabledByCarrier == disableByCarrier) {
-            log("setRadioPowerFromCarrier mRadioDisabledByCarrier is already "
-                    + disableByCarrier + " Do nothing.");
-            return;
-        }
-
-        mRadioDisabledByCarrier = disableByCarrier;
-        setPowerStateToDesired();
-    }
-
-    /**
      * These two flags manage the behavior of the cell lock -- the
      * lock should be held if either flag is true.  The intention is
      * to allow temporary acquisition of the lock to get a single
@@ -1222,8 +1222,8 @@
                     mCdnr.updateEfFromUsim(null /* Usim */);
                 }
                 onUpdateIccAvailability();
-                if (mUiccApplcation == null
-                        || mUiccApplcation.getState() != AppState.APPSTATE_READY) {
+                if (mUiccApplication == null
+                        || mUiccApplication.getState() != AppState.APPSTATE_READY) {
                     mIsSimReady = false;
                     updateSpnDisplay();
                 }
@@ -1648,7 +1648,8 @@
                 if (ar.exception == null) {
                     boolean enable = (boolean) ar.result;
                     if (DBG) log("EVENT_RADIO_POWER_FROM_CARRIER: " + enable);
-                    setRadioPowerFromCarrier(enable);
+                    setRadioPowerForReason(enable, false, false, false,
+                            TelephonyManager.RADIO_POWER_REASON_CARRIER);
                 }
                 break;
 
@@ -1657,8 +1658,20 @@
                 if (ar.exception == null) {
                     List<PhysicalChannelConfig> list = (List<PhysicalChannelConfig>) ar.result;
                     if (VDBG) {
-                        log("EVENT_PHYSICAL_CHANNEL_CONFIG: size=" + list.size() + " list="
-                                + list);
+                        log("EVENT_PHYSICAL_CHANNEL_CONFIG: list=" + list
+                                + (list == null ? "" : ", list.size()=" + list.size()));
+                    }
+                    if ((list == null || list.isEmpty())
+                            && mLastAnchorNrCellId != PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN
+                            && mPhone.getContext().getSystemService(TelephonyManager.class)
+                                    .isRadioInterfaceCapabilitySupported(TelephonyManager
+                                            .CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED)
+                            && !mCarrierConfig.getBoolean(CarrierConfigManager
+                                    .KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL)
+                            && mCarrierConfig.getBoolean(CarrierConfigManager
+                                    .KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL)) {
+                        log("Ignore empty PCC list when RRC idle.");
+                        break;
                     }
                     mLastPhysicalChannelConfigList = list;
                     boolean hasChanged = false;
@@ -1670,13 +1683,40 @@
                         mNrFrequencyChangedRegistrants.notifyRegistrants();
                         hasChanged = true;
                     }
-                    hasChanged |= RatRatcheter
-                            .updateBandwidths(getBandwidthsFromConfigs(list), mSS);
+                    int anchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
+                    if (list != null) {
+                        anchorNrCellId = list
+                                .stream()
+                                .filter(config -> config.getNetworkType()
+                                        == TelephonyManager.NETWORK_TYPE_NR
+                                        && config.getConnectionStatus()
+                                        == PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING)
+                                .map(PhysicalChannelConfig::getPhysicalCellId)
+                                .findFirst()
+                                .orElse(PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN);
+                    }
+                    int[] bandwidths = new int[0];
+                    if (list != null) {
+                        bandwidths = getBandwidthsFromLastPhysicalChannelConfigs();
+                    }
+                    if (anchorNrCellId == mLastAnchorNrCellId
+                            && anchorNrCellId != PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN) {
+                        log("Ratchet bandwidths since anchor NR cell is the same.");
+                        hasChanged |= RatRatcheter.updateBandwidths(bandwidths, mSS);
+                    } else {
+                        log("Do not ratchet bandwidths since anchor NR cell is different ("
+                                + mLastAnchorNrCellId + " -> " + anchorNrCellId
+                                + "). New bandwidths are " + Arrays.toString(bandwidths));
+                        mLastAnchorNrCellId = anchorNrCellId;
+                        hasChanged |= !Arrays.equals(mSS.getCellBandwidths(), bandwidths);
+                        mSS.setCellBandwidths(bandwidths);
+                    }
 
                     mPhone.notifyPhysicalChannelConfig(list);
                     // Notify NR frequency, NR connection status or bandwidths changed.
                     if (hasChanged) {
                         mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+                        mServiceStateChangedRegistrants.notifyRegistrants();
                         TelephonyMetrics.getInstance().writeServiceStateChanged(
                                 mPhone.getPhoneId(), mSS);
                         mPhone.getVoiceCallSessionStats().onServiceStateChanged(mSS);
@@ -1704,10 +1744,6 @@
                 rspRspMsg.sendToTarget();
                 break;
 
-            case EVENT_CARRIER_CONFIG_CHANGED:
-                onCarrierConfigChanged();
-                break;
-
             case EVENT_POLL_STATE_REQUEST:
                 pollStateInternal(false);
                 break;
@@ -1754,8 +1790,12 @@
         return simAbsent;
     }
 
-    private static int[] getBandwidthsFromConfigs(List<PhysicalChannelConfig> list) {
-        return list.stream()
+    private int[] getBandwidthsFromLastPhysicalChannelConfigs() {
+        boolean includeLte = mCarrierConfig.getBoolean(
+                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL);
+        return mLastPhysicalChannelConfigList.stream()
+                .filter(config -> includeLte
+                        || config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR)
                 .map(PhysicalChannelConfig::getCellBandwidthDownlinkKhz)
                 .mapToInt(Integer::intValue)
                 .toArray();
@@ -2092,16 +2132,20 @@
         if (physicalChannelConfigs != null) {
             for (PhysicalChannelConfig config : physicalChannelConfigs) {
                 if (isNrPhysicalChannelConfig(config) && isInternetPhysicalChannelConfig(config)) {
-                    // Update the NR frequency range if there is an internet data connection
+                    // Update the NR frequency range if there is an active internet data connection
                     // associated with this NR physical channel channel config.
-                    newFrequencyRange = ServiceState.getBetterNRFrequencyRange(
-                            newFrequencyRange, config.getFrequencyRange());
-                    break;
+                    // If there are multiple valid configs, use the highest frequency range value.
+                    newFrequencyRange = Math.max(newFrequencyRange, config.getFrequencyRange());
                 }
             }
         }
 
         boolean hasChanged = newFrequencyRange != ss.getNrFrequencyRange();
+        if (hasChanged) {
+            log(String.format("NR frequency range changed from %s to %s.",
+                    ServiceState.frequencyRangeToString(ss.getNrFrequencyRange()),
+                    ServiceState.frequencyRangeToString(newFrequencyRange)));
+        }
         ss.setNrFrequencyRange(newFrequencyRange);
         return hasChanged;
     }
@@ -2132,6 +2176,11 @@
         }
 
         boolean hasChanged = newNrState != oldNrState;
+        if (hasChanged) {
+            log(String.format("NR state changed from %s to %s.",
+                    NetworkRegistrationInfo.nrStateToString(oldNrState),
+                    NetworkRegistrationInfo.nrStateToString(newNrState)));
+        }
         regInfo.setNrState(newNrState);
         ss.addNetworkRegistrationInfo(regInfo);
         return hasChanged;
@@ -2196,8 +2245,6 @@
 
                 int registrationState = networkRegState.getNetworkRegistrationState();
                 int cssIndicator = voiceSpecificStates.cssSupported ? 1 : 0;
-                int newVoiceRat = ServiceState.networkTypeToRilRadioTechnology(
-                        networkRegState.getAccessNetworkTechnology());
                 mNewSS.setVoiceRegState(regCodeToServiceState(registrationState));
                 mNewSS.setCssIndicator(cssIndicator);
                 mNewSS.addNetworkRegistrationInfo(networkRegState);
@@ -2230,7 +2277,7 @@
                                     && !isRoamIndForHomeSystem(roamingIndicator);
                     mNewSS.setVoiceRoaming(cdmaRoaming);
                     mRoamingIndicator = roamingIndicator;
-                    mIsInPrl = (systemIsInPrl == 0) ? false : true;
+                    mIsInPrl = systemIsInPrl != 0;
                     mDefaultRoamingIndicator = defaultRoamingIndicator;
 
                     int systemId = 0;
@@ -2508,7 +2555,7 @@
             // Prioritize the PhysicalChannelConfig list because we might already be in carrier
             // aggregation by the time poll state is performed.
             if (primaryPcc != null) {
-                bandwidths = getBandwidthsFromConfigs(mLastPhysicalChannelConfigList);
+                bandwidths = getBandwidthsFromLastPhysicalChannelConfigs();
                 for (int bw : bandwidths) {
                     if (!isValidLteBandwidthKhz(bw)) {
                         loge("Invalid LTE Bandwidth in RegistrationState, " + bw);
@@ -2544,7 +2591,7 @@
             // Prioritize the PhysicalChannelConfig list because we might already be in carrier
             // aggregation by the time poll state is performed.
             if (primaryPcc != null) {
-                bandwidths = getBandwidthsFromConfigs(mLastPhysicalChannelConfigList);
+                bandwidths = getBandwidthsFromLastPhysicalChannelConfigs();
                 for (int bw : bandwidths) {
                     if (!isValidNrBandwidthKhz(bw)) {
                         loge("Invalid NR Bandwidth in RegistrationState, " + bw);
@@ -2607,8 +2654,7 @@
      */
     private boolean isRoamIndForHomeSystem(int roamInd) {
         // retrieve the carrier-specified list of ERIs for home system
-        final PersistableBundle config = getCarrierConfig();
-        int[] homeRoamIndicators = config.getIntArray(CarrierConfigManager
+        int[] homeRoamIndicators = mCarrierConfig.getIntArray(CarrierConfigManager
                     .KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY);
 
         log("isRoamIndForHomeSystem: homeRoamIndicators=" + Arrays.toString(homeRoamIndicators));
@@ -2637,8 +2683,6 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected void updateRoamingState() {
-        PersistableBundle bundle = getCarrierConfig();
-
         if (mPhone.isPhoneTypeGsm()) {
             /**
              * Since the roaming state of gsm service (from +CREG) and
@@ -2663,14 +2707,14 @@
                 roaming = false;
             }
 
-            if (alwaysOnHomeNetwork(bundle)) {
+            if (alwaysOnHomeNetwork(mCarrierConfig)) {
                 log("updateRoamingState: carrier config override always on home network");
                 roaming = false;
-            } else if (isNonRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())) {
+            } else if (isNonRoamingInGsmNetwork(mCarrierConfig, mNewSS.getOperatorNumeric())) {
                 log("updateRoamingState: carrier config override set non roaming:"
                         + mNewSS.getOperatorNumeric());
                 roaming = false;
-            } else if (isRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())) {
+            } else if (isRoamingInGsmNetwork(mCarrierConfig, mNewSS.getOperatorNumeric())) {
                 log("updateRoamingState: carrier config override set roaming:"
                         + mNewSS.getOperatorNumeric());
                 roaming = true;
@@ -2680,16 +2724,16 @@
         } else {
             String systemId = Integer.toString(mNewSS.getCdmaSystemId());
 
-            if (alwaysOnHomeNetwork(bundle)) {
+            if (alwaysOnHomeNetwork(mCarrierConfig)) {
                 log("updateRoamingState: carrier config override always on home network");
                 setRoamingOff();
-            } else if (isNonRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())
-                    || isNonRoamingInCdmaNetwork(bundle, systemId)) {
+            } else if (isNonRoamingInGsmNetwork(mCarrierConfig, mNewSS.getOperatorNumeric())
+                    || isNonRoamingInCdmaNetwork(mCarrierConfig, systemId)) {
                 log("updateRoamingState: carrier config override set non-roaming:"
                         + mNewSS.getOperatorNumeric() + ", " + systemId);
                 setRoamingOff();
-            } else if (isRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())
-                    || isRoamingInCdmaNetwork(bundle, systemId)) {
+            } else if (isRoamingInGsmNetwork(mCarrierConfig, mNewSS.getOperatorNumeric())
+                    || isRoamingInCdmaNetwork(mCarrierConfig, systemId)) {
                 log("updateRoamingState: carrier config override set roaming:"
                         + mNewSS.getOperatorNumeric() + ", " + systemId);
                 setRoamingOn();
@@ -2720,24 +2764,21 @@
         if (!mPhone.isPhoneTypeGsm() && !mSS.getRoaming()) {
             boolean hasBrandOverride = mUiccController.getUiccPort(getPhoneId()) != null
                     && mUiccController.getUiccPort(getPhoneId()).getOperatorBrandOverride() != null;
-            if (!hasBrandOverride) {
-                PersistableBundle config = getCarrierConfig();
-                if (config.getBoolean(
+            if (!hasBrandOverride && mCarrierConfig.getBoolean(
                         CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL)) {
-                    String operator = config.getString(
-                            CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING);
-                    log("updateOperatorNameFromCarrierConfig: changing from "
-                            + mSS.getOperatorAlpha() + " to " + operator);
-                    // override long and short operator name, keeping numeric the same
-                    mSS.setOperatorName(operator, operator, mSS.getOperatorNumeric());
-                }
+                String operator = mCarrierConfig.getString(
+                        CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING);
+                log("updateOperatorNameFromCarrierConfig: changing from "
+                        + mSS.getOperatorAlpha() + " to " + operator);
+                // override long and short operator name, keeping numeric the same
+                mSS.setOperatorName(operator, operator, mSS.getOperatorNumeric());
             }
         }
     }
 
     private void notifySpnDisplayUpdate(CarrierDisplayNameData data) {
         int subId = mPhone.getSubId();
-        // Update ACTION_SERVICE_PROVIDERS_UPDATED IFF any value changes
+        // Update ACTION_SERVICE_PROVIDERS_UPDATED if any value changes
         if (mSubId != subId
                 || data.shouldShowPlmn() != mCurShowPlmn
                 || data.shouldShowSpn() != mCurShowSpn
@@ -2767,22 +2808,12 @@
             SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
             mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
 
-            if (mPhone.isSubscriptionManagerServiceEnabled()) {
-                if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                    mSubscriptionManagerService.setCarrierName(subId, TextUtils.emptyIfNull(
-                            getCarrierName(data.shouldShowPlmn(), data.getPlmn(),
-                                    data.shouldShowSpn(), data.getSpn())));
-                }
-            } else {
-                if (!mSubscriptionController.setPlmnSpn(mPhone.getPhoneId(),
-                        data.shouldShowPlmn(), data.getPlmn(), data.shouldShowSpn(),
-                        data.getSpn())) {
-                    mSpnUpdatePending = true;
-                }
+            if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                mSubscriptionManagerService.setCarrierName(subId, TextUtils.emptyIfNull(
+                        getCarrierName(data.shouldShowPlmn(), data.getPlmn(),
+                                data.shouldShowSpn(), data.getSpn())));
             }
         }
-
-        mSubId = subId;
         mCurShowSpn = data.shouldShowSpn();
         mCurShowPlmn = data.shouldShowPlmn();
         mCurSpn = data.getSpn();
@@ -2820,8 +2851,8 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @VisibleForTesting
     public void updateSpnDisplay() {
-        PersistableBundle config = getCarrierConfig();
-        if (config.getBoolean(CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL)) {
+        if (mCarrierConfig.getBoolean(
+                CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL)) {
             updateSpnDisplayCdnr();
         } else {
             updateSpnDisplayLegacy();
@@ -2834,8 +2865,8 @@
         String spn = null;
         String dataSpn = null;
         boolean showSpn = false;
-        String plmn = null;
-        boolean showPlmn = false;
+        String plmn;
+        boolean showPlmn;
 
         String wfcVoiceSpnFormat = null;
         String wfcDataSpnFormat = null;
@@ -2853,20 +2884,17 @@
             //
             // 2) Show PLMN + Wi-Fi Calling if there is no valid SPN in case 1
 
-            int voiceIdx = 0;
-            int dataIdx = 0;
-            int flightModeIdx = -1;
-            boolean useRootLocale = false;
+            int voiceIdx;
+            int dataIdx;
+            int flightModeIdx;
+            boolean useRootLocale;
 
-            PersistableBundle bundle = getCarrierConfig();
-
-            voiceIdx = bundle.getInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT);
-            dataIdx = bundle.getInt(
-                    CarrierConfigManager.KEY_WFC_DATA_SPN_FORMAT_IDX_INT);
-            flightModeIdx = bundle.getInt(
+            voiceIdx = mCarrierConfig.getInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT);
+            dataIdx = mCarrierConfig.getInt(CarrierConfigManager.KEY_WFC_DATA_SPN_FORMAT_IDX_INT);
+            flightModeIdx = mCarrierConfig.getInt(
                     CarrierConfigManager.KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT);
             useRootLocale =
-                    bundle.getBoolean(CarrierConfigManager.KEY_WFC_SPN_USE_ROOT_LOCALE);
+                    mCarrierConfig.getBoolean(CarrierConfigManager.KEY_WFC_SPN_USE_ROOT_LOCALE);
 
             String[] wfcSpnFormats = SubscriptionManager.getResourcesForSubId(mPhone.getContext(),
                     mPhone.getSubId(), useRootLocale)
@@ -2897,21 +2925,19 @@
                 && (mPhone.getImsPhone() != null)
                 && (mPhone.getImsPhone().getImsRegistrationTech()
                 == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM)) {
-            // In Cros SIM Calling mode show SPN or PLMN + Cross SIM Calling
+            // In Cross SIM Calling mode show SPN or PLMN + Cross SIM Calling
             //
             // 1) Show SPN + Cross SIM Calling If SIM has SPN and SPN display condition
             //    is satisfied or SPN override is enabled for this carrier
             //
             // 2) Show PLMN + Cross SIM Calling if there is no valid SPN in case 1
-            PersistableBundle bundle = getCarrierConfig();
             int crossSimSpnFormatIdx =
-                    bundle.getInt(CarrierConfigManager.KEY_CROSS_SIM_SPN_FORMAT_INT);
+                    mCarrierConfig.getInt(CarrierConfigManager.KEY_CROSS_SIM_SPN_FORMAT_INT);
             boolean useRootLocale =
-                    bundle.getBoolean(CarrierConfigManager.KEY_WFC_SPN_USE_ROOT_LOCALE);
+                    mCarrierConfig.getBoolean(CarrierConfigManager.KEY_WFC_SPN_USE_ROOT_LOCALE);
 
             String[] crossSimSpnFormats = SubscriptionManager.getResourcesForSubId(
-                    mPhone.getContext(),
-                    mPhone.getSubId(), useRootLocale)
+                    mPhone.getContext(), mPhone.getSubId(), useRootLocale)
                     .getStringArray(R.array.crossSimSpnFormats);
 
             if (crossSimSpnFormatIdx < 0 || crossSimSpnFormatIdx >= crossSimSpnFormats.length) {
@@ -2941,7 +2967,6 @@
             //    EXTRA_SHOW_PLMN = true
             //    EXTRA_PLMN = null
 
-            IccRecords iccRecords = mIccRecords;
             int rule = getCarrierNameDisplayBitmask(mSS);
             boolean noService = false;
             if (combinedRegState == ServiceState.STATE_OUT_OF_SERVICE
@@ -2957,8 +2982,7 @@
                 } else {
                     // No service at all
                     plmn = Resources.getSystem()
-                            .getText(
-                                com.android.internal.R.string.lockscreen_carrier_default)
+                            .getText(com.android.internal.R.string.lockscreen_carrier_default)
                             .toString();
                     noService = true;
                 }
@@ -3001,8 +3025,7 @@
                 } else if (!TextUtils.isEmpty(plmn)) {
                     // Show PLMN + Cross-SIM Calling if there is no valid SPN in the above case
                     String originalPlmn = plmn.trim();
-                    PersistableBundle config = getCarrierConfig();
-                    if (mIccRecords != null && config.getBoolean(
+                    if (mIccRecords != null && mCarrierConfig.getBoolean(
                             CarrierConfigManager.KEY_WFC_CARRIER_NAME_OVERRIDE_BY_PNN_BOOL)) {
                         originalPlmn = mIccRecords.getPnnHomeName();
                     }
@@ -3027,8 +3050,7 @@
                 // Show PLMN + Wi-Fi Calling if there is no valid SPN in the above case
                 String originalPlmn = plmn.trim();
 
-                PersistableBundle config = getCarrierConfig();
-                if (mIccRecords != null && config.getBoolean(
+                if (mIccRecords != null && mCarrierConfig.getBoolean(
                         CarrierConfigManager.KEY_WFC_CARRIER_NAME_OVERRIDE_BY_PNN_BOOL)) {
                     originalPlmn = mIccRecords.getPnnHomeName();
                 }
@@ -3111,12 +3133,12 @@
     protected void setPowerStateToDesired(boolean forEmergencyCall,
             boolean isSelectedPhoneForEmergencyCall, boolean forceApply) {
         if (DBG) {
-            String tmpLog = "setPowerStateToDesired: mDeviceShuttingDown=" + mDeviceShuttingDown +
-                    ", mDesiredPowerState=" + mDesiredPowerState +
-                    ", getRadioState=" + mCi.getRadioState() +
-                    ", mRadioDisabledByCarrier=" + mRadioDisabledByCarrier +
-                    ", IMS reg state=" + mImsRegistrationOnOff +
-                    ", pending radio off=" + hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT);
+            String tmpLog = "setPowerStateToDesired: mDeviceShuttingDown=" + mDeviceShuttingDown
+                    + ", mDesiredPowerState=" + mDesiredPowerState
+                    + ", getRadioState=" + mCi.getRadioState()
+                    + ", mRadioPowerOffReasons=" + mRadioPowerOffReasons
+                    + ", IMS reg state=" + mImsRegistrationOnOff
+                    + ", pending radio off=" + hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT);
             log(tmpLog);
             mRadioPowerLog.log(tmpLog);
         }
@@ -3128,10 +3150,10 @@
         }
 
         // If we want it on and it's off, turn it on
-        if (mDesiredPowerState && !mRadioDisabledByCarrier
+        if (mDesiredPowerState && mRadioPowerOffReasons.isEmpty()
                 && (forceApply || mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF)) {
             mCi.setRadioPower(true, forEmergencyCall, isSelectedPhoneForEmergencyCall, null);
-        } else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState()
+        } else if ((!mDesiredPowerState || !mRadioPowerOffReasons.isEmpty()) && mCi.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON) {
             if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
             powerOffRadioSafely();
@@ -3148,7 +3170,6 @@
 
     /**
      * Cancel the EVENT_POWER_OFF_RADIO_DELAYED event if it is currently pending to be completed.
-     * @return true if there was a pending timeout message in the queue, false otherwise.
      */
     private void cancelDelayRadioOffWaitingForImsDeregTimeout() {
         if (hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT)) {
@@ -3157,21 +3178,6 @@
         }
     }
 
-    /**
-     * Start a timer to turn off the radio if IMS does not move to deregistered after the
-     * radio power off event occurred. If this event already exists in the message queue, then
-     * ignore the new request and use the existing one.
-     */
-    private void startDelayRadioOffWaitingForImsDeregTimeout() {
-        if (hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT)) {
-            if (DBG) log("startDelayRadioOffWaitingForImsDeregTimeout: timer exists, ignoring");
-            return;
-        }
-        if (DBG) log("startDelayRadioOffWaitingForImsDeregTimeout: starting timer");
-        sendEmptyMessageDelayed(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT,
-                getRadioPowerOffDelayTimeoutForImsRegistration());
-    }
-
     protected void onUpdateIccAvailability() {
         if (mUiccController == null ) {
             return;
@@ -3179,7 +3185,7 @@
 
         UiccCardApplication newUiccApplication = getUiccCardApplication();
 
-        if (mUiccApplcation != newUiccApplication) {
+        if (mUiccApplication != newUiccApplication) {
 
             // Remove the EF records that come from UICC
             if (mIccRecords instanceof SIMRecords) {
@@ -3188,26 +3194,26 @@
                 mCdnr.updateEfFromRuim(null /* ruim */);
             }
 
-            if (mUiccApplcation != null) {
+            if (mUiccApplication != null) {
                 log("Removing stale icc objects.");
-                mUiccApplcation.unregisterForReady(this);
+                mUiccApplication.unregisterForReady(this);
                 if (mIccRecords != null) {
                     mIccRecords.unregisterForRecordsLoaded(this);
                 }
                 mIccRecords = null;
-                mUiccApplcation = null;
+                mUiccApplication = null;
             }
             if (newUiccApplication != null) {
                 log("New card found");
-                mUiccApplcation = newUiccApplication;
-                mIccRecords = mUiccApplcation.getIccRecords();
+                mUiccApplication = newUiccApplication;
+                mIccRecords = mUiccApplication.getIccRecords();
                 if (mPhone.isPhoneTypeGsm()) {
-                    mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
+                    mUiccApplication.registerForReady(this, EVENT_SIM_READY, null);
                     if (mIccRecords != null) {
                         mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
                     }
                 } else if (mIsSubscriptionFromRuim) {
-                    mUiccApplcation.registerForReady(this, EVENT_RUIM_READY, null);
+                    mUiccApplication.registerForReady(this, EVENT_RUIM_READY, null);
                     if (mIccRecords != null) {
                         mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
                     }
@@ -3294,7 +3300,6 @@
                 + " mImsRegistrationOnOff=" + mImsRegistrationOnOff
                 + "}");
 
-
         if (mImsRegistrationOnOff && !registered) {
             // moving to deregistered, only send this event if we need to re-evaluate
             if (getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
@@ -3307,6 +3312,9 @@
             }
         }
         mImsRegistrationOnOff = registered;
+
+        // It's possible ServiceState changes did not trigger SPN display update; we update it here.
+        updateSpnDisplay();
     }
 
     public void onImsCapabilityChanged() {
@@ -3343,7 +3351,7 @@
                 nri = mNewSS.getNetworkRegistrationInfo(
                         NetworkRegistrationInfo.DOMAIN_PS,
                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-                mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+                mNewSS.setOutOfService(false);
                 // Add the IWLAN registration info back to service state.
                 if (nri != null) {
                     mNewSS.addNetworkRegistrationInfo(nri);
@@ -3360,7 +3368,7 @@
                 nri = mNewSS.getNetworkRegistrationInfo(
                         NetworkRegistrationInfo.DOMAIN_PS,
                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-                mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), true);
+                mNewSS.setOutOfService(true);
                 // Add the IWLAN registration info back to service state.
                 if (nri != null) {
                     mNewSS.addNetworkRegistrationInfo(nri);
@@ -3455,8 +3463,8 @@
         updateNrFrequencyRangeFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
         updateNrStateFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
 
-        if (TelephonyUtils.IS_DEBUGGABLE && mPhone.mTelephonyTester != null) {
-            mPhone.mTelephonyTester.overrideServiceState(mNewSS);
+        if (TelephonyUtils.IS_DEBUGGABLE && mPhone.getTelephonyTester() != null) {
+            mPhone.getTelephonyTester().overrideServiceState(mNewSS);
         }
 
         NetworkRegistrationInfo networkRegState = mNewSS.getNetworkRegistrationInfo(
@@ -3464,9 +3472,9 @@
         setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
 
         if (DBG) {
-            log("Poll ServiceState done: "
-                    + " oldSS=[" + mSS + "] newSS=[" + mNewSS + "]"
-                    + " oldMaxDataCalls=" + mMaxDataCalls
+            log("Poll ServiceState done: oldSS=" + mSS);
+            log("Poll ServiceState done: newSS=" + mNewSS);
+            log("Poll ServiceState done: oldMaxDataCalls=" + mMaxDataCalls
                     + " mNewMaxDataCalls=" + mNewMaxDataCalls
                     + " oldReasonDataDenied=" + mReasonDataDenied
                     + " mNewReasonDataDenied=" + mNewReasonDataDenied);
@@ -3487,14 +3495,10 @@
                 mSS.getState() == ServiceState.STATE_POWER_OFF
                         && mNewSS.getState() != ServiceState.STATE_POWER_OFF;
 
-        SparseBooleanArray hasDataAttached = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
-        SparseBooleanArray hasDataDetached = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
-        SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
-        SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
+        SparseBooleanArray hasDataAttached = new SparseBooleanArray();
+        SparseBooleanArray hasDataDetached = new SparseBooleanArray();
+        SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray();
+        SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray();
         boolean anyDataRegChanged = false;
         boolean anyDataRatChanged = false;
         boolean hasAlphaRawChanged =
@@ -3591,9 +3595,6 @@
 
         boolean hasCssIndicatorChanged = (mSS.getCssIndicator() != mNewSS.getCssIndicator());
 
-        boolean hasBandwidthChanged = !Arrays.equals(
-                mSS.getCellBandwidths(), mNewSS.getCellBandwidths());
-
         boolean has4gHandoff = false;
         boolean hasMultiApnSupport = false;
         boolean hasLostMultiApnSupport = false;
@@ -3637,7 +3638,6 @@
                     + " hasCssIndicatorChanged = " + hasCssIndicatorChanged
                     + " hasNrFrequencyRangeChanged = " + hasNrFrequencyRangeChanged
                     + " hasNrStateChanged = " + hasNrStateChanged
-                    + " hasBandwidthChanged = " + hasBandwidthChanged
                     + " hasAirplaneModeOnlChanged = " + hasAirplaneModeOnChanged);
         }
 
@@ -3684,7 +3684,7 @@
         ServiceState oldMergedSS = new ServiceState(mPhone.getServiceState());
         mSS = new ServiceState(mNewSS);
 
-        mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mNewSS.setOutOfService(false);
 
         mCellIdentity = primaryCellIdentity;
         if (mSS.getState() == ServiceState.STATE_IN_SERVICE && primaryCellIdentity != null) {
@@ -3730,10 +3730,6 @@
             mCssIndicatorChangedRegistrants.notifyRegistrants();
         }
 
-        if (hasBandwidthChanged) {
-            mBandwidthChangedRegistrants.notifyRegistrants();
-        }
-
         if (hasRejectCauseChanged) {
             setNotification(CS_REJECT_CAUSE_ENABLED);
         }
@@ -3982,8 +3978,9 @@
                 }
             }
 
-            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY &&
-                    mIccRecords != null && getCombinedRegState(mSS) == ServiceState.STATE_IN_SERVICE
+            if (mUiccApplication != null && mUiccApplication.getState() == AppState.APPSTATE_READY
+                    && mIccRecords != null
+                    && getCombinedRegState(mSS) == ServiceState.STATE_IN_SERVICE
                     && !ServiceState.isPsOnlyTech(mSS.getRilVoiceRadioTechnology())) {
                 // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
                 // one configured in SIM, use operator name from CSIM record. Note that ERI, SID,
@@ -4014,10 +4011,9 @@
         }
 
         String carrierName = mIccRecords != null ? mIccRecords.getServiceProviderName() : "";
-        PersistableBundle config = getCarrierConfig();
-        if (config.getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL)
+        if (mCarrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL)
                 || TextUtils.isEmpty(carrierName)) {
-            return config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
+            return mCarrierConfig.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
         }
 
         return carrierName;
@@ -4036,7 +4032,6 @@
      */
     @CarrierNameDisplayBitmask
     public int getCarrierNameDisplayBitmask(ServiceState ss) {
-        PersistableBundle config = getCarrierConfig();
         if (!TextUtils.isEmpty(getOperatorBrandOverride())) {
             // If the operator has been overridden, all PLMNs will be considered HOME PLMNs, only
             // show SPN.
@@ -4046,7 +4041,7 @@
             // This is a hack from IccRecords#getServiceProviderName().
             return CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN;
         } else {
-            boolean useRoamingFromServiceState = config.getBoolean(
+            boolean useRoamingFromServiceState = mCarrierConfig.getBoolean(
                     CarrierConfigManager.KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL);
             int carrierDisplayNameConditionFromSim =
                     mIccRecords == null ? 0 : mIccRecords.getCarrierNameDisplayCondition();
@@ -4266,8 +4261,7 @@
     private boolean isOperatorConsideredNonRoaming(ServiceState s) {
         String operatorNumeric = s.getOperatorNumeric();
 
-        PersistableBundle config = getCarrierConfig();
-        String[] numericArray = config.getStringArray(
+        String[] numericArray = mCarrierConfig.getStringArray(
                 CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY);
 
         if (ArrayUtils.isEmpty(numericArray) || operatorNumeric == null) {
@@ -4284,8 +4278,7 @@
 
     private boolean isOperatorConsideredRoaming(ServiceState s) {
         String operatorNumeric = s.getOperatorNumeric();
-        PersistableBundle config = getCarrierConfig();
-        String[] numericArray = config.getStringArray(
+        String[] numericArray = mCarrierConfig.getStringArray(
                 CarrierConfigManager.KEY_ROAMING_OPERATOR_STRING_ARRAY);
         if (ArrayUtils.isEmpty(numericArray) || operatorNumeric == null) {
             return false;
@@ -4318,12 +4311,12 @@
                     ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
                             ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
             //ignore the normal call and data restricted state before SIM READY
-            if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) {
+            if (mUiccApplication != null
+                    && mUiccApplication.getState() == AppState.APPSTATE_READY) {
                 newRs.setCsNormalRestricted(
                         ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
                                 ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
-                newRs.setPsRestricted(
-                        (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
+                newRs.setPsRestricted((state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL) != 0);
             }
 
             if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
@@ -4537,23 +4530,11 @@
         }
         Context context = mPhone.getContext();
 
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(mPhone.getSubId());
-            if (subInfo == null || !subInfo.isVisible()) {
-                log("cannot setNotification on invisible subid mSubId=" + mSubId);
-                return;
-            }
-        } else {
-            SubscriptionInfo info = mSubscriptionController
-                    .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName(),
-                            context.getAttributionTag());
-
-            //if subscription is part of a group and non-primary, suppress all notifications
-            if (info == null || (info.isOpportunistic() && info.getGroupUuid() != null)) {
-                log("cannot setNotification on invisible subid mSubId=" + mSubId);
-                return;
-            }
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(mPhone.getSubId());
+        if (subInfo == null || !subInfo.isVisible()) {
+            log("cannot setNotification on invisible subid mSubId=" + mSubId);
+            return;
         }
 
         // Needed because sprout RIL sends these when they shouldn't?
@@ -4564,10 +4545,8 @@
             return;
         }
 
-        boolean autoCancelCsRejectNotification = false;
-
-        PersistableBundle bundle = getCarrierConfig();
-        boolean disableVoiceBarringNotification = bundle.getBoolean(
+        boolean autoCancelCsRejectNotification;
+        boolean disableVoiceBarringNotification = mCarrierConfig.getBoolean(
                 CarrierConfigManager.KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
         if (disableVoiceBarringNotification && (notifyType == CS_ENABLED
                 || notifyType == CS_NORMAL_ENABLED
@@ -4575,7 +4554,7 @@
             if (DBG) log("Voice/emergency call barred notification disabled");
             return;
         }
-        autoCancelCsRejectNotification = bundle.getBoolean(
+        autoCancelCsRejectNotification = mCarrierConfig.getBoolean(
                 CarrierConfigManager.KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
 
         CharSequence details = "";
@@ -5068,9 +5047,11 @@
         }
     }
 
-    private void onCarrierConfigChanged() {
-        PersistableBundle config = getCarrierConfig();
-        log("CarrierConfigChange " + config);
+    private void onCarrierConfigurationChanged(int slotIndex) {
+        if (slotIndex != mPhone.getPhoneId()) return;
+
+        mCarrierConfig = getCarrierConfig();
+        log("CarrierConfigChange " + mCarrierConfig);
 
         // Load the ERI based on carrier config. Carrier might have their specific ERI.
         if (mEriManager != null) {
@@ -5078,8 +5059,8 @@
             mCdnr.updateEfForEri(getOperatorNameFromEri());
         }
 
-        updateOperatorNamePattern(config);
-        mCdnr.updateEfFromCarrierConfig(config);
+        updateOperatorNamePattern(mCarrierConfig);
+        mCdnr.updateEfFromCarrierConfig(mCarrierConfig);
         mPhone.notifyCallForwardingIndicator();
 
         // Sometimes the network registration information comes before carrier config is ready.
@@ -5137,8 +5118,8 @@
     // Determine if the Icc card exists
     private boolean iccCardExists() {
         boolean iccCardExist = false;
-        if (mUiccApplcation != null) {
-            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
+        if (mUiccApplication != null) {
+            iccCardExist = mUiccApplication.getState() != AppState.APPSTATE_UNKNOWN;
         }
         return iccCardExist;
     }
@@ -5341,9 +5322,8 @@
         pw.println(" mImsRegistrationOnOff=" + mImsRegistrationOnOff);
         pw.println(" pending radio off event="
                 + hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT));
-        pw.println(" mRadioDisabledByCarrier" + mRadioDisabledByCarrier);
+        pw.println(" mRadioPowerOffReasons=" + mRadioPowerOffReasons);
         pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown);
-        pw.println(" mSpnUpdatePending=" + mSpnUpdatePending);
         pw.println(" mCellInfoMinIntervalMs=" + mCellInfoMinIntervalMs);
         pw.println(" mEriManager=" + mEriManager);
 
@@ -5565,14 +5545,8 @@
         return mPhone.getPhoneId();
     }
 
-    /* Reset Service state when IWLAN is enabled as polling in airplane mode
-     * causes state to go to OUT_OF_SERVICE state instead of STATE_OFF
-     */
-
-
     /**
-     * This method adds IWLAN registration info for legacy mode devices camped on IWLAN. It also
-     * makes some adjustments when the device camps on IWLAN in airplane mode.
+     * This method makes some adjustments when the device camps on IWLAN in airplane mode.
      */
     private void processIwlanRegistrationInfo() {
         if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) {
@@ -5586,7 +5560,7 @@
             }
             // operator info should be kept in SS
             String operator = mNewSS.getOperatorAlphaLong();
-            mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), true);
+            mNewSS.setOutOfService(true);
             if (resetIwlanRatVal) {
                 mNewSS.setDataRegState(ServiceState.STATE_IN_SERVICE);
                 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
@@ -5596,17 +5570,6 @@
                         .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                         .build();
                 mNewSS.addNetworkRegistrationInfo(nri);
-                if (mAccessNetworksManager.isInLegacyMode()) {
-                    // If in legacy mode, simulate the behavior that IWLAN registration info
-                    // is reported through WWAN transport.
-                    nri = new NetworkRegistrationInfo.Builder()
-                            .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                            .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                            .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                            .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                            .build();
-                    mNewSS.addNetworkRegistrationInfo(nri);
-                }
                 mNewSS.setOperatorAlphaLong(operator);
                 // Since it's in airplane mode, cellular must be out of service. The only possible
                 // transport for data to go through is the IWLAN transport. Setting this to true
@@ -5616,31 +5579,6 @@
             }
             return;
         }
-
-        // If the device operates in legacy mode and camps on IWLAN, modem reports IWLAN as a RAT
-        // through WWAN registration info. To be consistent with the behavior with AP-assisted mode,
-        // we manually make a WLAN registration info for clients to consume. In this scenario,
-        // both WWAN and WLAN registration info are the IWLAN registration info and that's the
-        // 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()) {
-            NetworkRegistrationInfo wwanNri = mNewSS.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            if (wwanNri != null && wwanNri.getAccessNetworkTechnology()
-                    == TelephonyManager.NETWORK_TYPE_IWLAN) {
-                NetworkRegistrationInfo wlanNri = new NetworkRegistrationInfo.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                        .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                        .setRegistrationState(wwanNri.getNetworkRegistrationState())
-                        .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                        .setRejectCause(wwanNri.getRejectCause())
-                        .setEmergencyOnly(wwanNri.isEmergencyEnabled())
-                        .setAvailableServices(wwanNri.getAvailableServices())
-                        .build();
-                mNewSS.addNetworkRegistrationInfo(wlanNri);
-            }
-        }
     }
 
     /**
@@ -5898,25 +5836,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.
diff --git a/src/java/com/android/internal/telephony/SignalStrengthController.java b/src/java/com/android/internal/telephony/SignalStrengthController.java
index b2c0069..59f7333 100644
--- a/src/java/com/android/internal/telephony/SignalStrengthController.java
+++ b/src/java/com/android/internal/telephony/SignalStrengthController.java
@@ -16,12 +16,11 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+
 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;
@@ -98,7 +97,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;
@@ -143,20 +141,6 @@
     @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;
@@ -166,10 +150,12 @@
         mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
         setSignalStrengthDefaultValues();
 
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
         mCarrierConfig = getCarrierConfig();
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter);
+        // Callback which directly handle config change should be executed on handler thread
+        ccm.registerCarrierConfigChangeListener(this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) ->
+                        onCarrierConfigurationChanged(slotIndex));
     }
 
     @Override
@@ -282,11 +268,6 @@
                 break;
             }
 
-            case EVENT_CARRIER_CONFIG_CHANGED: {
-                onCarrierConfigChanged();
-                break;
-            }
-
             default:
                 log("Unhandled message with number: " + msg.what);
                 break;
@@ -358,16 +339,9 @@
                 || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS);
         if (!isStale) return false;
 
-        List<SubscriptionInfo> subInfoList;
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            subInfoList = SubscriptionManagerService.getInstance().getActiveSubscriptionInfoList(
-                    mPhone.getContext().getOpPackageName(),
-                    mPhone.getContext().getAttributionTag());
-        } else {
-            subInfoList = SubscriptionController.getInstance()
-                    .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
-                            mPhone.getContext().getAttributionTag());
-        }
+        List<SubscriptionInfo> subInfoList = SubscriptionManagerService.getInstance()
+                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
+                        mPhone.getContext().getAttributionTag());
 
         if (!ArrayUtils.isEmpty(subInfoList)) {
             for (SubscriptionInfo info : subInfoList) {
@@ -431,7 +405,7 @@
                             (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRP) != 0));
         }
 
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+        if (mPhone.getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
             int[] lteRsrqThresholds = mCarrierConfig.getIntArray(
                     CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
             if (lteRsrqThresholds != null) {
@@ -488,6 +462,18 @@
                                 AccessNetworkConstants.AccessNetworkType.NGRAN,
                                 (nrMeasurementEnabled & CellSignalStrengthNr.USE_SSSINR) != 0));
             }
+
+            int[] wcdmaEcnoThresholds = mCarrierConfig.getIntArray(
+                    CarrierConfigManager.KEY_WCDMA_ECNO_THRESHOLDS_INT_ARRAY);
+            if (wcdmaEcnoThresholds != null) {
+                signalThresholdInfos.add(
+                        createSignalThresholdsInfo(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO,
+                                wcdmaEcnoThresholds,
+                                AccessNetworkConstants.AccessNetworkType.UTRAN,
+                                false));
+            }
+
         }
 
         consolidatedAndSetReportingCriteria(signalThresholdInfos);
@@ -521,7 +507,7 @@
                         AccessNetworkConstants.AccessNetworkType.CDMA2000,
                         true));
 
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+        if (mPhone.getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
             signalThresholdInfos.add(
                     createSignalThresholdsInfo(
                             SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
@@ -554,6 +540,12 @@
                             AccessNetworkThresholds.NGRAN_SSSINR,
                             AccessNetworkConstants.AccessNetworkType.NGRAN,
                             false));
+            signalThresholdInfos.add(
+                    createSignalThresholdsInfo(
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO,
+                            AccessNetworkThresholds.UTRAN_ECNO,
+                            AccessNetworkConstants.AccessNetworkType.UTRAN,
+                            false));
         }
 
         consolidatedAndSetReportingCriteria(signalThresholdInfos);
@@ -582,12 +574,14 @@
                             measurementType,
                             mPhone.getSubId(),
                             mPhone.isDeviceIdle());
+            int hysteresisDb = getMinimumHysteresisDb(isEnabledForAppRequest, ran, measurementType,
+                    consolidatedThresholds);
             consolidatedSignalThresholdInfos.add(
                     new SignalThresholdInfo.Builder()
                             .setRadioAccessNetworkType(ran)
                             .setSignalMeasurementType(measurementType)
                             .setHysteresisMs(REPORTING_HYSTERESIS_MILLIS)
-                            .setHysteresisDb(REPORTING_HYSTERESIS_DB)
+                            .setHysteresisDb(hysteresisDb)
                             .setThresholds(consolidatedThresholds, true /*isSystem*/)
                             .setIsEnabled(isEnabledForSystem || isEnabledForAppRequest)
                             .build());
@@ -598,6 +592,126 @@
                         + consolidatedSignalThresholdInfos);
     }
 
+    /**
+     * Return the minimum hysteresis dB from all available sources:
+     * - system default
+     * - value set by client through API
+     * - threshold delta
+     */
+    @VisibleForTesting
+    public int getMinimumHysteresisDb(boolean isEnabledForAppRequest, int ran, int measurementType,
+              final int[] consolidatedThresholdList) {
+
+        int currHysteresisDb = getHysteresisDbFromCarrierConfig(ran, measurementType);
+
+        if (isEnabledForAppRequest) {
+            // Get minimum hysteresisDb at api
+            int apiHysteresisDb =
+                    getHysteresisDbFromSignalThresholdInfoRequests(ran, measurementType);
+
+            // Choose minimum of hysteresisDb between api Vs current system/cc value set
+            currHysteresisDb = Math.min(currHysteresisDb, apiHysteresisDb);
+
+            // Hal Req: choose hysteresis db value to be smaller of smallest of threshold delta
+            currHysteresisDb =  computeHysteresisDbOnSmallestThresholdDelta(
+                    currHysteresisDb, consolidatedThresholdList);
+        }
+        return currHysteresisDb;
+    }
+
+    /**
+     * Get the hysteresis db value from Signal Requests
+     * Note: Based on the current use case, there does not exist multile App signal threshold info
+     * requests with hysteresis db value, so this logic picks the latest hysteresis db value set.
+     *
+     * TODO(b/262655157): Support Multiple App Hysteresis DB value customisation
+     */
+    private int getHysteresisDbFromSignalThresholdInfoRequests(
+            @AccessNetworkConstants.RadioAccessNetworkType int ran,
+            @SignalThresholdInfo.SignalMeasurementType int measurement) {
+        int apiHysteresisDb = REPORTING_HYSTERESIS_DB;
+        for (SignalRequestRecord record : mSignalRequestRecords) {
+            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
+                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)) {
+                    if (info.getHysteresisDb() >= 0) {
+                        apiHysteresisDb = info.getHysteresisDb();
+                    }
+                }
+            }
+        }
+        return apiHysteresisDb;
+    }
+
+    private int getHysteresisDbFromCarrierConfig(int ran, int measurement) {
+        int configHysteresisDb = REPORTING_HYSTERESIS_DB;
+        String configKey = null;
+
+        switch (ran) {
+            case AccessNetworkConstants.AccessNetworkType.GERAN:
+                if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI) {
+                    configKey = CarrierConfigManager.KEY_GERAN_RSSI_HYSTERESIS_DB_INT;
+                }
+                break;
+            case AccessNetworkConstants.AccessNetworkType.UTRAN:
+                if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP) {
+                    configKey = CarrierConfigManager.KEY_UTRAN_RSCP_HYSTERESIS_DB_INT;
+                } else if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO) {
+                    configKey = CarrierConfigManager.KEY_UTRAN_ECNO_HYSTERESIS_DB_INT;
+                }
+                break;
+            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
+                if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP) {
+                    configKey = CarrierConfigManager.KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT;
+                } else if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ) {
+                    configKey = CarrierConfigManager.KEY_EUTRAN_RSRQ_HYSTERESIS_DB_INT;
+                } else if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR) {
+                    configKey = CarrierConfigManager.KEY_EUTRAN_RSSNR_HYSTERESIS_DB_INT;
+                }
+                break;
+            case AccessNetworkConstants.AccessNetworkType.NGRAN:
+                if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP) {
+                    configKey = CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT;
+                } else if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ) {
+                    configKey = CarrierConfigManager.KEY_NGRAN_SSRSRQ_HYSTERESIS_DB_INT;
+                } else if (measurement == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR) {
+                    configKey = CarrierConfigManager.KEY_NGRAN_SSSINR_HYSTERESIS_DB_INT;
+                }
+                break;
+            default:
+                localLog("No matching configuration");
+        }
+        if (configKey != null) {
+            configHysteresisDb = mCarrierConfig.getInt(configKey, REPORTING_HYSTERESIS_DB);
+        }
+        return configHysteresisDb >= SignalThresholdInfo.HYSTERESIS_DB_MINIMUM
+                ? configHysteresisDb : REPORTING_HYSTERESIS_DB;
+    }
+
+    /**
+     * This method computes the hysteresis db value between smaller of the smallest Threshold Delta
+     * and system / cc / api hysteresis db value determined.
+     *
+     * @param currMinHysteresisDb  smaller value between system / cc / api hysteresis db value
+     * @param signalThresholdInfoArray consolidated threshold info with App request consolidated.
+     * @return current minimum hysteresis db value computed between above params.
+     *
+     */
+    private int computeHysteresisDbOnSmallestThresholdDelta(
+            int currMinHysteresisDb, final int[] signalThresholdInfoArray) {
+        int index = 0;
+        if (signalThresholdInfoArray.length > 1) {
+            while (index != signalThresholdInfoArray.length - 1) {
+                if (signalThresholdInfoArray[index + 1] - signalThresholdInfoArray[index]
+                        < currMinHysteresisDb) {
+                    currMinHysteresisDb =
+                            signalThresholdInfoArray[index + 1] - signalThresholdInfoArray[index];
+                }
+                index++;
+            }
+        }
+        return currMinHysteresisDb;
+    }
+
     void setSignalStrengthDefaultValues() {
         mSignalStrength = new SignalStrength();
         mSignalStrengthUpdatedTime = System.currentTimeMillis();
@@ -987,7 +1101,9 @@
         return earfcnPairList;
     }
 
-    private void onCarrierConfigChanged() {
+    private void onCarrierConfigurationChanged(int slotIndex) {
+        if (slotIndex != mPhone.getPhoneId()) return;
+
         mCarrierConfig = getCarrierConfig();
         log("Carrier Config changed.");
 
@@ -1116,6 +1232,16 @@
                 15, /* SIGNAL_STRENGTH_GOOD */
                 30  /* SIGNAL_STRENGTH_GREAT */
         };
+
+        /**
+         * List of dBm thresholds for UTRAN {@link AccessNetworkConstants.AccessNetworkType} ECNO
+         */
+        public static final int[] UTRAN_ECNO = new int[]{
+                -24, /* SIGNAL_STRENGTH_POOR */
+                -14, /* SIGNAL_STRENGTH_MODERATE */
+                -6, /* SIGNAL_STRENGTH_GOOD */
+                1  /* SIGNAL_STRENGTH_GREAT */
+        };
     }
 
     private static void log(String msg) {
diff --git a/src/java/com/android/internal/telephony/SimIndication.java b/src/java/com/android/internal/telephony/SimIndication.java
index 20f89da..d74a9b1 100644
--- a/src/java/com/android/internal/telephony/SimIndication.java
+++ b/src/java/com/android/internal/telephony/SimIndication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
+
 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;
@@ -53,7 +55,7 @@
      * @param indicationType Type of radio indication
      */
     public void carrierInfoForImsiEncryption(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, null);
@@ -69,7 +71,7 @@
      * @param cdmaSource New CdmaSubscriptionSource
      */
     public void cdmaSubscriptionSourceChanged(int indicationType, int cdmaSource) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         int[] response = new int[]{cdmaSource};
         if (mRil.isLogOrTrace()) {
@@ -85,7 +87,7 @@
      * @param indicationType Type of radio indication
      */
     public void simPhonebookChanged(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED);
@@ -102,7 +104,7 @@
      */
     public void simPhonebookRecordsReceived(int indicationType, byte status,
             android.hardware.radio.sim.PhonebookRecordInfo[] records) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         List<SimPhonebookRecord> simPhonebookRecords = new ArrayList<>();
 
@@ -127,7 +129,7 @@
      */
     public void simRefresh(int indicationType,
             android.hardware.radio.sim.SimRefreshResult refreshResult) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         IccRefreshResponse response = new IccRefreshResponse();
         response.refreshResult = refreshResult.type;
@@ -144,7 +146,7 @@
      * @param indicationType Type of radio indication
      */
     public void simStatusChanged(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
 
@@ -159,7 +161,7 @@
      *        Refer to TS 102.223 section 9.4 for command types
      */
     public void stkEventNotify(int indicationType, String cmd) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_EVENT_NOTIFY);
 
@@ -175,7 +177,7 @@
      *        Refer to TS 102.223 section 9.4 for command types
      */
     public void stkProactiveCommand(int indicationType, String cmd) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_PROACTIVE_COMMAND);
 
@@ -189,7 +191,7 @@
      * @param indicationType Type of radio indication
      */
     public void stkSessionEnd(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_STK_SESSION_END);
 
@@ -204,7 +206,7 @@
      * @param activate false for subscription deactivated, true for subscription activated
      */
     public void subscriptionStatusChanged(int indicationType, boolean activate) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         int[] response = new int[]{activate ? 1 : 0};
 
@@ -222,7 +224,7 @@
      * @param enabled Whether uiccApplications are enabled or disabled
      */
     public void uiccApplicationsEnablementChanged(int indicationType, boolean enabled) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_SIM, indicationType);
 
         if (mRil.isLogOrTrace()) {
             mRil.unsljLogRet(RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED, enabled);
diff --git a/src/java/com/android/internal/telephony/SimResponse.java b/src/java/com/android/internal/telephony/SimResponse.java
index b0099fb..1e1dbe5 100644
--- a/src/java/com/android/internal/telephony/SimResponse.java
+++ b/src/java/com/android/internal/telephony/SimResponse.java
@@ -16,8 +16,11 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
+
 import android.hardware.radio.RadioError;
 import android.hardware.radio.RadioResponseInfo;
+import android.hardware.radio.sim.CarrierRestrictions;
 import android.hardware.radio.sim.IRadioSimResponse;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.TelephonyManager;
@@ -41,7 +44,7 @@
 
     private void responseIccIo(RadioResponseInfo responseInfo,
             android.hardware.radio.sim.IccIoResult result) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
 
         if (rr != null) {
             IccIoResult ret = new IccIoResult(result.sw1, result.sw2, result.simResponse);
@@ -68,7 +71,7 @@
      */
     public void areUiccApplicationsEnabledResponse(RadioResponseInfo responseInfo,
             boolean enabled) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
 
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
@@ -83,7 +86,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, remainingAttempts);
     }
 
     /**
@@ -91,14 +94,14 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -109,7 +112,7 @@
     public void getAllowedCarriersResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.sim.CarrierRestrictions carrierRestrictions,
             int multiSimPolicy) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
         if (rr == null) {
             return;
         }
@@ -125,7 +128,6 @@
         if (!carrierRestrictions.allowedCarriersPrioritized) {
             carrierRestrictionDefault = CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_ALLOWED;
         }
-
         ret = CarrierRestrictionRules.newBuilder()
                 .setAllowedCarriers(RILUtils.convertHalCarrierList(
                         carrierRestrictions.allowedCarriers))
@@ -133,6 +135,7 @@
                         carrierRestrictions.excludedCarriers))
                 .setDefaultCarrierRestriction(carrierRestrictionDefault)
                 .setMultiSimPolicy(policy)
+                .setCarrierRestrictionStatus(carrierRestrictions.status)
                 .build();
 
         if (responseInfo.error == RadioError.NONE) {
@@ -154,7 +157,7 @@
     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);
+                HAL_SERVICE_SIM, mRil, responseInfo, mdn, hSid, hNid, min, prl);
     }
 
     /**
@@ -162,7 +165,7 @@
      * @param source CDMA subscription source
      */
     public void getCdmaSubscriptionSourceResponse(RadioResponseInfo responseInfo, int source) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, source);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, source);
     }
 
     /**
@@ -171,7 +174,7 @@
      *        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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, response);
     }
 
     /**
@@ -180,7 +183,7 @@
      */
     public void getIccCardStatusResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.sim.CardStatus cardStatus) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
 
         if (rr != null) {
             IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus);
@@ -197,7 +200,7 @@
      * @param imsi String containing the IMSI
      */
     public void getImsiForAppResponse(RadioResponseInfo responseInfo, String imsi) {
-        RadioResponse.responseString(RIL.SIM_SERVICE, mRil, responseInfo, imsi);
+        RadioResponse.responseString(HAL_SERVICE_SIM, mRil, responseInfo, imsi);
     }
 
     /**
@@ -207,7 +210,7 @@
     public void getSimPhonebookCapacityResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.sim.PhonebookCapacity pbCapacity) {
         AdnCapacity capacity = RILUtils.convertHalPhonebookCapacity(pbCapacity);
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
                 RadioResponse.sendMessageResponse(rr.mResult, capacity);
@@ -220,14 +223,21 @@
      * @param responseInfo Response info struct containing response type, serial no. and error.
      */
     public void getSimPhonebookRecordsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
+    }
+
+    /**
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     */
+    public void iccCloseLogicalChannelWithSessionInfoResponse(RadioResponseInfo responseInfo) {
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -252,7 +262,7 @@
         for (int i = 0; i < selectResponse.length; i++) {
             arr.add((int) selectResponse[i]);
         }
-        RadioResponse.responseIntArrayList(RIL.SIM_SERVICE, mRil, responseInfo, arr);
+        RadioResponse.responseIntArrayList(HAL_SERVICE_SIM, mRil, responseInfo, arr);
     }
 
     /**
@@ -277,7 +287,7 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void reportStkServiceIsRunningResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -286,7 +296,7 @@
      */
     public void requestIccSimAuthenticationResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.sim.IccIoResult iccIo) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
 
         if (rr != null) {
             IccIoResult ret = new IccIoResult(iccIo.sw1, iccIo.sw2,
@@ -315,7 +325,7 @@
      *        string starting with first byte of response
      */
     public void sendEnvelopeResponse(RadioResponseInfo responseInfo, String commandResponse) {
-        RadioResponse.responseString(RIL.SIM_SERVICE, mRil, responseInfo, commandResponse);
+        RadioResponse.responseString(HAL_SERVICE_SIM, mRil, responseInfo, commandResponse);
     }
 
     /**
@@ -331,7 +341,7 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void sendTerminalResponseToSimResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -339,7 +349,7 @@
      */
     public void setAllowedCarriersResponse(RadioResponseInfo responseInfo) {
         int ret = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
         if (rr != null) {
             mRil.riljLog("setAllowedCarriersResponse - error = " + responseInfo.error);
 
@@ -355,14 +365,14 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void setCarrierInfoForImsiEncryptionResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -370,21 +380,21 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_SIM, mRil, responseInfo);
     }
 
     /**
@@ -392,7 +402,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, remainingAttempts);
     }
 
     /**
@@ -400,7 +410,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, remainingAttempts);
     }
 
     /**
@@ -408,7 +418,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, remainingAttempts);
     }
 
     /**
@@ -416,7 +426,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, remainingAttempts);
     }
 
     /**
@@ -428,7 +438,7 @@
     public void supplySimDepersonalizationResponse(RadioResponseInfo responseInfo, int persoType,
             int remainingRetries) {
         RadioResponse.responseInts(
-                RIL.SIM_SERVICE, mRil, responseInfo, persoType, remainingRetries);
+                HAL_SERVICE_SIM, mRil, responseInfo, persoType, remainingRetries);
     }
 
     /**
@@ -437,7 +447,7 @@
      */
     public void updateSimPhonebookRecordsResponse(RadioResponseInfo responseInfo,
             int updatedRecordIndex) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, updatedRecordIndex);
+        RadioResponse.responseInts(HAL_SERVICE_SIM, mRil, responseInfo, updatedRecordIndex);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 2f39958..ecd6276 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -260,15 +260,8 @@
      * Send tracker to appropriate (3GPP or 3GPP2) inbound SMS handler for broadcast.
      */
     private static void broadcastSms(InboundSmsTracker tracker) {
-        InboundSmsHandler handler;
         int subId = tracker.getSubId();
-        int phoneId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            phoneId = SubscriptionManagerService.getInstance().getPhoneId(subId);
-        } else {
-            // TODO consider other subs in this subId's group as well
-            phoneId = SubscriptionController.getInstance().getPhoneId(subId);
-        }
+        int phoneId = SubscriptionManagerService.getInstance().getPhoneId(subId);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             Rlog.e(TAG, "broadcastSms: ignoring message; no phone found for subId " + subId);
             return;
@@ -279,7 +272,7 @@
                     + " phoneId " + phoneId);
             return;
         }
-        handler = phone.getInboundSmsHandler(tracker.is3gpp2());
+        InboundSmsHandler handler = phone.getInboundSmsHandler(tracker.is3gpp2());
         if (handler != null) {
             handler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS, tracker);
         } else {
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index 08f7dd0..97161f8 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -18,6 +18,8 @@
 
 package com.android.internal.telephony;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
 import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission;
 
 import android.annotation.Nullable;
@@ -26,13 +28,13 @@
 import android.app.PendingIntent;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.BaseBundle;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.TelephonyServiceManager.ServiceRegisterer;
-import android.os.UserHandle;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SmsManager;
@@ -43,6 +45,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
 
@@ -156,11 +159,13 @@
         if (callingPackage == null) {
             callingPackage = getCallingPackage();
         }
+        Rlog.d(LOG_TAG, "sendDataForSubscriber caller=" + callingPackage);
 
         // Check if user is associated with the subscription
         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+                Binder.getCallingUserHandle(), destAddr)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
@@ -206,9 +211,48 @@
             String callingAttributionTag, String destAddr, String scAddr, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent,
             boolean persistMessageForNonDefaultSmsApp, long messageId) {
+        sendTextForSubscriber(subId, callingPackage, callingAttributionTag, destAddr, scAddr,
+                text, sentIntent, deliveryIntent, persistMessageForNonDefaultSmsApp, messageId,
+                false, false);
+
+    }
+
+    /**
+     * @param subId Subscription Id
+     * @param callingAttributionTag the attribution tag of the caller
+     * @param destAddr the address to send the message to
+     * @param scAddr is the service center address or null to use
+     *  the current default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is successfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK</code> for success, or relevant errors
+     *  the sentIntent may include the extra "errorCode" containing a radio technology specific
+     *  value, generally only useful for troubleshooting.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     *  raw pdu of the status report is in the extended data ("pdu").
+     * @param skipFdnCheck if set to true, FDN check must be skipped .This is set in case of STK sms
+     *
+     * @hide
+     */
+    public void sendTextForSubscriber(int subId, String callingPackage,
+            String callingAttributionTag, String destAddr, String scAddr, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent,
+            boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipFdnCheck,
+            boolean skipShortCodeCheck) {
         if (callingPackage == null) {
             callingPackage = getCallingPackage();
         }
+        Rlog.d(LOG_TAG, "sendTextForSubscriber caller=" + callingPackage);
+
+        if (skipFdnCheck || skipShortCodeCheck) {
+            if (mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.MODIFY_PHONE_STATE)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Requires MODIFY_PHONE_STATE permission.");
+            }
+        }
         if (!getSmsPermissions(subId).checkCallingCanSendText(persistMessageForNonDefaultSmsApp,
                 callingPackage, callingAttributionTag, "Sending SMS message")) {
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
@@ -216,15 +260,21 @@
         }
 
         // Check if user is associated with the subscription
-        if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+        boolean crossUserFullGranted = mContext.checkCallingOrSelfPermission(
+                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED;
+        Rlog.d(LOG_TAG, "sendTextForSubscriber: caller has INTERACT_ACROSS_USERS_FULL? "
+                + crossUserFullGranted);
+        if (!crossUserFullGranted
+                && !TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
+                Binder.getCallingUserHandle(), destAddr)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
 
         // Perform FDN check
-        if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
+        if (!skipFdnCheck && isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
             return;
         }
@@ -241,7 +291,7 @@
             sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent);
         } else {
             sendIccText(subId, callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent,
-                    persistMessageForNonDefaultSmsApp, messageId);
+                    persistMessageForNonDefaultSmsApp, messageId, skipShortCodeCheck);
         }
     }
 
@@ -258,16 +308,17 @@
 
     private void sendIccText(int subId, String callingPackage, String destAddr,
             String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessageForNonDefaultSmsApp, long messageId) {
+            boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck) {
         Rlog.d(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr"
-                + " Subscription: " + subId + " id: " + messageId);
+                + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
         if (iccSmsIntMgr != null) {
             iccSmsIntMgr.sendText(callingPackage, destAddr, scAddr, text, sentIntent,
-                    deliveryIntent, persistMessageForNonDefaultSmsApp, messageId);
+                    deliveryIntent, persistMessageForNonDefaultSmsApp, messageId,
+                    skipShortCodeCheck);
         } else {
             Rlog.e(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr is null for"
-                    + " Subscription: " + subId + " id: " + messageId);
+                    + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
         }
     }
@@ -295,11 +346,13 @@
         if (callingPackage == null) {
             callingPackage = getCallingPackage();
         }
+        Rlog.d(LOG_TAG, "sendTextForSubscriberWithOptions caller=" + callingPackage);
 
         // Check if user is associated with the subscription
         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+                Binder.getCallingUserHandle(), destAddr)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
@@ -332,11 +385,13 @@
         if (getCallingPackage() != null) {
             callingPackage = getCallingPackage();
         }
+        Rlog.d(LOG_TAG, "sendMultipartTextForSubscriber caller=" + callingPackage);
 
         // Check if user is associated with the subscription
         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+                Binder.getCallingUserHandle(), destAddr)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
@@ -354,7 +409,7 @@
                     messageId);
         } else {
             Rlog.e(LOG_TAG, "sendMultipartTextForSubscriber iccSmsIntMgr is null for"
-                    + " Subscription: " + subId + " id: " + messageId);
+                    + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
         }
     }
@@ -367,11 +422,13 @@
         if (callingPackage == null) {
             callingPackage = getCallingPackage();
         }
+        Rlog.d(LOG_TAG, "sendMultipartTextForSubscriberWithOptions caller=" + callingPackage);
 
         // Check if user is associated with the subscription
         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+                Binder.getCallingUserHandle(), destAddr)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
@@ -490,7 +547,7 @@
         // Don't show the SMS SIM Pick activity if it is not foreground.
         boolean isCallingProcessForeground = am != null
                 && am.getUidImportance(Binder.getCallingUid())
-                        == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+                == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
         if (!isCallingProcessForeground) {
             Rlog.d(LOG_TAG, "isSmsSimPickActivityNeeded: calling process not foreground. "
                     + "Suppressing activity.");
@@ -561,32 +618,19 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public int getPreferredSmsSubscription() {
-        int defaultSubId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            // If there is a default, choose that one.
-            defaultSubId = SubscriptionManagerService.getInstance().getDefaultSmsSubId();
-        } else {
-            // If there is a default, choose that one.
-            defaultSubId = SubscriptionController.getInstance().getDefaultSmsSubId();
-        }
+        // If there is a default, choose that one.
+        int defaultSubId = SubscriptionManagerService.getInstance().getDefaultSmsSubId();
+
         if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) {
             return defaultSubId;
         }
         // No default, if there is only one sub active, choose that as the "preferred" sub id.
         long token = Binder.clearCallingIdentity();
         try {
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                int[] activeSubs = SubscriptionManagerService.getInstance()
-                        .getActiveSubIdList(true /*visibleOnly*/);
-                if (activeSubs.length == 1) {
-                    return activeSubs[0];
-                }
-            } else {
-                int[] activeSubs = SubscriptionController.getInstance()
-                        .getActiveSubIdList(true /*visibleOnly*/);
-                if (activeSubs.length == 1) {
-                    return activeSubs[0];
-                }
+            int[] activeSubs = SubscriptionManagerService.getInstance()
+                    .getActiveSubIdList(true /*visibleOnly*/);
+            if (activeSubs.length == 1) {
+                return activeSubs[0];
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -614,6 +658,8 @@
             throw new SecurityException("sendStoredText: Package " + callingPkg
                     + "does not belong to " + Binder.getCallingUid());
         }
+        Rlog.d(LOG_TAG, "sendStoredText caller=" + callingPkg);
+
         if (iccSmsIntMgr != null) {
             iccSmsIntMgr.sendStoredText(callingPkg, callingAttributionTag, messageUri, scAddress,
                     sentIntent, deliveryIntent);
@@ -632,6 +678,8 @@
             throw new SecurityException("sendStoredMultipartText: Package " + callingPkg
                     + " does not belong to " + Binder.getCallingUid());
         }
+        Rlog.d(LOG_TAG, "sendStoredMultipartText caller=" + callingPkg);
+
         if (iccSmsIntMgr != null) {
             iccSmsIntMgr.sendStoredMultipartText(callingPkg, callingAttributionTag, messageUri,
                     scAddress, sentIntents, deliveryIntents);
@@ -785,6 +833,58 @@
     }
 
     @Override
+    public void setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable) {
+        Phone phone = getPhone(subId);
+        Context context;
+        if (phone != null) {
+            context = phone.getContext();
+        } else {
+            Rlog.e(LOG_TAG, "Phone Object is Null");
+            return;
+        }
+        // If it doesn't have modify phone state permission
+        // a SecurityException will be thrown.
+        if (context.checkPermission(android.Manifest
+                        .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(),
+                        Binder.getCallingUid()) != PERMISSION_GRANTED) {
+            throw new SecurityException(
+                    "setStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE");
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            phone.mSmsStorageMonitor.sendMemoryStatusOverride(isStorageAvailable);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void clearStorageMonitorMemoryStatusOverride(int subId) {
+        Phone phone = getPhone(subId);
+        Context context;
+        if (phone != null) {
+            context = phone.getContext();
+        } else {
+            Rlog.e(LOG_TAG, "Phone Object is Null");
+            return;
+        }
+        // If it doesn't have modify phone state permission
+        // a SecurityException will be thrown.
+        if (context.checkPermission(android.Manifest
+                        .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(),
+                        Binder.getCallingUid()) != PERMISSION_GRANTED) {
+            throw new SecurityException(
+                    "clearStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE");
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            phone.mSmsStorageMonitor.clearMemoryStatusOverride();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public int checkSmsShortCodeDestination(int subId, String callingPackage,
             String callingFeatureId, String destAddress, String countryIso) {
         if (callingPackage == null) {
@@ -809,17 +909,20 @@
     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
             String callingAttributionTag, int subId, String number, int port, String text,
             PendingIntent sentIntent) {
+        Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber caller=" + callingPackage);
+
         // Do not send non-emergency SMS in ECBM as it forces device to exit ECBM.
         if(getPhone(subId).isInEcm()) {
             Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber: Do not send non-emergency "
-                + "SMS in ECBM as it forces device to exit ECBM.");
+                    + "SMS in ECBM as it forces device to exit ECBM.");
             return;
         }
 
         // Check if user is associated with the subscription
         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
-                Binder.getCallingUserHandle())) {
-            // TODO(b/258629881): Display error dialog.
+                Binder.getCallingUserHandle(), number)) {
+            TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
+                    Binder.getCallingUid(), callingPackage);
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
             return;
         }
@@ -1004,7 +1107,7 @@
             }
         } else {
             Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null"
-                + " for Subscription: " + subId);
+                    + " for Subscription: " + subId);
             return true;
         }
 
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 04927ed..d2dfcac 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -20,6 +20,8 @@
 import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_NONE;
 import static com.android.internal.telephony.cdma.sms.BearerData.ERROR_TEMPORARY;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -29,19 +31,30 @@
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.AsyncResult;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.os.UserManager;
 import android.provider.Telephony.Sms;
 import android.provider.Telephony.Sms.Intents;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.DomainSelectionService;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.SmsManager;
 import android.telephony.SmsMessage;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 
 import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.cdma.CdmaInboundSmsHandler;
 import com.android.internal.telephony.cdma.CdmaSMSDispatcher;
+import com.android.internal.telephony.domainselection.DomainSelectionConnection;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.domainselection.EmergencySmsDomainSelectionConnection;
+import com.android.internal.telephony.domainselection.SmsDomainSelectionConnection;
 import com.android.internal.telephony.gsm.GsmInboundSmsHandler;
 import com.android.internal.telephony.gsm.GsmSMSDispatcher;
 import com.android.telephony.Rlog;
@@ -50,6 +63,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 /**
  *
@@ -115,6 +130,195 @@
             new HashMap<>();
 
     /**
+     * Testing interface for injecting mock DomainSelectionConnection and a flag to indicate
+     * whether the domain selection is supported.
+     */
+    @VisibleForTesting
+    public interface DomainSelectionResolverProxy {
+        /**
+         * Returns a {@link DomainSelectionConnection} created using the specified
+         * context and callback.
+         *
+         * @param phone The {@link Phone} instance.
+         * @param selectorType The domain selector type to identify the domain selection connection.
+         *                     A {@link DomainSelectionService#SELECTOR_TYPE_SMS} is used for SMS.
+         * @param isEmergency A flag to indicate whether this connection is
+         *                    for an emergency SMS or not.
+         */
+        @Nullable DomainSelectionConnection getDomainSelectionConnection(Phone phone,
+                @DomainSelectionService.SelectorType int selectorType, boolean isEmergency);
+
+        /**
+         * Checks if the device supports the domain selection service to route the call / SMS /
+         * supplementary services to the appropriate domain.
+         *
+         * @return {@code true} if the domain selection is supported on the device,
+         *         {@code false} otherwise.
+         */
+        boolean isDomainSelectionSupported();
+    }
+
+    private DomainSelectionResolverProxy mDomainSelectionResolverProxy =
+            new DomainSelectionResolverProxy() {
+                @Override
+                @Nullable
+                public DomainSelectionConnection getDomainSelectionConnection(Phone phone,
+                        @DomainSelectionService.SelectorType int selectorType,
+                        boolean isEmergency) {
+                    try {
+                        return DomainSelectionResolver.getInstance().getDomainSelectionConnection(
+                                phone, selectorType, isEmergency);
+                    } catch (IllegalStateException e) {
+                        // In general, DomainSelectionResolver is always initialized by TeleService,
+                        // but if it's not initialized (like in unit tests),
+                        // it returns null to perform the legacy behavior in this case.
+                        return null;
+                    }
+                }
+
+                @Override
+                public boolean isDomainSelectionSupported() {
+                    return DomainSelectionResolver.getInstance().isDomainSelectionSupported();
+                }
+            };
+
+    /** Stores the sending SMS information for a pending request. */
+    private class PendingRequest {
+        public static final int TYPE_DATA = 1;
+        public static final int TYPE_TEXT = 2;
+        public static final int TYPE_MULTIPART_TEXT = 3;
+        public static final int TYPE_RETRY_SMS = 4;
+
+        public final int type;
+        public final SMSDispatcher.SmsTracker tracker;
+        public final String callingPackage;
+        public final String destAddr;
+        public final String scAddr;
+        public final ArrayList<PendingIntent> sentIntents;
+        public final ArrayList<PendingIntent> deliveryIntents;
+        public final boolean isForVvm;
+        // sendData specific
+        public final byte[] data;
+        public final int destPort;
+        // sendText / sendMultipartText specific
+        public final ArrayList<String> texts;
+        public final Uri messageUri;
+        public final boolean persistMessage;
+        public final int priority;
+        public final boolean expectMore;
+        public final int validityPeriod;
+        public final long messageId;
+        public final boolean skipShortCodeCheck;
+
+        PendingRequest(int type, SMSDispatcher.SmsTracker tracker, String callingPackage,
+                String destAddr, String scAddr, ArrayList<PendingIntent> sentIntents,
+                ArrayList<PendingIntent> deliveryIntents, boolean isForVvm, byte[] data,
+                int destPort, ArrayList<String> texts, Uri messageUri, boolean persistMessage,
+                int priority, boolean expectMore, int validityPeriod, long messageId,
+                boolean skipShortCodeCheck) {
+            this.type = type;
+            this.tracker = tracker;
+            this.callingPackage = callingPackage;
+            this.destAddr = destAddr;
+            this.scAddr = scAddr;
+            this.sentIntents = sentIntents;
+            this.deliveryIntents = deliveryIntents;
+            this.isForVvm = isForVvm;
+
+            this.data = data;
+            this.destPort = destPort;
+
+            this.texts = texts;
+            this.messageUri = messageUri;
+            this.persistMessage = persistMessage;
+            this.priority = priority;
+            this.expectMore = expectMore;
+            this.validityPeriod = validityPeriod;
+            this.messageId = messageId;
+            this.skipShortCodeCheck = skipShortCodeCheck;
+        }
+    }
+
+    /**
+     * Manages the {@link DomainSelectionConnection} instance and its related information.
+     */
+    @VisibleForTesting
+    protected class DomainSelectionConnectionHolder
+            implements DomainSelectionConnection.DomainSelectionConnectionCallback {
+        private final boolean mEmergency;
+        // Manages the pending request while selecting a proper domain.
+        private final List<PendingRequest> mPendingRequests = new ArrayList<>();
+        // Manages the domain selection connections: MO SMS or emergency SMS.
+        private DomainSelectionConnection mConnection;
+
+        DomainSelectionConnectionHolder(boolean emergency) {
+            mEmergency = emergency;
+        }
+
+        /**
+         * Returns a {@link DomainSelectionConnection} instance.
+         */
+        public DomainSelectionConnection getConnection() {
+            return mConnection;
+        }
+
+        /**
+         * Returns a list of {@link PendingRequest} that was added
+         * while the domain selection is performed.
+         */
+        public List<PendingRequest> getPendingRequests() {
+            return mPendingRequests;
+        }
+
+        /**
+         * Checks whether or not the domain selection is requested.
+         * If there is no pending request, the domain selection request is needed to
+         * select a proper domain for MO SMS.
+         */
+        public boolean isDomainSelectionRequested() {
+            return !mPendingRequests.isEmpty();
+        }
+
+        /**
+         * Checks whether or not this holder is for an emergency SMS.
+         */
+        public boolean isEmergency() {
+            return mEmergency;
+        }
+
+        /**
+         * Clears all pending requests.
+         */
+        public void clearAllRequests() {
+            mPendingRequests.clear();
+        }
+
+        /**
+         * Add a new pending request.
+         */
+        public void addRequest(@NonNull PendingRequest request) {
+            mPendingRequests.add(request);
+        }
+
+        /**
+         * Sets a {@link DomainSelectionConnection} instance.
+         */
+        public void setConnection(DomainSelectionConnection connection) {
+            mConnection = connection;
+        }
+
+
+        @Override
+        public void onSelectionTerminated(@DisconnectCauses int cause) {
+            notifyDomainSelectionTerminated(this);
+        }
+    }
+
+    /** Manages the domain selection connections: MO SMS or emergency SMS. */
+    private DomainSelectionConnectionHolder mDscHolder;
+    private DomainSelectionConnectionHolder mEmergencyDscHolder;
+
+    /**
      * Puts a delivery pending tracker to the map based on the format.
      *
      * @param tracker the tracker awaiting a delivery status report.
@@ -129,6 +333,14 @@
 
     public SmsDispatchersController(Phone phone, SmsStorageMonitor storageMonitor,
             SmsUsageMonitor usageMonitor) {
+        this(phone, storageMonitor, usageMonitor, phone.getLooper());
+    }
+
+    @VisibleForTesting
+    public SmsDispatchersController(Phone phone, SmsStorageMonitor storageMonitor,
+            SmsUsageMonitor usageMonitor, Looper looper) {
+        super(looper);
+
         Rlog.d(TAG, "SmsDispatchersController created");
 
         mContext = phone.getContext();
@@ -141,9 +353,9 @@
         mImsSmsDispatcher = new ImsSmsDispatcher(phone, this, ImsManager::getConnector);
         mCdmaDispatcher = new CdmaSMSDispatcher(phone, this);
         mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
-                storageMonitor, phone);
+                storageMonitor, phone, looper);
         mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
-                storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher);
+                storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher, looper);
         mGsmDispatcher = new GsmSMSDispatcher(phone, this, mGsmInboundSmsHandler);
         SmsBroadcastUndelivered.initialize(phone.getContext(),
                 mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
@@ -188,6 +400,9 @@
         mCdmaDispatcher.dispose();
         mGsmInboundSmsHandler.dispose();
         mCdmaInboundSmsHandler.dispose();
+        // Cancels the domain selection request if it's still in progress.
+        finishDomainSelection(mDscHolder);
+        finishDomainSelection(mEmergencyDscHolder);
     }
 
     /**
@@ -242,6 +457,21 @@
         }
     }
 
+    private String getSmscAddressFromUSIMWithPhoneIdentity(String callingPkg) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            IccSmsInterfaceManager iccSmsIntMgr = mPhone.getIccSmsInterfaceManager();
+            if (iccSmsIntMgr != null) {
+                return iccSmsIntMgr.getSmscAddressFromIccEf(callingPkg);
+            } else {
+                Rlog.d(TAG, "getSmscAddressFromIccEf iccSmsIntMgr is null");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return null;
+    }
+
     private void reevaluateTimerStatus() {
         long currentTime = System.currentTimeMillis();
 
@@ -390,7 +620,12 @@
         // SMS pdus when the phone is camping on CDMA(3gpp2) network and vice versa.
         android.telephony.SmsMessage msg =
                 android.telephony.SmsMessage.createFromPdu(pdu, format);
-        injectSmsPdu(msg, format, callback, false /* ignoreClass */, isOverIms);
+        injectSmsPdu(msg, format, callback, false /* ignoreClass */, isOverIms, 0 /* unused */);
+    }
+
+    @VisibleForTesting
+    public void setImsSmsDispatcher(ImsSmsDispatcher imsSmsDispatcher) {
+        mImsSmsDispatcher = imsSmsDispatcher;
     }
 
     /**
@@ -405,7 +640,7 @@
      */
     @VisibleForTesting
     public void injectSmsPdu(SmsMessage msg, String format, SmsInjectionCallback callback,
-            boolean ignoreClass, boolean isOverIms) {
+            boolean ignoreClass, boolean isOverIms, int token) {
         Rlog.d(TAG, "SmsDispatchersController:injectSmsPdu");
         try {
             if (msg == null) {
@@ -427,7 +662,7 @@
                 Rlog.i(TAG, "SmsDispatchersController:injectSmsText Sending msg=" + msg
                         + ", format=" + format + "to mGsmInboundSmsHandler");
                 mGsmInboundSmsHandler.sendMessage(
-                        InboundSmsHandler.EVENT_INJECT_SMS, isOverIms ? 1 : 0, 0, ar);
+                        InboundSmsHandler.EVENT_INJECT_SMS, isOverIms ? 1 : 0, token, ar);
             } else if (format.equals(SmsConstants.FORMAT_3GPP2)) {
                 Rlog.i(TAG, "SmsDispatchersController:injectSmsText Sending msg=" + msg
                         + ", format=" + format + "to mCdmaInboundSmsHandler");
@@ -445,20 +680,60 @@
     }
 
     /**
+     * sets ImsManager object.
+     *
+     * @param imsManager holds a valid object or a null for setting
+     */
+    public boolean setImsManager(ImsManager imsManager) {
+        if (mGsmInboundSmsHandler != null) {
+            mGsmInboundSmsHandler.setImsManager(imsManager);
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Retry the message along to the radio.
      *
      * @param tracker holds the SMS message to send
      */
     public void sendRetrySms(SMSDispatcher.SmsTracker tracker) {
-        String oldFormat = tracker.mFormat;
         boolean retryUsingImsService = false;
 
-        if (!tracker.mUsesImsServiceForIms && mImsSmsDispatcher.isAvailable()) {
-            // If this tracker has not been handled by ImsSmsDispatcher yet and IMS Service is
-            // available now, retry this failed tracker using IMS Service.
-            retryUsingImsService = true;
+        if (!tracker.mUsesImsServiceForIms) {
+            if (mDomainSelectionResolverProxy.isDomainSelectionSupported()) {
+                DomainSelectionConnectionHolder holder = getDomainSelectionConnection(false);
+
+                // If the DomainSelectionConnection is not available,
+                // fallback to the legacy implementation.
+                if (holder != null && holder.getConnection() != null) {
+                    sendSmsUsingDomainSelection(holder,
+                            new PendingRequest(PendingRequest.TYPE_RETRY_SMS, tracker,
+                                    null, null, null, null, null, false, null, 0, null, null, false,
+                                    0, false, 0, 0L, false),
+                            "sendRetrySms");
+                    return;
+                }
+            }
+
+            if (mImsSmsDispatcher.isAvailable()) {
+                // If this tracker has not been handled by ImsSmsDispatcher yet and IMS Service is
+                // available now, retry this failed tracker using IMS Service.
+                retryUsingImsService = true;
+            }
         }
 
+        sendRetrySms(tracker, retryUsingImsService);
+    }
+
+    /**
+     * Retry the message along to the radio.
+     *
+     * @param tracker holds the SMS message to send
+     * @param retryUsingImsService a flag to indicate whether the retry SMS can use the ImsService
+     */
+    public void sendRetrySms(SMSDispatcher.SmsTracker tracker, boolean retryUsingImsService) {
+        String oldFormat = tracker.mFormat;
         // If retryUsingImsService is true, newFormat will be IMS SMS format. Otherwise, newFormat
         // will be based on voice technology.
         String newFormat =
@@ -545,6 +820,23 @@
     }
 
     /**
+     * Memory Available Event
+     * @param result callback message
+     */
+    public void reportSmsMemoryStatus(Message result) {
+        Rlog.d(TAG, "reportSmsMemoryStatus: ");
+        try {
+            mImsSmsDispatcher.onMemoryAvailable();
+            AsyncResult.forMessage(result, null, null);
+            result.sendToTarget();
+        } catch (Exception e) {
+            Rlog.e(TAG, "reportSmsMemoryStatus Failed ", e);
+            AsyncResult.forMessage(result, null, e);
+            result.sendToTarget();
+        }
+    }
+
+    /**
      * SMS over IMS is supported if IMS is registered and SMS is supported on IMS.
      *
      * @return true if SMS over IMS is supported via an IMS Service or mIms is true for the older
@@ -590,6 +882,347 @@
         return (mCdmaDispatcher.getFormat().equals(format));
     }
 
+    /** Sets a proxy interface for accessing the methods of {@link DomainSelectionResolver}. */
+    @VisibleForTesting
+    public void setDomainSelectionResolverProxy(@NonNull DomainSelectionResolverProxy proxy) {
+        mDomainSelectionResolverProxy = proxy;
+    }
+
+    /**
+     * Determines whether or not to use CDMA format for MO SMS when the domain selection uses.
+     * If the domain is {@link NetworkRegistrationInfo#DOMAIN_PS}, then format is based on
+     * IMS SMS format, otherwise format is based on current phone type.
+     *
+     * @return {@code true} if CDMA format should be used for MO SMS, {@code false} otherwise.
+     */
+    private boolean isCdmaMo(@NetworkRegistrationInfo.Domain int domain) {
+        if (domain != NetworkRegistrationInfo.DOMAIN_PS) {
+            // IMS is not registered, use voice technology to determine SMS format.
+            return (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType());
+        }
+        // IMS is registered with SMS support
+        return isCdmaFormat(mImsSmsDispatcher.getFormat());
+    }
+
+    /**
+     * Returns a {@link DomainSelectionConnectionHolder} according to the flag specified.
+     *
+     * @param emergency The flag to indicate that the domain selection is for an emergency SMS.
+     * @return A {@link DomainSelectionConnectionHolder} instance or null.
+     */
+    @VisibleForTesting
+    @Nullable
+    protected DomainSelectionConnectionHolder getDomainSelectionConnectionHolder(
+            boolean emergency) {
+        return emergency ? mEmergencyDscHolder : mDscHolder;
+    }
+
+    /**
+     * Returns a {@link DomainSelectionConnectionHolder} if the domain selection supports,
+     * return null otherwise.
+     *
+     * @param emergency The flag to indicate that the domain selection is for an emergency SMS.
+     * @return A {@link DomainSelectionConnectionHolder} that grabs the
+     *         {@link DomainSelectionConnection} and its related information to use the domain
+     *         selection architecture.
+     */
+    private DomainSelectionConnectionHolder getDomainSelectionConnection(boolean emergency) {
+        DomainSelectionConnectionHolder holder = getDomainSelectionConnectionHolder(emergency);
+        DomainSelectionConnection connection = (holder != null) ? holder.getConnection() : null;
+        boolean created = false;
+
+        if (connection == null) {
+            connection = mDomainSelectionResolverProxy.getDomainSelectionConnection(
+                    mPhone, DomainSelectionService.SELECTOR_TYPE_SMS, emergency);
+
+            if (connection == null) {
+                // Domain selection architecture is not supported.
+                // Use the legacy architecture.
+                return null;
+            }
+
+            created = true;
+        }
+
+        if (holder == null) {
+            holder = new DomainSelectionConnectionHolder(emergency);
+
+            if (emergency) {
+                mEmergencyDscHolder = holder;
+            } else {
+                mDscHolder = holder;
+            }
+        }
+
+        holder.setConnection(connection);
+
+        return holder;
+    }
+
+    /**
+     * Requests the domain selection for MO SMS.
+     *
+     * @param holder The {@link DomainSelectionConnectionHolder} that contains the
+     *               {@link DomainSelectionConnection} and its related information.
+     */
+    private void requestDomainSelection(@NonNull DomainSelectionConnectionHolder holder) {
+        DomainSelectionService.SelectionAttributes attr =
+                new DomainSelectionService.SelectionAttributes.Builder(mPhone.getPhoneId(),
+                        mPhone.getSubId(), DomainSelectionService.SELECTOR_TYPE_SMS)
+                .setEmergency(holder.isEmergency())
+                .build();
+
+        if (holder.isEmergency()) {
+            EmergencySmsDomainSelectionConnection emergencyConnection =
+                    (EmergencySmsDomainSelectionConnection) holder.getConnection();
+            CompletableFuture<Integer> future =
+                    emergencyConnection.requestDomainSelection(attr, holder);
+            future.thenAcceptAsync((domain) -> {
+                if (VDBG) {
+                    logd("requestDomainSelection(emergency): domain="
+                            + DomainSelectionService.getDomainName(domain));
+                }
+                sendAllPendingRequests(holder, domain);
+                finishDomainSelection(holder);
+            }, this::post);
+        } else {
+            SmsDomainSelectionConnection connection =
+                    (SmsDomainSelectionConnection) holder.getConnection();
+            CompletableFuture<Integer> future = connection.requestDomainSelection(attr, holder);
+            future.thenAcceptAsync((domain) -> {
+                if (VDBG) {
+                    logd("requestDomainSelection: domain="
+                            + DomainSelectionService.getDomainName(domain));
+                }
+                sendAllPendingRequests(holder, domain);
+                finishDomainSelection(holder);
+            }, this::post);
+        }
+    }
+
+    /**
+     * Sends a SMS after selecting the domain via the domain selection service.
+     *
+     * @param holder The {@link DomainSelectionConnectionHolder} that contains the
+     *               {@link DomainSelectionConnection} and its related information.
+     * @param request The {@link PendingRequest} that stores the SMS request
+     *                (data, text, multipart text) to be sent.
+     * @param logTag The log tag to display which method called this method.
+     */
+    private void sendSmsUsingDomainSelection(@NonNull DomainSelectionConnectionHolder holder,
+            @NonNull PendingRequest request, @NonNull String logTag) {
+        boolean isDomainSelectionRequested = holder.isDomainSelectionRequested();
+        // The domain selection is in progress so waits for the result of
+        // the domain selection by adding this request to the pending list.
+        holder.addRequest(request);
+
+        if (!isDomainSelectionRequested) {
+            if (VDBG) {
+                logd("requestDomainSelection: " + logTag);
+            }
+            requestDomainSelection(holder);
+        }
+    }
+
+    /**
+     * Finishes the domain selection for MO SMS.
+     *
+     * @param holder The {@link DomainSelectionConnectionHolder} object that is being finished.
+     */
+    private void finishDomainSelection(DomainSelectionConnectionHolder holder) {
+        DomainSelectionConnection connection = (holder != null) ? holder.getConnection() : null;
+
+        if (connection != null) {
+            // After this method is called, the domain selection service will clean up
+            // its resources and finish the procedure that are related to the current domain
+            // selection request.
+            connection.finishSelection();
+        }
+
+        if (holder != null) {
+            final List<PendingRequest> pendingRequests = holder.getPendingRequests();
+
+            logd("finishDomainSelection: pendingRequests=" + pendingRequests.size());
+
+            for (PendingRequest r : pendingRequests) {
+                triggerSentIntentForFailure(r.sentIntents);
+            }
+
+            holder.clearAllRequests();
+            holder.setConnection(null);
+        }
+    }
+
+    /**
+     * Notifies the application that MO SMS is not sent by the error of domain selection.
+     *
+     * @param holder The {@link DomainSelectionConnectionHolder} object that is being terminated.
+     */
+    private void notifyDomainSelectionTerminated(@NonNull DomainSelectionConnectionHolder holder) {
+        final List<PendingRequest> pendingRequests = holder.getPendingRequests();
+
+        logd("notifyDomainSelectionTerminated: pendingRequests=" + pendingRequests.size());
+
+        for (PendingRequest r : pendingRequests) {
+            triggerSentIntentForFailure(r.sentIntents);
+        }
+
+        holder.setConnection(null);
+        holder.clearAllRequests();
+    }
+
+    /**
+     * Sends all pending requests for MO SMS.
+     *
+     * @param holder The {@link DomainSelectionConnectionHolder} object that all the pending
+     *               requests are handled.
+     * @param domain The domain where the SMS is being sent, which can be one of the following:
+     *               - {@link NetworkRegistrationInfo#DOMAIN_PS}
+     *               - {@link NetworkRegistrationInfo#DOMAIN_CS}
+     */
+    private void sendAllPendingRequests(@NonNull DomainSelectionConnectionHolder holder,
+            @NetworkRegistrationInfo.Domain int domain) {
+        final List<PendingRequest> pendingRequests = holder.getPendingRequests();
+
+        if (VDBG) {
+            logd("sendAllPendingRequests: domain=" + DomainSelectionService.getDomainName(domain)
+                    + ", size=" + pendingRequests.size());
+        }
+
+        for (PendingRequest r : pendingRequests) {
+            switch (r.type) {
+                case PendingRequest.TYPE_DATA:
+                    sendData(domain, r);
+                    break;
+                case PendingRequest.TYPE_TEXT:
+                    sendText(domain, r);
+                    break;
+                case PendingRequest.TYPE_MULTIPART_TEXT:
+                    sendMultipartText(domain, r);
+                    break;
+                case PendingRequest.TYPE_RETRY_SMS:
+                    sendRetrySms(r.tracker, (domain == NetworkRegistrationInfo.DOMAIN_PS));
+                    break;
+                default:
+                    // Not reachable.
+                    break;
+            }
+        }
+
+        holder.clearAllRequests();
+    }
+
+    /**
+     * Sends a data based SMS to a specific application port.
+     *
+     * @param domain The domain where the SMS is being sent, which can be one of the following:
+     *               - {@link NetworkRegistrationInfo#DOMAIN_PS}
+     *               - {@link NetworkRegistrationInfo#DOMAIN_CS}
+     * @param request The pending request for MO SMS.
+     */
+    private void sendData(@NetworkRegistrationInfo.Domain int domain,
+            @NonNull PendingRequest request) {
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            mImsSmsDispatcher.sendData(request.callingPackage, request.destAddr, request.scAddr,
+                    request.destPort, request.data, request.sentIntents.get(0),
+                    request.deliveryIntents.get(0), request.isForVvm);
+        } else if (isCdmaMo(domain)) {
+            mCdmaDispatcher.sendData(request.callingPackage, request.destAddr, request.scAddr,
+                    request.destPort, request.data, request.sentIntents.get(0),
+                    request.deliveryIntents.get(0), request.isForVvm);
+        } else {
+            mGsmDispatcher.sendData(request.callingPackage, request.destAddr, request.scAddr,
+                    request.destPort, request.data, request.sentIntents.get(0),
+                    request.deliveryIntents.get(0), request.isForVvm);
+        }
+    }
+
+    /**
+     * Sends a text based SMS.
+     *
+     * @param domain The domain where the SMS is being sent, which can be one of the following:
+     *               - {@link NetworkRegistrationInfo#DOMAIN_PS}
+     *               - {@link NetworkRegistrationInfo#DOMAIN_CS}
+     * @param request The pending request for MO SMS.
+     */
+    private void sendText(@NetworkRegistrationInfo.Domain int domain,
+            @NonNull PendingRequest request) {
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            mImsSmsDispatcher.sendText(request.destAddr, request.scAddr, request.texts.get(0),
+                    request.sentIntents.get(0), request.deliveryIntents.get(0),
+                    request.messageUri, request.callingPackage, request.persistMessage,
+                    request.priority, false /*request.expectMore*/, request.validityPeriod,
+                    request.isForVvm, request.messageId, request.skipShortCodeCheck);
+        } else {
+            if (isCdmaMo(domain)) {
+                mCdmaDispatcher.sendText(request.destAddr, request.scAddr, request.texts.get(0),
+                        request.sentIntents.get(0), request.deliveryIntents.get(0),
+                        request.messageUri, request.callingPackage, request.persistMessage,
+                        request.priority, request.expectMore, request.validityPeriod,
+                        request.isForVvm, request.messageId, request.skipShortCodeCheck);
+            } else {
+                mGsmDispatcher.sendText(request.destAddr, request.scAddr, request.texts.get(0),
+                        request.sentIntents.get(0), request.deliveryIntents.get(0),
+                        request.messageUri, request.callingPackage, request.persistMessage,
+                        request.priority, request.expectMore, request.validityPeriod,
+                        request.isForVvm, request.messageId, request.skipShortCodeCheck);
+            }
+        }
+    }
+
+    /**
+     * Sends a multi-part text based SMS.
+     *
+     * @param domain The domain where the SMS is being sent, which can be one of the following:
+     *               - {@link NetworkRegistrationInfo#DOMAIN_PS}
+     *               - {@link NetworkRegistrationInfo#DOMAIN_CS}
+     * @param request The pending request for MO SMS.
+     */
+    private void sendMultipartText(@NetworkRegistrationInfo.Domain int domain,
+            @NonNull PendingRequest request) {
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            mImsSmsDispatcher.sendMultipartText(request.destAddr, request.scAddr, request.texts,
+                    request.sentIntents, request.deliveryIntents, request.messageUri,
+                    request.callingPackage, request.persistMessage, request.priority,
+                    false /*request.expectMore*/, request.validityPeriod, request.messageId);
+        } else {
+            if (isCdmaMo(domain)) {
+                mCdmaDispatcher.sendMultipartText(request.destAddr, request.scAddr, request.texts,
+                        request.sentIntents, request.deliveryIntents, request.messageUri,
+                        request.callingPackage, request.persistMessage, request.priority,
+                        request.expectMore, request.validityPeriod, request.messageId);
+            } else {
+                mGsmDispatcher.sendMultipartText(request.destAddr, request.scAddr, request.texts,
+                        request.sentIntents, request.deliveryIntents, request.messageUri,
+                        request.callingPackage, request.persistMessage, request.priority,
+                        request.expectMore, request.validityPeriod, request.messageId);
+            }
+        }
+    }
+
+    private void triggerSentIntentForFailure(@NonNull PendingIntent sentIntent) {
+        try {
+            sentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+        } catch (CanceledException e) {
+            logd("Intent has been canceled!");
+        }
+    }
+
+    private void triggerSentIntentForFailure(@NonNull List<PendingIntent> sentIntents) {
+        for (PendingIntent sentIntent : sentIntents) {
+            triggerSentIntentForFailure(sentIntent);
+        }
+    }
+
+    /**
+     * Creates an ArrayList object from any object.
+     */
+    private static <T> ArrayList<T> asArrayList(T object) {
+        ArrayList<T> list = new ArrayList<>();
+        list.add(object);
+        return list;
+    }
+
     /**
      * Send a data based SMS to a specific application port.
      *
@@ -671,6 +1304,26 @@
      */
     protected void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm) {
+        if (TextUtils.isEmpty(scAddr)) {
+            scAddr = getSmscAddressFromUSIMWithPhoneIdentity(callingPackage);
+        }
+
+        if (mDomainSelectionResolverProxy.isDomainSelectionSupported()) {
+            DomainSelectionConnectionHolder holder = getDomainSelectionConnection(false);
+
+            // If the DomainSelectionConnection is not available,
+            // fallback to the legacy implementation.
+            if (holder != null && holder.getConnection() != null) {
+                sendSmsUsingDomainSelection(holder,
+                        new PendingRequest(PendingRequest.TYPE_DATA, null, callingPackage,
+                                destAddr, scAddr, asArrayList(sentIntent),
+                                asArrayList(deliveryIntent), isForVvm, data, destPort, null, null,
+                                false, 0, false, 0, 0L, false),
+                        "sendData");
+                return;
+            }
+        }
+
         if (mImsSmsDispatcher.isAvailable()) {
             mImsSmsDispatcher.sendData(callingPackage, destAddr, scAddr, destPort, data, sentIntent,
                     deliveryIntent, isForVvm);
@@ -784,19 +1437,148 @@
             PendingIntent deliveryIntent, Uri messageUri, String callingPkg, boolean persistMessage,
             int priority, boolean expectMore, int validityPeriod, boolean isForVvm,
             long messageId) {
+        sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, messageUri, callingPkg,
+                persistMessage, priority, expectMore, validityPeriod, isForVvm, messageId, false);
+    }
+
+    /**
+     * Send a text based SMS.
+     *
+     * @param destAddr the address to send the message to
+     * @param scAddr is the service center address or null to use
+     *  the current default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is successfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK<code> for success,
+     *  or one of these errors:<br>
+     *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
+     *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
+     *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
+     *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
+     *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
+     *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
+     *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
+     *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
+     *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
+     *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
+     *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
+     *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
+     *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
+     *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
+     *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
+     *  <code>SmsManager.RESULT_CANCELLED</code><br>
+     *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
+     *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
+     *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
+     *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
+     *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
+     *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
+     *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
+     *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
+     *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
+     *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
+     *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
+     *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
+     *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
+     *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
+     *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
+     *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
+     *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
+     *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
+     *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
+     *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
+     *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
+     *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
+     *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
+     *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
+     *  the sentIntent may include the extra "errorCode" containing a radio technology specific
+     *  value, generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     * @param messageUri optional URI of the message if it is already stored in the system
+     * @param callingPkg the calling package name
+     * @param persistMessage whether to save the sent message into SMS DB for a
+     *  non-default SMS app.
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     * @param skipShortCodeCheck Skip check for short code type destination address.
+     */
+    public void sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent,
+            PendingIntent deliveryIntent, Uri messageUri, String callingPkg, boolean persistMessage,
+            int priority, boolean expectMore, int validityPeriod, boolean isForVvm,
+            long messageId, boolean skipShortCodeCheck) {
+        if (TextUtils.isEmpty(scAddr)) {
+            scAddr = getSmscAddressFromUSIMWithPhoneIdentity(callingPkg);
+        }
+
+        if (mDomainSelectionResolverProxy.isDomainSelectionSupported()) {
+            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+            boolean isEmergency = tm.isEmergencyNumber(destAddr);
+            DomainSelectionConnectionHolder holder = getDomainSelectionConnection(isEmergency);
+
+            // If the DomainSelectionConnection is not available,
+            // fallback to the legacy implementation.
+            if (holder != null && holder.getConnection() != null) {
+                sendSmsUsingDomainSelection(holder,
+                        new PendingRequest(PendingRequest.TYPE_TEXT, null, callingPkg,
+                                destAddr, scAddr, asArrayList(sentIntent),
+                                asArrayList(deliveryIntent), isForVvm, null, 0, asArrayList(text),
+                                messageUri, persistMessage, priority, expectMore, validityPeriod,
+                                messageId, skipShortCodeCheck),
+                        "sendText");
+                return;
+            }
+        }
+
         if (mImsSmsDispatcher.isAvailable() || mImsSmsDispatcher.isEmergencySmsSupport(destAddr)) {
             mImsSmsDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
                     messageUri, callingPkg, persistMessage, priority, false /*expectMore*/,
-                    validityPeriod, isForVvm, messageId);
+                    validityPeriod, isForVvm, messageId, skipShortCodeCheck);
         } else {
             if (isCdmaMo()) {
                 mCdmaDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
                         messageUri, callingPkg, persistMessage, priority, expectMore,
-                        validityPeriod, isForVvm, messageId);
+                        validityPeriod, isForVvm, messageId, skipShortCodeCheck);
             } else {
                 mGsmDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
                         messageUri, callingPkg, persistMessage, priority, expectMore,
-                        validityPeriod, isForVvm, messageId);
+                        validityPeriod, isForVvm, messageId, skipShortCodeCheck);
             }
         }
     }
@@ -910,6 +1692,26 @@
             ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg,
             boolean persistMessage, int priority, boolean expectMore, int validityPeriod,
             long messageId) {
+        if (TextUtils.isEmpty(scAddr)) {
+            scAddr = getSmscAddressFromUSIMWithPhoneIdentity(callingPkg);
+        }
+
+        if (mDomainSelectionResolverProxy.isDomainSelectionSupported()) {
+            DomainSelectionConnectionHolder holder = getDomainSelectionConnection(false);
+
+            // If the DomainSelectionConnection is not available,
+            // fallback to the legacy implementation.
+            if (holder != null && holder.getConnection() != null) {
+                sendSmsUsingDomainSelection(holder,
+                        new PendingRequest(PendingRequest.TYPE_MULTIPART_TEXT, null,
+                                callingPkg, destAddr, scAddr, sentIntents, deliveryIntents, false,
+                                null, 0, parts, messageUri, persistMessage, priority, expectMore,
+                                validityPeriod, messageId, false),
+                        "sendMultipartText");
+                return;
+            }
+        }
+
         if (mImsSmsDispatcher.isAvailable()) {
             mImsSmsDispatcher.sendMultipartText(destAddr, scAddr, parts, sentIntents,
                     deliveryIntents, messageUri, callingPkg, persistMessage, priority,
@@ -1066,4 +1868,8 @@
     private void logd(String msg) {
         Rlog.d(TAG, msg);
     }
+
+    private void logi(String s) {
+        Rlog.i(TAG + " [" + mPhone.getPhoneId() + "]", s);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/SmsPermissions.java b/src/java/com/android/internal/telephony/SmsPermissions.java
index 44751ac..529eea0 100644
--- a/src/java/com/android/internal/telephony/SmsPermissions.java
+++ b/src/java/com/android/internal/telephony/SmsPermissions.java
@@ -23,9 +23,11 @@
 import android.content.Intent;
 import android.os.Binder;
 import android.os.Build;
+import android.os.UserHandle;
 import android.service.carrier.CarrierMessagingService;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 /**
@@ -132,10 +134,19 @@
      */
     public boolean checkCallingOrSelfCanGetSmscAddress(String callingPackage, String message) {
         // Allow it to the default SMS app always.
-        if (!isCallerDefaultSmsPackage(callingPackage)) {
-            TelephonyPermissions
-                        .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
-                                mContext, mPhone.getSubId(), message);
+        boolean isDefaultSmsPackage;
+        int callerUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            isDefaultSmsPackage = isCallerDefaultSmsPackage(callingPackage, callerUid);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (!isDefaultSmsPackage) {
+            Rlog.d(LOG_TAG, "Caller is not a default SMS application");
+            TelephonyPermissions.
+                    enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                            mContext, mPhone.getSubId(), message);
         }
         return true;
     }
@@ -151,33 +162,49 @@
      */
     public boolean checkCallingOrSelfCanSetSmscAddress(String callingPackage, String message) {
         // Allow it to the default SMS app always.
-        if (!isCallerDefaultSmsPackage(callingPackage)) {
+        boolean isDefaultSmsPackage;
+        int callerUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            isDefaultSmsPackage = isCallerDefaultSmsPackage(callingPackage, callerUid);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (!isDefaultSmsPackage) {
+            Rlog.d(LOG_TAG, "Caller is not a default SMS application");
             // Allow it with MODIFY_PHONE_STATE or Carrier Privileges
-            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                    mContext, mPhone.getSubId(), message);
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mContext,
+                    mPhone.getSubId(), message);
         }
         return true;
     }
 
     /** Check if a package is default SMS app. */
     @VisibleForTesting
-    public boolean isCallerDefaultSmsPackage(String packageName) {
-        if (packageNameMatchesCallingUid(packageName)) {
-            return SmsApplication.isDefaultSmsApplication(mContext, packageName);
+    public boolean isCallerDefaultSmsPackage(String packageName, int callerUid) {
+        if (packageNameMatchesCallingUid(packageName, callerUid)) {
+            UserHandle userHandle = TelephonyUtils.getSubscriptionUserHandle(mContext,
+                    mPhone.getSubId());
+            return SmsApplication.isDefaultSmsApplicationAsUser(mContext, packageName, userHandle);
         }
         return false;
     }
 
+    @VisibleForTesting
+    public boolean packageNameMatchesCallingUid(String packageName) {
+        return packageNameMatchesCallingUid(packageName, Binder.getCallingUid());
+    }
+
     /**
      * Check if the passed in packageName belongs to the calling uid.
      * @param packageName name of the package to check
      * @return true if package belongs to calling uid, false otherwise
      */
     @VisibleForTesting
-    public boolean packageNameMatchesCallingUid(String packageName) {
+    public boolean packageNameMatchesCallingUid(String packageName, int callerUid) {
         try {
             ((AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE))
-                    .checkPackage(Binder.getCallingUid(), packageName);
+                    .checkPackage(callerUid, packageName);
             // If checkPackage doesn't throw an exception then we are the given package
             return true;
         } catch (SecurityException e) {
diff --git a/src/java/com/android/internal/telephony/SmsStorageMonitor.java b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
old mode 100755
new mode 100644
index 2375c73..2736f7a
--- a/src/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -18,18 +18,22 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.os.AsyncResult;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.UserHandle;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.SubscriptionManager;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 /**
@@ -40,7 +44,7 @@
  * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
  */
 public class SmsStorageMonitor extends Handler {
-    private static final String TAG = "SmsStorageMonitor";
+    private static final String TAG = "SmsStorageMonitor1";
 
     /** Maximum number of times to retry memory status reporting */
     private static final int MAX_RETRIES = 1;
@@ -83,6 +87,10 @@
     final CommandsInterface mCi;
     boolean mStorageAvailable = true;
 
+    boolean mInitialStorageAvailableStatus = true;
+
+    private boolean mMemoryStatusOverrideFlag = false;
+
     /**
      * Hold the wake lock for 5 seconds, which should be enough time for
      * any receiver(s) to grab its own wake lock.
@@ -111,6 +119,31 @@
         mContext.registerReceiver(mResultReceiver, filter);
     }
 
+    /**
+     * Overriding of the Memory Status by the TestApi and send the event to Handler to test
+     * the RP-SMMA feature
+     * @param isStorageAvailable boolean value specifies the MemoryStatus to be
+     * sent to Handler
+     */
+    public void sendMemoryStatusOverride(boolean isStorageAvailable) {
+        if (!mMemoryStatusOverrideFlag) {
+            mInitialStorageAvailableStatus = mStorageAvailable;
+            mMemoryStatusOverrideFlag = true;
+        }
+        mStorageAvailable = isStorageAvailable;
+        if (isStorageAvailable) {
+            sendMessage(obtainMessage(EVENT_REPORT_MEMORY_STATUS));
+        }
+    }
+
+    /**
+     * reset Memory Status change made by {@link #sendMemoryStatusOverride}
+     */
+    public void clearMemoryStatusOverride() {
+        mStorageAvailable = mInitialStorageAvailableStatus;
+        mMemoryStatusOverrideFlag = false;
+    }
+
     @VisibleForTesting
     public void setMaxRetries(int maxCount) {
         mMaxRetryCount = maxCount;
@@ -209,6 +242,18 @@
 
     private void sendMemoryStatusReport(boolean isAvailable) {
         mIsWaitingResponse = true;
+        Resources r = mContext.getResources();
+        if (r.getBoolean(com.android.internal.R.bool.config_smma_notification_supported_over_ims)) {
+            IccSmsInterfaceManager smsIfcMngr = mPhone.getIccSmsInterfaceManager();
+            if (smsIfcMngr != null) {
+                Rlog.d(TAG, "sendMemoryStatusReport: smsIfcMngr is available");
+                if (smsIfcMngr.mDispatchersController.isIms() && isAvailable) {
+                    smsIfcMngr.mDispatchersController.reportSmsMemoryStatus(
+                            obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+                    return;
+                }
+            }
+        }
         mCi.reportSmsMemoryStatus(isAvailable, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
     }
 
@@ -223,9 +268,14 @@
      * that SIM storage for SMS messages is full.
      */
     private void handleIccFull() {
+        UserHandle userHandle = TelephonyUtils.getSubscriptionUserHandle(mContext,
+                mPhone.getSubId());
+        ComponentName componentName = SmsApplication.getDefaultSimFullApplicationAsUser(mContext,
+                false, userHandle);
+
         // broadcast SIM_FULL intent
         Intent intent = new Intent(Intents.SIM_FULL_ACTION);
-        intent.setComponent(SmsApplication.getDefaultSimFullApplication(mContext, false));
+        intent.setComponent(componentName);
         mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
         SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
         mContext.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS);
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index 8bcdc07..8e4ac60 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -43,6 +43,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -73,6 +74,8 @@
 
     private static final String SHORT_CODE_PATH = "/data/misc/sms/codes";
 
+    private static final String SHORT_CODE_VERSION_PATH = "/data/misc/sms/metadata/version";
+
     /** Default checking period for SMS sent without user permission. */
     private static final int DEFAULT_SMS_CHECK_PERIOD = 60000;      // 1 minute
 
@@ -128,6 +131,8 @@
     /** Last modified time for pattern file */
     private long mPatternFileLastModified = 0;
 
+    private int mPatternFileVersion = -1;
+
     private RoleManager mRoleManager;
 
     /** Directory for per-app SMS permission XML file. */
@@ -415,9 +420,11 @@
                     if (mPatternFile.exists()) {
                         if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from file");
                         mCurrentPatternMatcher = getPatternMatcherFromFile(countryIso);
+                        mPatternFileVersion = getPatternFileVersionFromFile();
                     } else {
                         if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from resource");
                         mCurrentPatternMatcher = getPatternMatcherFromResource(countryIso);
+                        mPatternFileVersion = -1;
                     }
                     mCurrentCountry = countryIso;
                 }
@@ -655,6 +662,37 @@
         return false;
     }
 
+    private int getPatternFileVersionFromFile() {
+        File versionFile = new File(SHORT_CODE_VERSION_PATH);
+        if (versionFile.exists()) {
+            BufferedReader reader = null;
+            try {
+                reader = new BufferedReader(new FileReader(versionFile));
+                String version = reader.readLine();
+                if (version != null) {
+                    return Integer.parseInt(version);
+                }
+            } catch (IOException e) {
+                Rlog.e(TAG, "File reader exception reading short code "
+                        + "pattern file version", e);
+            } finally {
+                try {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                } catch (IOException e) {
+                    Rlog.e(TAG, "File reader exception closing short code "
+                            + "pattern file version reader", e);
+                }
+            }
+        }
+        return -1;
+    }
+
+    public int getShortCodeXmlFileVersion() {
+        return mPatternFileVersion;
+    }
+
     private static void log(String msg) {
         Rlog.d(TAG, msg);
     }
diff --git a/src/java/com/android/internal/telephony/SrvccConnection.java b/src/java/com/android/internal/telephony/SrvccConnection.java
new file mode 100644
index 0000000..f25a15c
--- /dev/null
+++ b/src/java/com/android/internal/telephony/SrvccConnection.java
@@ -0,0 +1,260 @@
+/*
+ * 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;
+
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ACTIVE;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ALERTING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_DIALING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_HOLDING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING_SETUP;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_WAITING;
+
+import android.net.Uri;
+import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsStreamMediaProfile;
+import android.text.TextUtils;
+
+import com.android.ims.internal.ConferenceParticipant;
+import com.android.internal.telephony.imsphone.ImsPhoneConnection;
+import com.android.telephony.Rlog;
+
+/**
+ * Connection information for SRVCC
+ */
+public class SrvccConnection {
+    private static final String TAG = "SrvccConnection";
+
+    public static final int CALL_TYPE_NORMAL = 0;
+    public static final int CALL_TYPE_EMERGENCY = 1;
+
+    public static final int SUBSTATE_NONE = 0;
+    /** Pre-alerting state. Applicable for MT calls only */
+    public static final int SUBSTATE_PREALERTING = 1;
+
+    public static final int TONE_NONE = 0;
+    public static final int TONE_LOCAL = 1;
+    public static final int TONE_NETWORK = 2;
+
+    /** Values are CALL_TYPE_ */
+    private int mType = CALL_TYPE_NORMAL;
+
+    /** Values are Call.State */
+    private Call.State mState;
+
+    /** Values are SUBSTATE_ */
+    private int mSubstate = SUBSTATE_NONE;
+
+    /** Values are TONE_ */
+    private int mRingbackToneType = TONE_NONE;
+
+    /** true if it is a multi-party call */
+    private boolean mIsMpty = false;
+
+    /** true if it is a mobile terminated call */
+    private boolean mIsMT;
+
+    /** Remote party nummber */
+    private String mNumber;
+
+    /** Values are PhoneConstants.PRESENTATION_ */
+    private int mNumPresentation;
+
+    /** Remote party name */
+    private String mName;
+
+    /** Values are PhoneConstants.PRESENTATION_ */
+    private int mNamePresentation;
+
+    public SrvccConnection(ImsCallProfile profile,
+            ImsPhoneConnection c, @PreciseCallStates int preciseCallState) {
+        mState = toCallState(preciseCallState);
+        if (mState == Call.State.ALERTING) {
+            mRingbackToneType = isLocalTone(profile) ? TONE_LOCAL : TONE_NETWORK;
+        }
+        if (preciseCallState == PRECISE_CALL_STATE_INCOMING_SETUP) {
+            mSubstate = SUBSTATE_PREALERTING;
+        }
+
+        if (c == null) {
+            initialize(profile);
+        } else {
+            initialize(c);
+        }
+    }
+
+    public SrvccConnection(ConferenceParticipant cp, @PreciseCallStates int preciseCallState) {
+        Rlog.d(TAG, "initialize with ConferenceParticipant");
+        mState = toCallState(preciseCallState);
+        mIsMT = cp.getCallDirection() == android.telecom.Call.Details.DIRECTION_INCOMING;
+        mNumber = getParticipantAddress(cp.getHandle());
+        mNumPresentation = cp.getParticipantPresentation();
+        if (mNumPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+            mNumber = "";
+        }
+        mName = cp.getDisplayName();
+        if (!TextUtils.isEmpty(mName)) {
+            mNamePresentation = PhoneConstants.PRESENTATION_ALLOWED;
+        } else {
+            mNamePresentation = PhoneConstants.PRESENTATION_UNKNOWN;
+        }
+        mIsMpty = true;
+    }
+
+    private static String getParticipantAddress(Uri address) {
+        if (address == null) {
+            return null;
+        }
+
+        String number = address.getSchemeSpecificPart();
+        if (TextUtils.isEmpty(number)) {
+            return null;
+        }
+
+        String[] numberParts = number.split("[@;:]");
+        if (numberParts.length == 0) return null;
+
+        return numberParts[0];
+    }
+
+    // MT call in alerting or prealerting state
+    private void initialize(ImsCallProfile profile) {
+        Rlog.d(TAG, "initialize with ImsCallProfile");
+        mIsMT = true;
+        mNumber = profile.getCallExtra(ImsCallProfile.EXTRA_OI);
+        mName = profile.getCallExtra(ImsCallProfile.EXTRA_CNA);
+        mNumPresentation = ImsCallProfile.OIRToPresentation(
+                profile.getCallExtraInt(ImsCallProfile.EXTRA_OIR));
+        mNamePresentation = ImsCallProfile.OIRToPresentation(
+                profile.getCallExtraInt(ImsCallProfile.EXTRA_CNAP));
+    }
+
+    private void initialize(ImsPhoneConnection c) {
+        Rlog.d(TAG, "initialize with ImsPhoneConnection");
+        if (c.isEmergencyCall()) {
+            mType = CALL_TYPE_EMERGENCY;
+        }
+        mIsMT = c.isIncoming();
+        mNumber = c.getAddress();
+        mNumPresentation = c.getNumberPresentation();
+        mName = c.getCnapName();
+        mNamePresentation = c.getCnapNamePresentation();
+    }
+
+    private boolean isLocalTone(ImsCallProfile profile) {
+        if (profile == null) return false;
+
+        ImsStreamMediaProfile mediaProfile = profile.getMediaProfile();
+        if (mediaProfile == null) return false;
+
+        boolean shouldPlayRingback =
+                (mediaProfile.getAudioDirection() == ImsStreamMediaProfile.DIRECTION_INACTIVE)
+                        ? true : false;
+        return shouldPlayRingback;
+    }
+
+    private static Call.State toCallState(int preciseCallState) {
+        switch (preciseCallState) {
+            case PRECISE_CALL_STATE_ACTIVE: return Call.State.ACTIVE;
+            case PRECISE_CALL_STATE_HOLDING: return Call.State.HOLDING;
+            case PRECISE_CALL_STATE_DIALING: return Call.State.DIALING;
+            case PRECISE_CALL_STATE_ALERTING: return Call.State.ALERTING;
+            case PRECISE_CALL_STATE_INCOMING: return Call.State.INCOMING;
+            case PRECISE_CALL_STATE_WAITING: return Call.State.WAITING;
+            case PRECISE_CALL_STATE_INCOMING_SETUP: return Call.State.INCOMING;
+            default:
+        }
+        return Call.State.DISCONNECTED;
+    }
+
+    /** Returns the type of the call */
+    public int getType() {
+        return mType;
+    }
+
+    /** Returns the state */
+    public Call.State getState() {
+        return mState;
+    }
+
+    /** Updates the state */
+    public void setState(Call.State state) {
+        mState = state;
+    }
+
+    /** Returns the sub state */
+    public int getSubState() {
+        return mSubstate;
+    }
+
+    /** Returns the ringback tone type */
+    public int getRingbackToneType() {
+        return mRingbackToneType;
+    }
+
+    /** true if it is a multi-party call */
+    public boolean isMultiParty() {
+        return mIsMpty;
+    }
+
+    /** true if it is a mobile terminated call */
+    public boolean isIncoming() {
+        return mIsMT;
+    }
+
+    /** Returns the remote party nummber */
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /** Returns the number presentation */
+    public int getNumberPresentation() {
+        return mNumPresentation;
+    }
+
+    /** Returns the remote party name */
+    public String getName() {
+        return mName;
+    }
+
+    /** Returns the name presentation */
+    public int getNamePresentation() {
+        return mNamePresentation;
+    }
+
+    /**
+     * Build a human representation of a connection instance, suitable for debugging.
+     * Don't log personal stuff unless in debug mode.
+     * @return a string representing the internal state of this connection.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(" type:").append(getType());
+        sb.append(", state:").append(getState());
+        sb.append(", subState:").append(getSubState());
+        sb.append(", toneType:").append(getRingbackToneType());
+        sb.append(", mpty:").append(isMultiParty());
+        sb.append(", incoming:").append(isIncoming());
+        sb.append(", numberPresentation:").append(getNumberPresentation());
+        sb.append(", number:").append(Rlog.pii(TAG, getNumber()));
+        sb.append(", namePresentation:").append(getNamePresentation());
+        sb.append(", name:").append(Rlog.pii(TAG, getName()));
+        return sb.toString();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
deleted file mode 100644
index 0abd677..0000000
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ /dev/null
@@ -1,4991 +0,0 @@
-/*
-* Copyright (C) 2014 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-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;
-import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.app.compat.CompatChanges;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ContentResolver;
-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.net.Uri;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Handler;
-import android.os.ParcelUuid;
-import android.os.PersistableBundle;
-import android.os.RegistrantList;
-import android.os.RemoteException;
-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;
-import android.telephony.CarrierConfigManager;
-import android.telephony.RadioAccessFamily;
-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;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.ims.ImsManager;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.data.PhoneSwitcher;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.subscription.SubscriptionManagerService;
-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.UiccProfile;
-import com.android.internal.telephony.uicc.UiccSlot;
-import com.android.internal.telephony.util.ArrayUtils;
-import com.android.internal.telephony.util.TelephonyUtils;
-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.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.stream.Collectors;
-
-/**
- * Implementation of the ISub interface.
- *
- * Any setters which take subId, slotIndex or phoneId as a parameter will throw an exception if the
- * parameter equals the corresponding INVALID_XXX_ID or DEFAULT_XXX_ID.
- *
- * All getters will lookup the corresponding default if the parameter is DEFAULT_XXX_ID. Ie calling
- * getPhoneId(DEFAULT_SUB_ID) will return the same as getPhoneId(getDefaultSubId()).
- *
- * Finally, any getters which perform the mapping between subscriptions, slots and phones will
- * return the corresponding INVALID_XXX_ID if the parameter is INVALID_XXX_ID. All other getters
- * will fail and return the appropriate error value. Ie calling
- * getSlotIndex(INVALID_SUBSCRIPTION_ID) will return INVALID_SIM_SLOT_INDEX and calling
- * getSubInfoForSubscriber(INVALID_SUBSCRIPTION_ID) will return null.
- *
- */
-public class SubscriptionController extends ISub.Stub {
-    private static final String LOG_TAG = "SubscriptionController";
-    private static final boolean DBG = false;
-    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 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;
-
-    // Lock that both mCacheActiveSubInfoList and mCacheOpportunisticSubInfoList use.
-    private Object mSubInfoListLock = new Object();
-
-    /* The Cache of Active SubInfoRecord(s) list of currently in use SubInfoRecord(s) */
-    private final List<SubscriptionInfo> mCacheActiveSubInfoList = new ArrayList<>();
-
-    /* Similar to mCacheActiveSubInfoList but only caching opportunistic subscriptions. */
-    private List<SubscriptionInfo> mCacheOpportunisticSubInfoList = new ArrayList<>();
-    private AtomicBoolean mOpptSubInfoListChangedDirtyBit = new AtomicBoolean();
-
-    private static final Comparator<SubscriptionInfo> SUBSCRIPTION_INFO_COMPARATOR =
-            (arg0, arg1) -> {
-                // Primary sort key on SimSlotIndex
-                int flag = arg0.getSimSlotIndex() - arg1.getSimSlotIndex();
-                if (flag == 0) {
-                    // Secondary sort on SubscriptionId
-                    return arg0.getSubscriptionId() - arg1.getSubscriptionId();
-                }
-                return flag;
-            };
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected final Object mLock = new Object();
-
-    /** The singleton instance. */
-    protected static SubscriptionController sInstance = null;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected Context mContext;
-    protected TelephonyManager mTelephonyManager;
-    protected UiccController mUiccController;
-
-    /**
-     * Apps targeting on Android T and beyond will get an empty list if there is no access to device
-     * identifiers nor has carrier privileges when calling
-     * SubscriptionManager#getSubscriptionsInGroup.
-     */
-    @ChangeId
-    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
-    public static final long REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID = 213902861L;
-
-    private AppOpsManager mAppOps;
-
-    // Each slot can have multiple subs.
-    private static class WatchedSlotIndexToSubIds {
-        private final Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds =
-                new ConcurrentHashMap<>();
-
-        public void clear() {
-            mSlotIndexToSubIds.clear();
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        }
-
-        public Set<Entry<Integer, ArrayList<Integer>>> entrySet() {
-            return mSlotIndexToSubIds.entrySet();
-        }
-
-        // Force all updates to data structure through wrapper.
-        public ArrayList<Integer> getCopy(int slotIndex) {
-            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
-            if (subIdList == null) {
-                return null;
-            }
-
-            return new ArrayList<>(subIdList);
-        }
-
-        public void put(int slotIndex, ArrayList<Integer> value) {
-            mSlotIndexToSubIds.put(slotIndex, value);
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        }
-
-        public void remove(int slotIndex) {
-            mSlotIndexToSubIds.remove(slotIndex);
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        }
-
-        public int size() {
-            return mSlotIndexToSubIds.size();
-        }
-
-        @VisibleForTesting
-        public Map<Integer, ArrayList<Integer>> getMap() {
-            return mSlotIndexToSubIds;
-        }
-
-        public int removeFromSubIdList(int slotIndex, int subId) {
-            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
-            if (subIdList == null) {
-                return NO_ENTRY_FOR_SLOT_INDEX;
-            } else {
-                if (subIdList.contains(subId)) {
-                    subIdList.remove(new Integer(subId));
-                    if (subIdList.isEmpty()) {
-                        mSlotIndexToSubIds.remove(slotIndex);
-                    }
-                    invalidateDefaultSubIdCaches();
-                    invalidateSlotIndexCaches();
-                    return SUB_ID_FOUND;
-                } else {
-                    return SUB_ID_NOT_IN_SLOT;
-                }
-            }
-        }
-
-        public void addToSubIdList(int slotIndex, Integer value) {
-            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
-            if (subIdList == null) {
-                subIdList = new ArrayList<Integer>();
-                subIdList.add(value);
-                mSlotIndexToSubIds.put(slotIndex, subIdList);
-            } else {
-                subIdList.add(value);
-            }
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        }
-
-        public void clearSubIdList(int slotIndex) {
-            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
-            if (subIdList != null) {
-                subIdList.clear();
-                invalidateDefaultSubIdCaches();
-                invalidateSlotIndexCaches();
-            }
-        }
-    }
-
-    public static class WatchedInt {
-        private int mValue;
-
-        public WatchedInt(int initialValue) {
-            mValue = initialValue;
-        }
-
-        public int get() {
-            return mValue;
-        }
-
-        public void set(int newValue) {
-            mValue = newValue;
-        }
-    }
-
-    private final WatchedSlotIndexToSubIds mSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
-
-    private final WatchedInt mDefaultFallbackSubId =
-            new WatchedInt(SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-        @Override
-        public void set(int newValue) {
-            super.set(newValue);
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        }
-    };
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private static int mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private int[] colorArr;
-    private long mLastISubServiceRegTime;
-    private RegistrantList mUiccAppsEnableChangeRegList = new RegistrantList();
-
-    // The properties that should be shared and synced across grouped subscriptions.
-    private static final Set<String> GROUP_SHARING_PROPERTIES = new HashSet<>(Arrays.asList(
-            SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
-            SubscriptionManager.VT_IMS_ENABLED,
-            SubscriptionManager.WFC_IMS_ENABLED,
-            SubscriptionManager.WFC_IMS_MODE,
-            SubscriptionManager.WFC_IMS_ROAMING_MODE,
-            SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
-            SubscriptionManager.DATA_ROAMING,
-            SubscriptionManager.DISPLAY_NAME,
-            SubscriptionManager.ENABLED_MOBILE_DATA_POLICIES,
-            SubscriptionManager.UICC_APPLICATIONS_ENABLED,
-            SubscriptionManager.IMS_RCS_UCE_ENABLED,
-            SubscriptionManager.CROSS_SIM_CALLING_ENABLED,
-            SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
-            SubscriptionManager.USER_HANDLE
-    ));
-
-    public static SubscriptionController init(Context c) {
-        synchronized (SubscriptionController.class) {
-            if (sInstance == null) {
-                sInstance = new SubscriptionController(c);
-            } else {
-                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
-            }
-            return sInstance;
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static SubscriptionController getInstance() {
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            throw new RuntimeException("getInstance should not be called.");
-        }
-        if (sInstance == null) {
-            Log.wtf(LOG_TAG, "getInstance null");
-        }
-
-        return sInstance;
-    }
-
-    protected SubscriptionController(Context c) {
-        internalInit(c);
-        migrateImsSettings();
-    }
-
-    protected void internalInit(Context c) {
-        mContext = c;
-        mTelephonyManager = TelephonyManager.from(mContext);
-
-        try {
-            mUiccController = UiccController.getInstance();
-        } catch(RuntimeException ex) {
-            throw new RuntimeException(
-                    "UiccController has to be initialised before SubscriptionController init");
-        }
-
-        mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
-
-        ServiceRegisterer subscriptionServiceRegisterer = TelephonyFrameworkInitializer
-                .getTelephonyServiceManager()
-                .getSubscriptionServiceRegisterer();
-        if (subscriptionServiceRegisterer.get() == null) {
-            subscriptionServiceRegisterer.register(this);
-            mLastISubServiceRegTime = System.currentTimeMillis();
-        }
-
-        // clear SLOT_INDEX for all subs
-        clearSlotIndexForSubInfoRecords();
-
-        // Cache Setting values
-        cacheSettingValues();
-
-        // Initial invalidate activates caching.
-        invalidateDefaultSubIdCaches();
-        invalidateDefaultDataSubIdCaches();
-        invalidateDefaultSmsSubIdCaches();
-        invalidateActiveDataSubIdCaches();
-        invalidateSlotIndexCaches();
-
-        mContext.getContentResolver().registerContentObserver(
-                SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI, false,
-                new ContentObserver(new Handler()) {
-                    @Override
-                    public void onChange(boolean selfChange, Uri uri) {
-                        if (uri.equals(SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI)) {
-                            refreshCachedActiveSubscriptionInfoList();
-                            notifySubscriptionInfoChanged();
-
-                            SubscriptionManager subManager = SubscriptionManager.from(mContext);
-                            for (SubscriptionInfo subInfo : getActiveSubscriptionInfoList(
-                                    mContext.getOpPackageName(), mContext.getAttributionTag())) {
-                                if (SubscriptionController.getInstance()
-                                        .isActiveSubId(subInfo.getSubscriptionId())) {
-                                    ImsManager imsManager = ImsManager.getInstance(mContext,
-                                            subInfo.getSimSlotIndex());
-                                    imsManager.updateImsServiceConfig();
-                                }
-                            }
-                        }
-                    }
-                });
-
-        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
-
-        if (DBG) logdl("[SubscriptionController] init by Context");
-    }
-
-    /**
-     * Should only be triggered once.
-     */
-    public void notifySubInfoReady() {
-        // broadcast default subId.
-        sendDefaultChangedBroadcast(SubscriptionManager.getDefaultSubscriptionId());
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private boolean isSubInfoReady() {
-        return SubscriptionInfoUpdater.isSubInfoInitialized();
-    }
-
-    /**
-     * This function marks SIM_SLOT_INDEX as INVALID for all subscriptions in the database. This
-     * should be done as part of initialization.
-     *
-     * TODO: SIM_SLOT_INDEX is based on current state and should not even be persisted in the
-     * database.
-     */
-    private void clearSlotIndexForSubInfoRecords() {
-        if (mContext == null) {
-            logel("[clearSlotIndexForSubInfoRecords] TelephonyManager or mContext is null");
-            return;
-        }
-
-        // Update all subscriptions in simInfo db with invalid slot index
-        ContentValues value = new ContentValues(1);
-        value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value, null, null);
-    }
-
-    /**
-     * Cache the Settings values by reading these values from Setting from disk to prevent disk I/O
-     * access during the API calling. This is based on an assumption that the Settings system will
-     * itself cache this value after the first read and thus only the first read after boot will
-     * access the disk.
-     */
-    private void cacheSettingValues() {
-        Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION,
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION,
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected void enforceModifyPhoneState(String message) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE, message);
-    }
-
-    private void enforceReadPrivilegedPhoneState(String message) {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
-    }
-
-    private void enforceManageSubscriptionUserAssociation(String message) {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION, message);
-    }
-
-    /**
-     * Returns whether the {@code callingPackage} has access to subscriber identifiers on the
-     * specified {@code subId} using the provided {@code message} in any resulting
-     * SecurityException.
-     */
-    private boolean hasSubscriberIdentifierAccess(int subId, String callingPackage,
-            String callingFeatureId, String message, boolean reportFailure) {
-        try {
-            return TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mContext, subId,
-                    callingPackage, callingFeatureId, message, reportFailure);
-        } catch (SecurityException e) {
-            // A SecurityException indicates that the calling package is targeting at least the
-            // minimum level that enforces identifier access restrictions and the new access
-            // requirements are not met.
-            return false;
-        }
-    }
-
-    /**
-     * Returns whether the {@code callingPackage} has access to the phone number on the specified
-     * {@code subId} using the provided {@code message} in any resulting SecurityException.
-     */
-    private boolean hasPhoneNumberAccess(int subId, String callingPackage, String callingFeatureId,
-            String message) {
-        try {
-            return TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(mContext, subId,
-                    callingPackage, callingFeatureId, message);
-        } catch (SecurityException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Notify the changed of subscription info.
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public void notifySubscriptionInfoChanged() {
-        TelephonyRegistryManager trm =
-                (TelephonyRegistryManager)
-                        mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
-        if (DBG) logd("notifySubscriptionInfoChanged:");
-        trm.notifySubscriptionInfoChanged();
-
-        MultiSimSettingController.getInstance().notifySubscriptionInfoChanged();
-        TelephonyMetrics metrics = TelephonyMetrics.getInstance();
-        List<SubscriptionInfo> subInfos;
-        synchronized (mSubInfoListLock) {
-            subInfos = new ArrayList<>(mCacheActiveSubInfoList);
-        }
-
-        if (mOpptSubInfoListChangedDirtyBit.getAndSet(false)) {
-            notifyOpportunisticSubscriptionInfoChanged();
-        }
-        metrics.updateActiveSubscriptionInfoList(subInfos);
-    }
-
-    /**
-     * New SubInfoRecord instance and fill in detail info
-     * @param cursor The database cursor
-     * @return the query result of desired SubInfoRecord
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private SubscriptionInfo getSubInfoRecord(Cursor cursor) {
-        SubscriptionInfo.Builder builder = new SubscriptionInfo.Builder();
-        int id = cursor.getInt(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
-        builder.setId(id)
-                .setIccId(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.ICC_ID)))
-                .setSimSlotIndex(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.SIM_SLOT_INDEX)))
-                .setDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.DISPLAY_NAME)))
-                .setCarrierName(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.CARRIER_NAME)))
-                .setDisplayNameSource(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.NAME_SOURCE)))
-                .setIconTint(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.HUE)))
-                .setDataRoaming(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.DATA_ROAMING)))
-                .setMcc(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.MCC_STRING)))
-                .setMnc(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.MNC_STRING)));
-
-        String ehplmnsRaw = cursor.getString(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.EHPLMNS));
-        String hplmnsRaw = cursor.getString(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.HPLMNS));
-        String[] ehplmns = ehplmnsRaw == null ? null : ehplmnsRaw.split(",");
-        String[] hplmns = hplmnsRaw == null ? null : hplmnsRaw.split(",");
-
-        builder.setEhplmns(ehplmns).setHplmns(hplmns);
-
-
-        // CARD_ID is the private ICCID/EID string, also known as the card string
-        String cardString = cursor.getString(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.CARD_ID));
-        builder.setCardString(cardString);
-        // publicCardId is the publicly exposed int card ID
-        int publicCardId = mUiccController.convertToPublicCardId(cardString);
-        builder.setCardId(publicCardId);
-
-        builder.setCountryIso(cursor.getString(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.ISO_COUNTRY_CODE)))
-                .setCarrierId(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.CARRIER_ID)));
-
-        boolean isEmbedded = cursor.getInt(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.IS_EMBEDDED)) == 1;
-        builder.setEmbedded(isEmbedded);
-        if (isEmbedded) {
-            builder.setNativeAccessRules(UiccAccessRule.decodeRules(cursor.getBlob(
-                            cursor.getColumnIndexOrThrow(SubscriptionManager.ACCESS_RULES))));
-        }
-
-        builder.setCarrierConfigAccessRules(UiccAccessRule.decodeRules(cursor.getBlob(
-                cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.ACCESS_RULES_FROM_CARRIER_CONFIGS))))
-                .setOpportunistic(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.IS_OPPORTUNISTIC)) == 1)
-                .setGroupUuid(cursor.getString(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.GROUP_UUID)))
-                .setProfileClass(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.PROFILE_CLASS)))
-                .setPortIndex(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.PORT_INDEX)))
-                .setType(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.SUBSCRIPTION_TYPE)))
-                .setGroupOwner(getOptionalStringFromCursor(cursor, SubscriptionManager.GROUP_OWNER,
-                        /*defaultVal*/ null))
-                .setUiccApplicationsEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.UICC_APPLICATIONS_ENABLED)) == 1)
-                .setUsageSetting(cursor.getInt(cursor.getColumnIndexOrThrow(
-                        SubscriptionManager.USAGE_SETTING)));
-
-        // If line1number has been set to a different number, use it instead.
-        String number = cursor.getString(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.NUMBER));
-        String line1Number = mTelephonyManager.getLine1Number(id);
-        if (!TextUtils.isEmpty(line1Number) && !line1Number.equals(number)) {
-            number = line1Number;
-        }
-        builder.setNumber(number);
-
-        // 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?
-
-        return builder.build();
-    }
-
-    private String getOptionalStringFromCursor(Cursor cursor, String column, String defaultVal) {
-        // Return defaultVal if the column doesn't exist.
-        int columnIndex = cursor.getColumnIndex(column);
-        return (columnIndex == -1) ? defaultVal : cursor.getString(columnIndex);
-    }
-
-    /**
-     * Get a subscription that matches IccId.
-     * @return null if there isn't a match, or subscription info if there is one.
-     */
-    public SubscriptionInfo getSubInfoForIccId(String iccId) {
-        List<SubscriptionInfo> info = getSubInfo(
-                SubscriptionManager.ICC_ID + "=\'" + iccId + "\'", null);
-        if (info == null || info.size() == 0) return null;
-        // Should be at most one subscription with the iccid.
-        return info.get(0);
-    }
-
-    /**
-     * Query SubInfoRecord(s) from subinfo database
-     * @param selection A filter declaring which rows to return
-     * @param queryKey query key content
-     * @return Array list of queried result from database
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public List<SubscriptionInfo> getSubInfo(String selection, Object queryKey) {
-        if (VDBG) logd("selection:" + selection + ", querykey: " + queryKey);
-        String[] selectionArgs = null;
-        if (queryKey != null) {
-            selectionArgs = new String[] {queryKey.toString()};
-        }
-        ArrayList<SubscriptionInfo> subList = null;
-        Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
-                null, selection, selectionArgs, null);
-        try {
-            if (cursor != null) {
-                while (cursor.moveToNext()) {
-                    SubscriptionInfo subInfo = getSubInfoRecord(cursor);
-                    if (subInfo != null) {
-                        if (subList == null) {
-                            subList = new ArrayList<SubscriptionInfo>();
-                        }
-                        subList.add(subInfo);
-                    }
-                }
-            } else {
-                if (DBG) logd("Query fail");
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        return subList;
-    }
-
-    /**
-     * Find unused color to be set for new SubInfoRecord
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return RGB integer value of color
-     */
-    private int getUnusedColor(String callingPackage, String callingFeatureId) {
-        List<SubscriptionInfo> availableSubInfos = getActiveSubscriptionInfoList(callingPackage,
-                callingFeatureId);
-        colorArr = mContext.getResources().getIntArray(com.android.internal.R.array.sim_colors);
-        int colorIdx = 0;
-
-        if (availableSubInfos != null) {
-            for (int i = 0; i < colorArr.length; i++) {
-                int j;
-                for (j = 0; j < availableSubInfos.size(); j++) {
-                    if (colorArr[i] == availableSubInfos.get(j).getIconTint()) {
-                        break;
-                    }
-                }
-                if (j == availableSubInfos.size()) {
-                    return colorArr[i];
-                }
-            }
-            colorIdx = availableSubInfos.size() % colorArr.length;
-        }
-        return colorArr[colorIdx];
-    }
-
-    @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
-        return getActiveSubscriptionInfo(subId, callingPackage, null);
-    }
-
-    /**
-     * Get the active SubscriptionInfo with the subId key
-     * @param subId The unique SubscriptionInfo key in database
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return SubscriptionInfo, maybe null if its not active
-     */
-    @Override
-    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage,
-            String callingFeatureId) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
-                callingFeatureId, "getActiveSubscriptionInfo")) {
-            return null;
-        }
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        List<SubscriptionInfo> subList;
-        try {
-            subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (subList != null) {
-            for (SubscriptionInfo si : subList) {
-                if (si.getSubscriptionId() == subId) {
-                    if (VDBG) {
-                        logd("[getActiveSubscriptionInfo]+ subId=" + subId + " subInfo=" + si);
-                    }
-                    return conditionallyRemoveIdentifiers(si, callingPackage, callingFeatureId,
-                            "getActiveSubscriptionInfo");
-                }
-            }
-        }
-        if (DBG) {
-            logd("[getActiveSubscriptionInfo]- subId=" + subId
-                    + " subList=" + subList + " subInfo=null");
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single subscription info record for a given subscription.
-     *
-     * @param subId the subId to query.
-     *
-     * @hide
-     */
-    public SubscriptionInfo getSubscriptionInfo(int subId) {
-        synchronized (mSubInfoListLock) {
-            // check cache for active subscriptions first, before querying db
-            for (SubscriptionInfo subInfo : mCacheActiveSubInfoList) {
-                if (subInfo.getSubscriptionId() == subId) {
-                    return subInfo;
-                }
-            }
-
-            // check cache for opportunistic subscriptions too, before querying db
-            for (SubscriptionInfo subInfo : mCacheOpportunisticSubInfoList) {
-                if (subInfo.getSubscriptionId() == subId) {
-                    return subInfo;
-                }
-            }
-        }
-
-        List<SubscriptionInfo> subInfoList = getSubInfo(
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null);
-        if (subInfoList == null || subInfoList.isEmpty()) return null;
-        return subInfoList.get(0);
-    }
-
-    /**
-     * Get the active SubscriptionInfo associated with the iccId
-     * @param iccId the IccId of SIM card
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return SubscriptionInfo, maybe null if its not active
-     */
-    @Override
-    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage,
-            String callingFeatureId) {
-        enforceReadPrivilegedPhoneState("getActiveSubscriptionInfoForIccId");
-        return getActiveSubscriptionInfoForIccIdInternal(iccId);
-    }
-
-    /**
-     * Get the active SubscriptionInfo associated with the given iccId. The caller *must* perform
-     * permission checks when using this method.
-     */
-    private SubscriptionInfo getActiveSubscriptionInfoForIccIdInternal(String iccId) {
-        if (iccId == null) {
-            return null;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (subList != null) {
-                for (SubscriptionInfo si : subList) {
-                    if (iccId.equals(si.getIccId())) {
-                        if (DBG)
-                            logd("[getActiveSubInfoUsingIccId]+ iccId=" + iccId + " subInfo=" + si);
-                        return si;
-                    }
-                }
-            }
-            if (DBG) {
-                logd("[getActiveSubInfoUsingIccId]+ iccId=" + iccId
-                        + " subList=" + subList + " subInfo=null");
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the active SubscriptionInfo associated with the slotIndex.
-     * This API does not return details on Remote-SIM subscriptions.
-     * @param slotIndex the slot which the subscription is inserted
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return SubscriptionInfo, null for Remote-SIMs or non-active slotIndex.
-     */
-    @Override
-    public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
-            String callingPackage, String callingFeatureId) {
-        Phone phone = PhoneFactory.getPhone(slotIndex);
-        if (phone == null) {
-            if (DBG) {
-                loge("[getActiveSubscriptionInfoForSimSlotIndex] no phone, slotIndex=" + slotIndex);
-            }
-            return null;
-        }
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, phone.getSubId(), callingPackage, callingFeatureId,
-                "getActiveSubscriptionInfoForSimSlotIndex")) {
-            return null;
-        }
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        List<SubscriptionInfo> subList;
-        try {
-            subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (subList != null) {
-            for (SubscriptionInfo si : subList) {
-                if (si.getSimSlotIndex() == slotIndex) {
-                    if (DBG) {
-                        logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex="
-                                + slotIndex + " subId=" + si);
-                    } else {
-                        logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex="
-                                + slotIndex + " subId=" + conditionallyRemoveIdentifiers(si, false,
-                                false));
-                    }
-                    return conditionallyRemoveIdentifiers(si, callingPackage, callingFeatureId,
-                            "getActiveSubscriptionInfoForSimSlotIndex");
-                }
-            }
-            if (DBG) {
-                logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex
-                        + " subId=null");
-            }
-        } else {
-            if (DBG) {
-                logd("[getActiveSubscriptionInfoForSimSlotIndex]+ subList=null");
-            }
-        }
-
-
-        return null;
-    }
-
-    /**
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return List of all SubscriptionInfo records in database,
-     * include those that were inserted before, maybe empty but not null.
-     * @hide
-     */
-    @Override
-    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage,
-            String callingFeatureId) {
-        return getAllSubInfoList(callingPackage, callingFeatureId, false);
-    }
-
-    /**
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @param skipConditionallyRemoveIdentifier if set, skip removing identifier conditionally
-     * @return List of all SubscriptionInfo records in database,
-     * include those that were inserted before, maybe empty but not null.
-     * @hide
-     */
-    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage,
-            String callingFeatureId, boolean skipConditionallyRemoveIdentifier) {
-        if (VDBG) logd("[getAllSubInfoList]+");
-
-        // This API isn't public, so no need to provide a valid subscription ID - we're not worried
-        // about carrier-privileged callers not having access.
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                callingFeatureId, "getAllSubInfoList")) {
-            return null;
-        }
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        List<SubscriptionInfo> subList;
-        try {
-            subList = getSubInfo(null, null);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (subList != null && !skipConditionallyRemoveIdentifier) {
-            if (VDBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return");
-            subList = subList.stream().map(
-                    subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo,
-                            callingPackage, callingFeatureId, "getAllSubInfoList"))
-                    .collect(Collectors.toList());
-        } else {
-            if (VDBG) logd("[getAllSubInfoList]- no info return");
-        }
-        return subList;
-    }
-
-    private List<SubscriptionInfo> makeCacheListCopyWithLock(List<SubscriptionInfo> cacheSubList) {
-        synchronized (mSubInfoListLock) {
-            return new ArrayList<>(cacheSubList);
-        }
-    }
-
-    @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
-        return getSubscriptionInfoListFromCacheHelper(callingPackage, null,
-                makeCacheListCopyWithLock(mCacheActiveSubInfoList));
-    }
-
-    /**
-     * Get the SubInfoRecord(s) of the currently active SIM(s) - which include both local
-     * and remote SIMs.
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return Array list of currently inserted SubInfoRecord(s)
-     */
-    @Override
-    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage,
-            String callingFeatureId) {
-        return getSubscriptionInfoListFromCacheHelper(callingPackage, callingFeatureId,
-                makeCacheListCopyWithLock(mCacheActiveSubInfoList));
-    }
-
-    /**
-     * Refresh the cache of SubInfoRecord(s) of the currently available SIM(s) - including
-     * local & remote SIMs.
-     */
-    @VisibleForTesting  // For mockito to mock this method
-    public void refreshCachedActiveSubscriptionInfoList() {
-        boolean opptSubListChanged;
-
-        List<SubscriptionInfo> activeSubscriptionInfoList = getSubInfo(
-                SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
-                + SubscriptionManager.SUBSCRIPTION_TYPE + "="
-                + SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM,
-                null);
-
-        synchronized (mSubInfoListLock) {
-            if (activeSubscriptionInfoList != null) {
-                // Log when active sub info changes.
-                if (mCacheActiveSubInfoList.size() != activeSubscriptionInfoList.size()
-                        || !mCacheActiveSubInfoList.containsAll(activeSubscriptionInfoList)) {
-                    logdl("Active subscription info list changed. " + activeSubscriptionInfoList);
-                }
-
-                mCacheActiveSubInfoList.clear();
-                activeSubscriptionInfoList.sort(SUBSCRIPTION_INFO_COMPARATOR);
-                mCacheActiveSubInfoList.addAll(activeSubscriptionInfoList);
-            } else {
-                logd("activeSubscriptionInfoList is null.");
-                mCacheActiveSubInfoList.clear();
-            }
-            if (DBG_CACHE) {
-                if (!mCacheActiveSubInfoList.isEmpty()) {
-                    for (SubscriptionInfo si : mCacheActiveSubInfoList) {
-                        logd("[refreshCachedActiveSubscriptionInfoList] Setting Cached info="
-                                + si);
-                    }
-                } else {
-                    logdl("[refreshCachedActiveSubscriptionInfoList]- no info return");
-                }
-            }
-        }
-
-        // Refresh cached opportunistic sub list and detect whether it's changed.
-        refreshCachedOpportunisticSubscriptionInfoList();
-    }
-
-    @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public int getActiveSubInfoCount(String callingPackage) {
-        return getActiveSubInfoCount(callingPackage, null);
-    }
-
-    /**
-     * Get the SUB count of active SUB(s)
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package.
-     * @return active SIM count
-     */
-    @Override
-    public int getActiveSubInfoCount(String callingPackage, String callingFeatureId) {
-        // Let getActiveSubscriptionInfoList perform permission checks / filtering.
-        List<SubscriptionInfo> records = getActiveSubscriptionInfoList(callingPackage,
-                callingFeatureId);
-        if (records == null) {
-            if (VDBG) logd("[getActiveSubInfoCount] records null");
-            return 0;
-        }
-        if (VDBG) logd("[getActiveSubInfoCount]- count: " + records.size());
-        return records.size();
-    }
-
-    /**
-     * Get the SUB count of all SUB(s) in SubscriptoinInfo database
-     * @param callingPackage The package making the IPC.
-     * @param callingFeatureId The feature in the package
-     * @return all SIM count in database, include what was inserted before
-     */
-    public int getAllSubInfoCount(String callingPackage, String callingFeatureId) {
-        if (DBG) logd("[getAllSubInfoCount]+");
-
-        // This API isn't public, so no need to provide a valid subscription ID - we're not worried
-        // about carrier-privileged callers not having access.
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                callingFeatureId, "getAllSubInfoCount")) {
-            return 0;
-        }
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
-                    null, null, null, null);
-            try {
-                if (cursor != null) {
-                    int count = cursor.getCount();
-                    if (DBG) logd("[getAllSubInfoCount]- " + count + " SUB(s) in DB");
-                    return count;
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-            if (DBG) logd("[getAllSubInfoCount]- no SUB in DB");
-
-            return 0;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * @return the maximum number of local subscriptions this device will support at any one time.
-     */
-    @Override
-    public int getActiveSubInfoCountMax() {
-        // FIXME: This valid now but change to use TelephonyDevController in the future
-        return mTelephonyManager.getSimCount();
-    }
-
-    @Override
-    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage,
-            String callingFeatureId) {
-        try {
-            enforceReadPrivilegedPhoneState("getAvailableSubscriptionInfoList");
-        } catch (SecurityException e) {
-            try {
-                mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE, null);
-                // If caller doesn't have READ_PRIVILEGED_PHONE_STATE permission but only
-                // has READ_PHONE_STATE permission, log this event.
-                EventLog.writeEvent(0x534e4554, "185235454", Binder.getCallingUid());
-            } catch (SecurityException ex) {
-                // Ignore
-            }
-            throw new SecurityException("Need READ_PRIVILEGED_PHONE_STATE to call "
-                    + " getAvailableSubscriptionInfoList");
-        }
-
-        // Now that all security checks pass, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            String selection = SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
-                    + SubscriptionManager.SUBSCRIPTION_TYPE + "="
-                    + SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM;
-
-            EuiccManager euiccManager =
-                    (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE);
-            if (euiccManager.isEnabled()) {
-                selection += " OR " + SubscriptionManager.IS_EMBEDDED + "=1";
-            }
-
-            // Available eSIM profiles are reported by EuiccManager. However for physical SIMs if
-            // they are in inactive slot or programmatically disabled, they are still considered
-            // available. In this case we get their iccid from slot info and include their
-            // subscriptionInfos.
-            List<String> iccIds = getIccIdsOfInsertedPhysicalSims();
-
-            if (!iccIds.isEmpty()) {
-                selection += " OR ("  + getSelectionForIccIdList(iccIds.toArray(new String[0]))
-                        + ")";
-            }
-
-            List<SubscriptionInfo> subList = getSubInfo(selection, null /* queryKey */);
-
-            if (subList != null) {
-                subList.sort(SUBSCRIPTION_INFO_COMPARATOR);
-
-                if (VDBG) logdl("[getAvailableSubInfoList]- " + subList.size() + " infos return");
-            } else {
-                if (DBG) logdl("[getAvailableSubInfoList]- no info return");
-            }
-
-            return subList;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    private List<String> getIccIdsOfInsertedPhysicalSims() {
-        List<String> ret = new ArrayList<>();
-        UiccSlot[] uiccSlots = UiccController.getInstance().getUiccSlots();
-        if (uiccSlots == null) return ret;
-
-        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));
-                }
-            }
-        }
-
-        return ret;
-    }
-
-    @Override
-    public List<SubscriptionInfo> getAccessibleSubscriptionInfoList(String callingPackage) {
-        EuiccManager euiccManager = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE);
-        if (!euiccManager.isEnabled()) {
-            if (DBG) {
-                logdl("[getAccessibleSubInfoList] Embedded subscriptions are disabled");
-            }
-            return null;
-        }
-
-        // Verify that the given package belongs to the calling UID.
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-
-        // Perform the operation as ourselves. If the caller cannot read phone state, they may still
-        // have carrier privileges per the subscription metadata, so we always need to make the
-        // query and then filter the results.
-        final long identity = Binder.clearCallingIdentity();
-        List<SubscriptionInfo> subList;
-        try {
-            subList = getSubInfo(SubscriptionManager.IS_EMBEDDED + "=1", null);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        if (subList == null) {
-            if (DBG) logdl("[getAccessibleSubInfoList] No info returned");
-            return null;
-        }
-
-        // Filter the list to only include subscriptions which the (restored) caller can manage.
-        List<SubscriptionInfo> filteredList = subList.stream()
-                .filter(subscriptionInfo ->
-                        subscriptionInfo.canManageSubscription(mContext, callingPackage))
-                .sorted(SUBSCRIPTION_INFO_COMPARATOR)
-                .collect(Collectors.toList());
-        if (VDBG) {
-            logdl("[getAccessibleSubInfoList] " + filteredList.size() + " infos returned");
-        }
-        return filteredList;
-    }
-
-    /**
-     * Return the list of subscriptions in the database which are either:
-     * <ul>
-     * <li>Embedded (but see note about {@code includeNonRemovableSubscriptions}, or
-     * <li>In the given list of current embedded ICCIDs (which may not yet be in the database, or
-     *     which may not currently be marked as embedded).
-     * </ul>
-     *
-     * <p>NOTE: This is not accessible to external processes, so it does not need a permission
-     * check. It is only intended for use by {@link SubscriptionInfoUpdater}.
-     *
-     * @param embeddedIccids all ICCIDs of available embedded subscriptions. This is used to surface
-     *     entries for profiles which had been previously deleted.
-     * @param isEuiccRemovable whether the current ICCID is removable. Non-removable subscriptions
-     *     will only be returned if the current ICCID is not removable; otherwise, they are left
-     *     alone (not returned here unless in the embeddedIccids list) under the assumption that
-     *     they will still be accessible when the eUICC containing them is activated.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public List<SubscriptionInfo> getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
-            String[] embeddedIccids, boolean isEuiccRemovable) {
-        StringBuilder whereClause = new StringBuilder();
-        whereClause.append("(").append(SubscriptionManager.IS_EMBEDDED).append("=1");
-        if (isEuiccRemovable) {
-            // Current eUICC is removable, so don't return non-removable subscriptions (which would
-            // be deleted), as these are expected to still be present on a different, non-removable
-            // eUICC.
-            whereClause.append(" AND ").append(SubscriptionManager.IS_REMOVABLE).append("=1");
-        }
-        // Else, return both removable and non-removable subscriptions. This is expected to delete
-        // all removable subscriptions, which is desired as they may not be accessible.
-
-        whereClause.append(") OR ").append(SubscriptionManager.ICC_ID).append(" IN (");
-        // ICCIDs are validated to contain only numbers when passed in, and come from a trusted
-        // app, so no need to escape.
-        for (int i = 0; i < embeddedIccids.length; i++) {
-            if (i > 0) {
-                whereClause.append(",");
-            }
-            whereClause.append("'").append(embeddedIccids[i]).append("'");
-        }
-        whereClause.append(")");
-
-        List<SubscriptionInfo> list = getSubInfo(whereClause.toString(), null);
-        if (list == null) {
-            return Collections.emptyList();
-        }
-        return list;
-    }
-
-    @Override
-    public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS,
-                "requestEmbeddedSubscriptionInfoListRefresh");
-        long token = Binder.clearCallingIdentity();
-        try {
-            PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(cardId, null /* callback */);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Asynchronously refresh the embedded subscription info list for the embedded card has the
-     * given card id {@code cardId}.
-     *
-     * @param callback Optional callback to execute after the refresh completes. Must terminate
-     *     quickly as it will be called from SubscriptionInfoUpdater's handler thread.
-     */
-    // No permission check needed as this is not exposed via AIDL.
-    public void requestEmbeddedSubscriptionInfoListRefresh(
-            int cardId, @Nullable Runnable callback) {
-        PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(cardId, callback);
-    }
-
-    /**
-     * Asynchronously refresh the embedded subscription info list for the embedded card has the
-     * default card id return by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
-     *
-     * @param callback Optional callback to execute after the refresh completes. Must terminate
-     *     quickly as it will be called from SubscriptionInfoUpdater's handler thread.
-     */
-    // No permission check needed as this is not exposed via AIDL.
-    public void requestEmbeddedSubscriptionInfoListRefresh(@Nullable Runnable callback) {
-        PhoneFactory.requestEmbeddedSubscriptionInfoListRefresh(
-                mTelephonyManager.getCardIdForDefaultEuicc(), callback);
-    }
-
-    /**
-     * Add a new subscription info record, if needed.
-     * @param uniqueId This is the unique identifier for the subscription within the specific
-     *                 subscription type.
-     * @param displayName human-readable name of the device the subscription corresponds to.
-     * @param slotIndex value for {@link SubscriptionManager#SIM_SLOT_INDEX}
-     * @param subscriptionType the type of subscription to be added.
-     * @return 0 if success, < 0 on error.
-     */
-    @Override
-    public int addSubInfo(String uniqueId, String displayName, int slotIndex,
-            int subscriptionType) {
-        if (DBG) {
-            String iccIdStr = uniqueId;
-            if (!isSubscriptionForRemoteSim(subscriptionType)) {
-                iccIdStr = SubscriptionInfo.givePrintableIccid(uniqueId);
-            }
-            logdl("[addSubInfoRecord]+ iccid: " + iccIdStr
-                    + ", slotIndex: " + slotIndex
-                    + ", subscriptionType: " + subscriptionType);
-        }
-
-        enforceModifyPhoneState("addSubInfo");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            if (uniqueId == null) {
-                if (DBG) logdl("[addSubInfo]- null iccId");
-                return -1;
-            }
-
-            ContentResolver resolver = mContext.getContentResolver();
-            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 {
-                selection += " OR " + SubscriptionManager.ICC_ID + "=?";
-                args = new String[]{uniqueId, IccUtils.getDecimalSubstring(uniqueId)};
-            }
-            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},
-                    selection, args, null);
-
-            boolean setDisplayName = false;
-            try {
-                boolean recordsDoNotExist = (cursor == null || !cursor.moveToFirst());
-                if (isSubscriptionForRemoteSim(subscriptionType)) {
-                    if (recordsDoNotExist) {
-                        // create a Subscription record
-                        slotIndex = SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB;
-                        Uri uri = insertEmptySubInfoRecord(uniqueId, displayName,
-                                slotIndex, subscriptionType);
-                        if (DBG) logd("[addSubInfoRecord] New record created: " + uri);
-                    } else {
-                        if (DBG) logdl("[addSubInfoRecord] Record already exists");
-                    }
-                } else {  // Handle Local SIM devices
-                    if (recordsDoNotExist) {
-                        setDisplayName = true;
-                        Uri uri = insertEmptySubInfoRecord(uniqueId, slotIndex);
-                        if (DBG) logdl("[addSubInfoRecord] New record created: " + uri);
-                    } else { // there are matching records in the database for the given ICC_ID
-                        int subId = cursor.getInt(0);
-                        int oldSimInfoId = cursor.getInt(1);
-                        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) {
-                            value.put(SubscriptionManager.SIM_SLOT_INDEX, slotIndex);
-                        }
-
-                        if (oldIccId != null && oldIccId.length() < uniqueId.length()
-                                && (oldIccId.equals(IccUtils.getDecimalSubstring(uniqueId)))) {
-                            value.put(SubscriptionManager.ICC_ID, uniqueId);
-                        }
-
-                        UiccCard card = mUiccController.getUiccCardForPhone(slotIndex);
-                        if (card != null) {
-                            String cardId = card.getCardId();
-                            if (cardId != null && cardId != oldCardId) {
-                                value.put(SubscriptionManager.CARD_ID, cardId);
-                            }
-                        }
-
-                        //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);
-                        }
-
-                        if (DBG) logdl("[addSubInfoRecord] Record already exists");
-                    }
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-
-            selection = SubscriptionManager.SIM_SLOT_INDEX + "=?";
-            args = new String[] {String.valueOf(slotIndex)};
-            if (isSubscriptionForRemoteSim(subscriptionType)) {
-                selection = SubscriptionManager.ICC_ID + "=? AND "
-                        + SubscriptionManager.SUBSCRIPTION_TYPE + "=?";
-                args = new String[]{uniqueId, Integer.toString(subscriptionType)};
-            }
-            cursor = resolver.query(SubscriptionManager.CONTENT_URI, null,
-                    selection, args, null);
-            try {
-                if (cursor != null && cursor.moveToFirst()) {
-                    do {
-                        int subId = cursor.getInt(cursor.getColumnIndexOrThrow(
-                                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
-                        // If sSlotIndexToSubIds already has the same subId for a slotIndex/phoneId,
-                        // do not add it.
-                        if (addToSubIdList(slotIndex, subId, subscriptionType)) {
-                            // TODO While two subs active, if user deactivats first
-                            // one, need to update the default subId with second one.
-
-                            // FIXME: Currently we assume phoneId == slotIndex which in the future
-                            // may not be true, for instance with multiple subs per slot.
-                            // But is true at the moment.
-                            int subIdCountMax = getActiveSubInfoCountMax();
-                            int defaultSubId = getDefaultSubId();
-                            if (DBG) {
-                                logdl("[addSubInfoRecord]"
-                                        + " mSlotIndexToSubIds.size=" + mSlotIndexToSubIds.size()
-                                        + " slotIndex=" + slotIndex + " subId=" + subId
-                                        + " defaultSubId=" + defaultSubId
-                                        + " simCount=" + subIdCountMax);
-                            }
-
-                            // Set the default sub if not set or if single sim device
-                            if (!isSubscriptionForRemoteSim(subscriptionType)) {
-                                if (!SubscriptionManager.isValidSubscriptionId(defaultSubId)
-                                        || subIdCountMax == 1
-                                        || mDefaultFallbackSubId.get() ==
-                                        SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                                    logdl("setting default fallback subid to " + subId);
-                                    setDefaultFallbackSubId(subId, subscriptionType);
-                                }
-                                // If single sim device, set this subscription as the default for
-                                // everything
-                                if (subIdCountMax == 1) {
-                                    if (DBG) {
-                                        logdl("[addSubInfoRecord] one sim set defaults to subId="
-                                                + subId);
-                                    }
-                                    setDefaultDataSubId(subId);
-                                    setDefaultSmsSubId(subId);
-                                    setDefaultVoiceSubId(subId);
-                                }
-                            } else {
-                                updateDefaultSubIdsIfNeeded(subId, subscriptionType);
-                            }
-                        } else {
-                            if (DBG) {
-                                logdl("[addSubInfoRecord] current SubId is already known, "
-                                        + "IGNORE");
-                            }
-                        }
-                        if (DBG) {
-                            logdl("[addSubInfoRecord] hashmap(" + slotIndex + "," + subId + ")");
-                        }
-                    } while (cursor.moveToNext());
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-
-            // Refresh the Cache of Active Subscription Info List. This should be done after
-            // updating sSlotIndexToSubIds which is done through addToSubIdList() above.
-            refreshCachedActiveSubscriptionInfoList();
-
-            if (isSubscriptionForRemoteSim(subscriptionType)) {
-                notifySubscriptionInfoChanged();
-            } else {  // Handle Local SIM devices
-                // Set Display name after sub id is set above so as to get valid simCarrierName
-                int subId = getSubId(slotIndex);
-                if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-                    if (DBG) {
-                        logdl("[addSubInfoRecord]- getSubId failed invalid subId = " + subId);
-                    }
-                    return -1;
-                }
-                if (setDisplayName) {
-                    String simCarrierName = mTelephonyManager.getSimOperatorName(subId);
-                    String nameToSet;
-
-                    if (!TextUtils.isEmpty(simCarrierName)) {
-                        nameToSet = simCarrierName;
-                    } else {
-                        nameToSet = "CARD " + Integer.toString(slotIndex + 1);
-                    }
-
-                    ContentValues value = new ContentValues();
-                    value.put(SubscriptionManager.DISPLAY_NAME, nameToSet);
-                    resolver.update(SubscriptionManager.getUriForSubscriptionId(subId), value,
-                            null, null);
-
-                    // Refresh the Cache of Active Subscription Info List
-                    refreshCachedActiveSubscriptionInfoList();
-
-                    if (DBG) logdl("[addSubInfoRecord] sim name = " + nameToSet);
-                }
-
-                if (DBG) logdl("[addSubInfoRecord]- info size=" + mSlotIndexToSubIds.size());
-            }
-
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        return 0;
-    }
-
-    private void updateDefaultSubIdsIfNeeded(int newDefault, int subscriptionType) {
-        if (DBG) {
-            logdl("[updateDefaultSubIdsIfNeeded] newDefault=" + newDefault
-                    + ", subscriptionType=" + subscriptionType);
-        }
-        // Set the default ot new value only if the current default is invalid.
-        if (!isActiveSubscriptionId(getDefaultSubId())) {
-            // current default is not valid anylonger. set a new default
-            if (DBG) {
-                logdl("[updateDefaultSubIdsIfNeeded] set sDefaultFallbackSubId=" + newDefault);
-            }
-            setDefaultFallbackSubId(newDefault, subscriptionType);
-        }
-
-        int value = getDefaultSmsSubId();
-        if (!isActiveSubscriptionId(value)) {
-            // current default is not valid. set it to the given newDefault value
-            setDefaultSmsSubId(newDefault);
-        }
-        value = getDefaultDataSubId();
-        if (!isActiveSubscriptionId(value)) {
-            setDefaultDataSubId(newDefault);
-        }
-        value = getDefaultVoiceSubId();
-        if (!isActiveSubscriptionId(value)) {
-            setDefaultVoiceSubId(newDefault);
-        }
-    }
-
-    /**
-     * This method returns true if the given subId is among the list of currently active
-     * subscriptions.
-     */
-    private boolean isActiveSubscriptionId(int subId) {
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) return false;
-        ArrayList<Integer> subIdList = getActiveSubIdArrayList();
-        if (subIdList.isEmpty()) return false;
-        return subIdList.contains(new Integer(subId));
-    }
-
-    /*
-     * Delete subscription info record for the given device.
-     * @param uniqueId This is the unique identifier for the subscription within the specific
-     *                 subscription type.
-     * @param subscriptionType the type of subscription to be removed
-     * @return 0 if success, < 0 on error.
-     */
-    @Override
-    public int removeSubInfo(String uniqueId, int subscriptionType) {
-        enforceModifyPhoneState("removeSubInfo");
-        if (DBG) {
-            logd("[removeSubInfo] uniqueId: " + uniqueId
-                    + ", subscriptionType: " + subscriptionType);
-        }
-
-        // validate the given info - does it exist in the active subscription list
-        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        int slotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-        synchronized (mSubInfoListLock) {
-            for (SubscriptionInfo info : mCacheActiveSubInfoList) {
-                if ((info.getSubscriptionType() == subscriptionType)
-                        && info.getIccId().equalsIgnoreCase(uniqueId)) {
-                    subId = info.getSubscriptionId();
-                    slotIndex = info.getSimSlotIndex();
-                    break;
-                }
-            }
-        }
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            if (DBG) {
-                logd("Invalid subscription details: subscriptionType = " + subscriptionType
-                        + ", uniqueId = " + uniqueId);
-            }
-            return -1;
-        }
-
-        if (DBG) logd("removing the subid : " + subId);
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        int result = 0;
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            ContentResolver resolver = mContext.getContentResolver();
-            result = resolver.delete(SubscriptionManager.CONTENT_URI,
-                    SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=? AND "
-                            + SubscriptionManager.SUBSCRIPTION_TYPE + "=?",
-                    new String[]{Integer.toString(subId), Integer.toString(subscriptionType)});
-            if (result != 1) {
-                if (DBG) {
-                    logd("found NO subscription to remove with subscriptionType = "
-                            + subscriptionType + ", uniqueId = " + uniqueId);
-                }
-                return -1;
-            }
-            refreshCachedActiveSubscriptionInfoList();
-            result = mSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
-            if (result == NO_ENTRY_FOR_SLOT_INDEX) {
-                loge("sSlotIndexToSubIds has no entry for slotIndex = " + slotIndex);
-            } else if (result == SUB_ID_NOT_IN_SLOT) {
-                loge("sSlotIndexToSubIds has no subid: " + subId + ", in index: " + slotIndex);
-            }
-
-            // Since a subscription is removed, if this one is set as default for any setting,
-            // set some other subid as the default.
-            int newDefault = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-            SubscriptionInfo info = null;
-            final List<SubscriptionInfo> records = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (!records.isEmpty()) {
-                // yes, we have more subscriptions. pick the first one.
-                // FIXME do we need a policy to figure out which one is to be next default
-                info = records.get(0);
-            }
-            updateDefaultSubIdsIfNeeded(info.getSubscriptionId(), info.getSubscriptionType());
-
-            notifySubscriptionInfoChanged();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        return result;
-    }
-
-    /**
-     * Clear an subscriptionInfo to subinfo database if needed by updating slot index to invalid.
-     * @param slotIndex the slot which the SIM is removed
-     */
-    public void clearSubInfoRecord(int slotIndex) {
-        if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex);
-
-        // update simInfo db with invalid slot index
-        ContentResolver resolver = mContext.getContentResolver();
-        ContentValues value = new ContentValues(1);
-        value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        String where = "(" + SubscriptionManager.SIM_SLOT_INDEX + "=" + slotIndex + ")";
-        resolver.update(SubscriptionManager.CONTENT_URI, value, where, null);
-
-        // Refresh the Cache of Active Subscription Info List
-        refreshCachedActiveSubscriptionInfoList();
-
-        boolean isFallBackRefreshRequired = false;
-        if (mDefaultFallbackSubId.get() > SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
-                mSlotIndexToSubIds.getCopy(slotIndex) != null &&
-                mSlotIndexToSubIds.getCopy(slotIndex).contains(mDefaultFallbackSubId.get())) {
-            isFallBackRefreshRequired = true;
-        }
-        mSlotIndexToSubIds.remove(slotIndex);
-        // set mDefaultFallbackSubId to invalid in case mSlotIndexToSubIds do not have any entries
-        if (mSlotIndexToSubIds.size() ==0 ) {
-            mDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        } else if (isFallBackRefreshRequired) {
-            // set mDefaultFallbackSubId to valid subId from mSlotIndexToSubIds
-            for (int index = 0; index < getActiveSubIdArrayList().size(); index ++) {
-                int subId = getActiveSubIdArrayList().get(index);
-                if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                    mDefaultFallbackSubId.set(subId);
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Insert an empty SubInfo record into the database.
-     *
-     * <p>NOTE: This is not accessible to external processes, so it does not need a permission
-     * check. It is only intended for use by {@link SubscriptionInfoUpdater}. If there is a
-     * subscription record exist with the same ICCID, no new empty record will be created.
-     *
-     * @return the URL of the newly created row. Return <code>null</code> if no new empty record is
-     * created.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    @Nullable
-    public Uri insertEmptySubInfoRecord(String iccId, int slotIndex) {
-        if (getSubInfoForIccId(iccId) != null) {
-            loge("insertEmptySubInfoRecord: Found existing record by ICCID. Do not create a "
-                    + "new empty entry.");
-            return null;
-        }
-        return insertEmptySubInfoRecord(iccId, null, slotIndex,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-    }
-
-    Uri insertEmptySubInfoRecord(String uniqueId, String displayName, int slotIndex,
-            int subscriptionType) {
-        ContentResolver resolver = mContext.getContentResolver();
-        ContentValues value = new ContentValues();
-        value.put(SubscriptionManager.ICC_ID, uniqueId);
-        int color = getUnusedColor(mContext.getOpPackageName(), mContext.getAttributionTag());
-        // default SIM color differs between slots
-        value.put(SubscriptionManager.HUE, color);
-        value.put(SubscriptionManager.SIM_SLOT_INDEX, slotIndex);
-        value.put(SubscriptionManager.CARRIER_NAME, "");
-        value.put(SubscriptionManager.CARD_ID, uniqueId);
-        value.put(SubscriptionManager.SUBSCRIPTION_TYPE, subscriptionType);
-        if (!TextUtils.isEmpty(displayName)) {
-            value.put(SubscriptionManager.DISPLAY_NAME, displayName);
-        }
-        if (!isSubscriptionForRemoteSim(subscriptionType)) {
-            UiccCard card = mUiccController.getUiccCardForPhone(slotIndex);
-            if (card != null) {
-                String cardId = card.getCardId();
-                if (cardId != null) {
-                    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
-        refreshCachedActiveSubscriptionInfoList();
-
-        return uri;
-    }
-
-    /**
-     * Generate and set carrier text based on input parameters
-     * @param showPlmn flag to indicate if plmn should be included in carrier text
-     * @param plmn plmn to be included in carrier text
-     * @param showSpn flag to indicate if spn should be included in carrier text
-     * @param spn spn to be included in carrier text
-     * @return true if carrier text is set, false otherwise
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public boolean setPlmnSpn(int slotIndex, boolean showPlmn, String plmn, boolean showSpn,
-                              String spn) {
-        synchronized (mLock) {
-            int subId = getSubId(slotIndex);
-            if (mContext.getPackageManager().resolveContentProvider(
-                    SubscriptionManager.CONTENT_URI.getAuthority(), 0) == null ||
-                    !SubscriptionManager.isValidSubscriptionId(subId)) {
-                // No place to store this info. Notify registrants of the change anyway as they
-                // might retrieve the SPN/PLMN text from the SST sticky broadcast.
-                // TODO: This can be removed once SubscriptionController is not running on devices
-                // that don't need it, such as TVs.
-                if (DBG) logd("[setPlmnSpn] No valid subscription to store info");
-                notifySubscriptionInfoChanged();
-                return false;
-            }
-            String carrierText = "";
-            if (showPlmn) {
-                carrierText = plmn;
-                if (showSpn) {
-                    // Need to show both plmn and spn if both are not same.
-                    if(!Objects.equals(spn, plmn)) {
-                        String separator = mContext.getString(
-                                com.android.internal.R.string.kg_text_message_separator).toString();
-                        carrierText = new StringBuilder().append(carrierText).append(separator)
-                                .append(spn).toString();
-                    }
-                }
-            } else if (showSpn) {
-                carrierText = spn;
-            }
-            setCarrierText(carrierText, subId);
-            return true;
-        }
-    }
-
-    /**
-     * Set carrier text by simInfo index
-     * @param text new carrier text
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     */
-    private int setCarrierText(String text, int subId) {
-        if (DBG) logd("[setCarrierText]+ text:" + text + " subId:" + subId);
-
-        enforceModifyPhoneState("setCarrierText");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            boolean update = true;
-            int result = 0;
-            SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-            if (subInfo != null) {
-                update = !TextUtils.equals(text, subInfo.getCarrierName());
-            }
-            if (update) {
-                ContentValues value = new ContentValues(1);
-                value.put(SubscriptionManager.CARRIER_NAME, text);
-
-                result = mContext.getContentResolver().update(
-                        SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-
-                // Refresh the Cache of Active Subscription Info List
-                refreshCachedActiveSubscriptionInfoList();
-
-                notifySubscriptionInfoChanged();
-            } else {
-                if (DBG) logd("[setCarrierText]: no value update");
-            }
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set SIM color tint by simInfo index
-     *
-     * @param subId the unique SubInfoRecord index in database
-     * @param tint the tint color of the SIM
-     *
-     * @return the number of records updated
-     */
-    @Override
-    public int setIconTint(int subId, int tint) {
-        if (DBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
-
-        enforceModifyPhoneState("setIconTint");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.HUE, tint);
-            if (DBG) logd("[setIconTint]- tint:" + tint + " set");
-
-            int result = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * This is only for internal use and the returned priority is arbitrary. The idea is to give a
-     * higher value to name source that has higher priority to override other name sources.
-     * @param nameSource Source of display name
-     * @return int representing the priority. Higher value means higher priority.
-     */
-    public static int getNameSourcePriority(@SimDisplayNameSource int nameSource) {
-        int index = Arrays.asList(
-                SubscriptionManager.NAME_SOURCE_CARRIER_ID,
-                SubscriptionManager.NAME_SOURCE_SIM_PNN,
-                SubscriptionManager.NAME_SOURCE_SIM_SPN,
-                SubscriptionManager.NAME_SOURCE_CARRIER,
-                SubscriptionManager.NAME_SOURCE_USER_INPUT // user has highest priority.
-        ).indexOf(nameSource);
-        return (index < 0) ? 0 : index;
-    }
-
-    /**
-     * Validate whether the NAME_SOURCE_SIM_PNN, NAME_SOURCE_SIM_SPN and
-     * NAME_SOURCE_CARRIER exist or not.
-     */
-    @VisibleForTesting
-    public boolean isExistingNameSourceStillValid(SubscriptionInfo subInfo) {
-
-        int subId = subInfo.getSubscriptionId();
-        int phoneId = getPhoneId(subInfo.getSubscriptionId());
-
-        Phone phone = PhoneFactory.getPhone(phoneId);
-        if (phone == null) {
-            return true;
-        }
-
-        String spn;
-
-        switch (subInfo.getDisplayNameSource()) {
-            case SubscriptionManager.NAME_SOURCE_SIM_PNN:
-                String pnn = phone.getPlmn();
-                return !TextUtils.isEmpty(pnn);
-            case SubscriptionManager.NAME_SOURCE_SIM_SPN:
-                spn = getServiceProviderName(phoneId);
-                return !TextUtils.isEmpty(spn);
-            case SubscriptionManager.NAME_SOURCE_CARRIER:
-                // Can not validate eSIM since it should not override with a lower priority source
-                // if the name is actually coming from eSIM and not from carrier config.
-                if (subInfo.isEmbedded()) {
-                    return true;
-                }
-                CarrierConfigManager configLoader =
-                        mContext.getSystemService(CarrierConfigManager.class);
-                PersistableBundle config =
-                        configLoader.getConfigForSubId(subId);
-                if (config == null) {
-                    return true;
-                }
-                boolean isCarrierNameOverride = config.getBoolean(
-                        CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
-                String carrierName = config.getString(
-                        CarrierConfigManager.KEY_CARRIER_NAME_STRING);
-                spn = getServiceProviderName(phoneId);
-                return isCarrierNameOverride
-                        || (TextUtils.isEmpty(spn) && !TextUtils.isEmpty(carrierName));
-            case SubscriptionManager.NAME_SOURCE_CARRIER_ID:
-            case SubscriptionManager.NAME_SOURCE_USER_INPUT:
-                return true;
-        }
-        return false;
-    }
-
-    @VisibleForTesting
-    public String getServiceProviderName(int phoneId) {
-        UiccProfile profile = mUiccController.getUiccProfileForPhone(phoneId);
-        if (profile == null) {
-            return null;
-        }
-        return profile.getServiceProviderName();
-    }
-
-    /**
-     * Set display name by simInfo index with name source
-     * @param displayName the display name of SIM card
-     * @param subId the unique SubInfoRecord index in database
-     * @param nameSource SIM display name source
-     * @return the number of records updated
-     */
-    @Override
-    public int setDisplayNameUsingSrc(String displayName, int subId,
-                                      @SimDisplayNameSource int nameSource) {
-        if (DBG) {
-            logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
-                + " nameSource:" + nameSource);
-        }
-
-        enforceModifyPhoneState("setDisplayNameUsingSrc");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            List<SubscriptionInfo> allSubInfo = getSubInfo(null, null);
-            // if there is no sub in the db, return 0 since subId does not exist in db
-            if (allSubInfo == null || allSubInfo.isEmpty()) return 0;
-            for (SubscriptionInfo subInfo : allSubInfo) {
-                int subInfoNameSource = subInfo.getDisplayNameSource();
-                boolean isHigherPriority = (getNameSourcePriority(subInfoNameSource)
-                        > getNameSourcePriority(nameSource));
-                boolean isEqualPriorityAndName = (getNameSourcePriority(subInfoNameSource)
-                        == getNameSourcePriority(nameSource))
-                        && (TextUtils.equals(displayName, subInfo.getDisplayName()));
-                if (subInfo.getSubscriptionId() == subId
-                        && isExistingNameSourceStillValid(subInfo)
-                        && (isHigherPriority || isEqualPriorityAndName)) {
-                    logd("Name source " + subInfoNameSource + "'s priority "
-                            + getNameSourcePriority(subInfoNameSource) + " is greater than "
-                            + "name source " + nameSource + "'s priority "
-                            + getNameSourcePriority(nameSource) + ", return now.");
-                    return 0;
-                }
-            }
-            String nameToSet;
-            if (TextUtils.isEmpty(displayName) || displayName.trim().length() == 0) {
-                nameToSet = mTelephonyManager.getSimOperatorName(subId);
-                if (TextUtils.isEmpty(nameToSet)) {
-                    if (nameSource == SubscriptionManager.NAME_SOURCE_USER_INPUT
-                            && SubscriptionManager.isValidSlotIndex(getSlotIndex(subId))) {
-                        nameToSet = "CARD " + (getSlotIndex(subId) + 1);
-                    } else {
-                        nameToSet = mContext.getString(SubscriptionManager.DEFAULT_NAME_RES);
-                    }
-                }
-            } else {
-                nameToSet = displayName;
-            }
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.DISPLAY_NAME, nameToSet);
-            if (nameSource >= SubscriptionManager.NAME_SOURCE_CARRIER_ID) {
-                if (DBG) logd("Set nameSource=" + nameSource);
-                value.put(SubscriptionManager.NAME_SOURCE, nameSource);
-            }
-            if (DBG) logd("[setDisplayName]- mDisplayName:" + nameToSet + " set");
-
-            // Update the nickname on the eUICC chip if it's an embedded subscription.
-            SubscriptionInfo sub = getSubscriptionInfo(subId);
-            if (sub != null && sub.isEmbedded()) {
-                // Ignore the result.
-                int cardId = sub.getCardId();
-                if (DBG) logd("Updating embedded sub nickname on cardId: " + cardId);
-                EuiccManager euiccManager = ((EuiccManager)
-                        mContext.getSystemService(Context.EUICC_SERVICE)).createForCardId(cardId);
-                euiccManager.updateSubscriptionNickname(subId, displayName,
-                        // This PendingIntent simply fulfills the requirement to pass in a callback;
-                        // we don't care about the result (hence 0 requestCode and no action
-                        // specified on the intent).
-                        PendingIntent.getService(
-                            mContext, 0 /* requestCode */, new Intent(),
-                                PendingIntent.FLAG_IMMUTABLE /* flags */));
-            }
-
-            int result = updateDatabase(value, subId, true);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set phone number by subId
-     * @param number the phone number of the SIM
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     */
-    @Override
-    public int setDisplayNumber(String number, int subId) {
-        if (DBG) logd("[setDisplayNumber]+ subId:" + subId);
-
-        enforceModifyPhoneState("setDisplayNumber");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            int result = 0;
-            int phoneId = getPhoneId(subId);
-
-            if (number == null || phoneId < 0 ||
-                    phoneId >= mTelephonyManager.getPhoneCount()) {
-                if (DBG) logd("[setDisplayNumber]- fail");
-                return -1;
-            }
-            boolean update = true;
-            SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-            if (subInfo != null) {
-                update = !TextUtils.equals(subInfo.getNumber(), number);
-            }
-            if (update) {
-                ContentValues value = new ContentValues(1);
-                value.put(SubscriptionManager.NUMBER, number);
-
-                // This function had a call to update number on the SIM (Phone.setLine1Number()) but
-                // that was removed as there doesn't seem to be a reason for that. If it is added
-                // back, watch out for deadlocks.
-                result = mContext.getContentResolver().update(
-                        SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-                if (DBG) logd("[setDisplayNumber]- update result :" + result);
-                // Refresh the Cache of Active Subscription Info List
-                refreshCachedActiveSubscriptionInfoList();
-                notifySubscriptionInfoChanged();
-            } else {
-                if (DBG) logd("[setDisplayNumber]: no value update");
-            }
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set the EHPLMNs and HPLMNs associated with the subscription.
-     */
-    public void setAssociatedPlmns(String[] ehplmns, String[] hplmns, int subId) {
-        if (DBG) logd("[setAssociatedPlmns]+ subId:" + subId);
-
-        validateSubId(subId);
-        int phoneId = getPhoneId(subId);
-
-        if (phoneId < 0 || phoneId >= mTelephonyManager.getPhoneCount()) {
-            if (DBG) logd("[setAssociatedPlmns]- fail");
-            return;
-        }
-
-        // remove trailing empty strings which will also get stripped from
-        // SubscriptionInfo.getEhplmns() and SubscriptionInfo.getHplmns()
-        String formattedEhplmns = ehplmns == null ? "" :
-                Arrays.stream(ehplmns).filter(s -> s != null && !s.isEmpty())
-                        .collect(Collectors.joining(","));
-        String formattedHplmns = hplmns == null ? "" :
-                Arrays.stream(hplmns).filter(s -> s != null && !s.isEmpty())
-                        .collect(Collectors.joining(","));
-        boolean noChange = false;
-        SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-        if (subInfo != null) {
-            noChange = (ehplmns == null && subInfo.getEhplmns().isEmpty())
-                    || String.join(",", subInfo.getEhplmns()).equals(formattedEhplmns);
-            noChange = noChange && (hplmns == null && subInfo.getHplmns().isEmpty())
-                    || String.join(",", subInfo.getHplmns()).equals(formattedHplmns);
-        }
-        if (!noChange) {
-            ContentValues value = new ContentValues(2);
-            value.put(SubscriptionManager.EHPLMNS, formattedEhplmns);
-            value.put(SubscriptionManager.HPLMNS, formattedHplmns);
-
-            int count = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-            if (DBG) logd("[setAssociatedPlmns]- update result :" + count);
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-            notifySubscriptionInfoChanged();
-        } else {
-            if (DBG) logd("[setAssociatedPlmns]+ subId:" + subId + "no value update");
-        }
-    }
-
-    /**
-     * Set data roaming by simInfo index
-     * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     */
-    @Override
-    public int setDataRoaming(int roaming, int subId) {
-        if (DBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
-
-        enforceModifyPhoneState("setDataRoaming");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            if (roaming < 0) {
-                if (DBG) logd("[setDataRoaming]- fail");
-                return -1;
-            }
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.DATA_ROAMING, roaming);
-            if (DBG) logd("[setDataRoaming]- roaming:" + roaming + " set");
-
-            int result = updateDatabase(value, subId, true);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set device to device status sharing preference
-     * @param sharing the sharing preference to set
-     * @param subId
-     * @return the number of records updated
-     */
-    @Override
-    public int setDeviceToDeviceStatusSharing(int sharing, int subId) {
-        if (DBG) logd("[setDeviceToDeviceStatusSharing]- sharing:" + sharing + " subId:" + subId);
-
-        enforceModifyPhoneState("setDeviceToDeviceStatusSharing");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            if (sharing < 0) {
-                if (DBG) logd("[setDeviceToDeviceStatusSharing]- fail");
-                return -1;
-            }
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.D2D_STATUS_SHARING, sharing);
-            if (DBG) logd("[setDeviceToDeviceStatusSharing]- sharing:" + sharing + " set");
-
-            int result = updateDatabase(value, subId, true);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set contacts that allow device to device status sharing.
-     * @param contacts contacts to set
-     * @param subscriptionId
-     * @return the number of records updated
-     */
-    @Override
-    public int setDeviceToDeviceStatusSharingContacts(String contacts, int subscriptionId) {
-        if (DBG) {
-            logd("[setDeviceToDeviceStatusSharingContacts]- contacts:" + contacts
-                    + " subId:" + subscriptionId);
-        }
-
-        enforceModifyPhoneState("setDeviceToDeviceStatusSharingContacts");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subscriptionId);
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.D2D_STATUS_SHARING_SELECTED_CONTACTS, contacts);
-            if (DBG) {
-                logd("[setDeviceToDeviceStatusSharingContacts]- contacts:" + contacts
-                        + " set");
-            }
-
-            int result = updateDatabase(value, subscriptionId, true);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    public void syncGroupedSetting(int refSubId) {
-        logd("syncGroupedSetting");
-        try (Cursor cursor = mContext.getContentResolver().query(
-                SubscriptionManager.CONTENT_URI, null,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
-                new String[] {String.valueOf(refSubId)}, null)) {
-            if (cursor == null || !cursor.moveToFirst()) {
-                logd("[syncGroupedSetting] failed. Can't find refSubId " + refSubId);
-                return;
-            }
-
-            ContentValues values = new ContentValues(GROUP_SHARING_PROPERTIES.size());
-            for (String propKey : GROUP_SHARING_PROPERTIES) {
-                copyDataFromCursorToContentValue(propKey, cursor, values);
-            }
-            updateDatabase(values, refSubId, true);
-        }
-    }
-
-    private void copyDataFromCursorToContentValue(String propKey, Cursor cursor,
-            ContentValues values) {
-        int columnIndex = cursor.getColumnIndex(propKey);
-        if (columnIndex == -1) {
-            logd("[copyDataFromCursorToContentValue] can't find column " + propKey);
-            return;
-        }
-
-        switch (propKey) {
-            case SubscriptionManager.ENHANCED_4G_MODE_ENABLED:
-            case SubscriptionManager.VT_IMS_ENABLED:
-            case SubscriptionManager.WFC_IMS_ENABLED:
-            case SubscriptionManager.WFC_IMS_MODE:
-            case SubscriptionManager.WFC_IMS_ROAMING_MODE:
-            case SubscriptionManager.WFC_IMS_ROAMING_ENABLED:
-            case SubscriptionManager.DATA_ROAMING:
-            case SubscriptionManager.IMS_RCS_UCE_ENABLED:
-            case SubscriptionManager.CROSS_SIM_CALLING_ENABLED:
-            case SubscriptionManager.NR_ADVANCED_CALLING_ENABLED:
-            case SubscriptionManager.USER_HANDLE:
-                values.put(propKey, cursor.getInt(columnIndex));
-                break;
-            case SubscriptionManager.DISPLAY_NAME:
-            case SubscriptionManager.ENABLED_MOBILE_DATA_POLICIES:
-                values.put(propKey, cursor.getString(columnIndex));
-                break;
-            default:
-                loge("[copyDataFromCursorToContentValue] invalid propKey " + propKey);
-        }
-    }
-
-    // TODO: replace all updates with this helper method.
-    private int updateDatabase(ContentValues value, int subId, boolean updateEntireGroup) {
-        List<SubscriptionInfo> infoList = getSubscriptionsInGroup(getGroupUuid(subId),
-                mContext.getOpPackageName(), mContext.getAttributionTag());
-        if (!updateEntireGroup || infoList == null || infoList.size() == 0) {
-            // Only update specified subscriptions.
-            return mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-        } else {
-            // Update all subscriptions in the same group.
-            int[] subIdList = new int[infoList.size()];
-            for (int i = 0; i < infoList.size(); i++) {
-                subIdList[i] = infoList.get(i).getSubscriptionId();
-            }
-            return mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
-                    value, getSelectionForSubIdList(subIdList), null);
-        }
-    }
-
-    /**
-     * Set carrier id by subId
-     * @param carrierId the subscription carrier id.
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     *
-     * @see TelephonyManager#getSimCarrierId()
-     */
-    public int setCarrierId(int carrierId, int subId) {
-        if (DBG) logd("[setCarrierId]+ carrierId:" + carrierId + " subId:" + subId);
-
-        enforceModifyPhoneState("setCarrierId");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            validateSubId(subId);
-            int result = 0;
-            boolean update = true;
-            SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-            if (subInfo != null) {
-                update = subInfo.getCarrierId() != carrierId;
-            }
-            if (update) {
-                ContentValues value = new ContentValues(1);
-                value.put(SubscriptionManager.CARRIER_ID, carrierId);
-                result = mContext.getContentResolver().update(
-                        SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-
-                // Refresh the Cache of Active Subscription Info List
-                refreshCachedActiveSubscriptionInfoList();
-
-                notifySubscriptionInfoChanged();
-            } else {
-                if (DBG) logd("[setCarrierId]: no value update");
-            }
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set MCC/MNC by subscription ID
-     * @param mccMnc MCC/MNC associated with the subscription
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     */
-    public int setMccMnc(String mccMnc, int subId) {
-        String mccString = mccMnc.substring(0, 3);
-        String mncString = mccMnc.substring(3);
-        int mcc = 0;
-        int mnc = 0;
-        try {
-            mcc = Integer.parseInt(mccString);
-            mnc = Integer.parseInt(mncString);
-        } catch (NumberFormatException e) {
-            loge("[setMccMnc] - couldn't parse mcc/mnc: " + mccMnc);
-        }
-        SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-        // check if there are any update
-        boolean update = true;
-        if (subInfo != null) {
-            update = (subInfo.getMcc() != mcc) || (subInfo.getMnc() != mnc)
-                    || !mccString.equals(subInfo.getMccString())
-                    || !mncString.equals(subInfo.getMncString());
-        }
-        int result = 0;
-        if (update) {
-            ContentValues value = new ContentValues(4);
-            value.put(SubscriptionManager.MCC, mcc);
-            value.put(SubscriptionManager.MNC, mnc);
-            value.put(SubscriptionManager.MCC_STRING, mccString);
-            value.put(SubscriptionManager.MNC_STRING, mncString);
-
-            result = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-            if (DBG) logd("[setMccMnc]+ mcc/mnc:" + mcc + "/" + mnc + " subId:" + subId);
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-            notifySubscriptionInfoChanged();
-        } else {
-            if (DBG) logd("[setMccMnc] - no values update");
-        }
-        return result;
-    }
-
-    /**
-     * Scrub given IMSI on production builds.
-     */
-    private String scrubImsi(String imsi) {
-        if (Build.IS_ENG) {
-            return imsi;
-        } else if (imsi != null) {
-            return imsi.substring(0, Math.min(6, imsi.length())) + "...";
-        } else {
-            return "null";
-        }
-    }
-
-    /**
-     * Set IMSI by subscription ID
-     * @param imsi IMSI (International Mobile Subscriber Identity)
-     * @return the number of records updated
-     */
-    public int setImsi(String imsi, int subId) {
-        if (DBG) logd("[setImsi]+ imsi:" + scrubImsi(imsi) + " subId:" + subId);
-        boolean update = true;
-        int result = 0;
-        SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-        if (subInfo != null) {
-            update = !TextUtils.equals(getImsiPrivileged(subId),imsi);
-        }
-
-        if (update) {
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.IMSI, imsi);
-            result = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-        } else {
-            if (DBG) logd("[setImsi]: no value update");
-        }
-        return result;
-    }
-
-    /**
-     * Set uicc applications being enabled or disabled.
-     * @param enabled whether uicc applications are enabled or disabled.
-     * @return the number of records updated
-     */
-    public int setUiccApplicationsEnabled(boolean enabled, int subId) {
-        if (DBG) logd("[setUiccApplicationsEnabled]+ enabled:" + enabled + " subId:" + subId);
-
-        enforceModifyPhoneState("setUiccApplicationsEnabled");
-
-        long identity = Binder.clearCallingIdentity();
-        try {
-            ContentValues value = new ContentValues(1);
-            value.put(SubscriptionManager.UICC_APPLICATIONS_ENABLED, enabled);
-
-            int result = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifyUiccAppsEnableChanged();
-            notifySubscriptionInfoChanged();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Register to change of uicc applications enablement changes.
-     * @param notifyNow whether to notify target upon registration.
-     */
-    public void registerForUiccAppsEnabled(Handler handler, int what, Object object,
-            boolean notifyNow) {
-        mUiccAppsEnableChangeRegList.addUnique(handler, what, object);
-        if (notifyNow) {
-            handler.obtainMessage(what, object).sendToTarget();
-        }
-    }
-
-    /**
-     * Unregister to change of uicc applications enablement changes.
-     */
-    public void unregisterForUiccAppsEnabled(Handler handler) {
-        mUiccAppsEnableChangeRegList.remove(handler);
-    }
-
-    private void notifyUiccAppsEnableChanged() {
-        mUiccAppsEnableChangeRegList.notifyRegistrants();
-    }
-
-    /**
-     * Get IMSI by subscription ID
-     * For active subIds, this will always return the corresponding imsi
-     * For inactive subIds, once they are activated once, even if they are deactivated at the time
-     *   of calling this function, the corresponding imsi will be returned
-     * When calling this method, the permission check should have already been done to allow
-     *   only privileged read
-     *
-     * @return imsi
-     */
-    public String getImsiPrivileged(int subId) {
-        try (Cursor cursor = mContext.getContentResolver().query(
-                SubscriptionManager.CONTENT_URI, null,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
-                new String[] {String.valueOf(subId)}, null)) {
-            String imsi = null;
-            if (cursor != null) {
-                if (cursor.moveToNext()) {
-                    imsi = getOptionalStringFromCursor(cursor, SubscriptionManager.IMSI,
-                            /*defaultVal*/ null);
-                }
-            } else {
-                logd("getImsiPrivileged: failed to retrieve imsi.");
-            }
-
-            return imsi;
-        }
-    }
-
-    /**
-     * Set ISO country code by subscription ID
-     * @param iso iso country code associated with the subscription
-     * @param subId the unique SubInfoRecord index in database
-     * @return the number of records updated
-     */
-    public int setCountryIso(String iso, int subId) {
-        if (DBG) logd("[setCountryIso]+ iso:" + iso + " subId:" + subId);
-        boolean update = true;
-        int result = 0;
-        SubscriptionInfo subInfo = getSubscriptionInfo(subId);
-        if (subInfo != null) {
-            update = !TextUtils.equals(subInfo.getCountryIso(), iso);
-        }
-        if (update) {
-            ContentValues value = new ContentValues();
-            value.put(SubscriptionManager.ISO_COUNTRY_CODE, iso);
-
-            result = mContext.getContentResolver().update(
-                    SubscriptionManager.getUriForSubscriptionId(subId), value, null, null);
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-        } else {
-            if (DBG) logd("[setCountryIso]: no value update");
-        }
-        return result;
-    }
-
-    @Override
-    public int getSlotIndex(int subId) {
-        if (VDBG) printStackTrace("[getSlotIndex] subId=" + subId);
-
-        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            subId = getDefaultSubId();
-        }
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            if (DBG) logd("[getSlotIndex]- subId invalid");
-            return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-        }
-
-        int size = mSlotIndexToSubIds.size();
-
-        if (size == 0) {
-            if (DBG) logd("[getSlotIndex]- size == 0, return SIM_NOT_INSERTED instead");
-            return SubscriptionManager.SIM_NOT_INSERTED;
-        }
-
-        for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
-            int sim = entry.getKey();
-            ArrayList<Integer> subs = entry.getValue();
-
-            if (subs != null && subs.contains(subId)) {
-                if (VDBG) logv("[getSlotIndex]- return = " + sim);
-                return sim;
-            }
-        }
-
-        if (DBG) logd("[getSlotIndex]- return fail");
-        return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-    }
-
-    /**
-     * Return the subIds for specified slot Id.
-     * @deprecated
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    @Deprecated
-    public int[] getSubIds(int slotIndex) {
-        if (VDBG) printStackTrace("[getSubId]+ slotIndex=" + slotIndex);
-
-        // Map default slotIndex to the current default subId.
-        // TODO: Not used anywhere sp consider deleting as it's somewhat nebulous
-        // as a slot maybe used for multiple different type of "connections"
-        // such as: voice, data and sms. But we're doing the best we can and using
-        // getDefaultSubId which makes a best guess.
-        if (slotIndex == SubscriptionManager.DEFAULT_SIM_SLOT_INDEX) {
-            slotIndex = getSlotIndex(getDefaultSubId());
-            if (VDBG) logd("[getSubId] map default slotIndex=" + slotIndex);
-        }
-
-        // Check that we have a valid slotIndex or the slotIndex is for a remote SIM (remote SIM
-        // uses special slot index that may be invalid otherwise)
-        if (!SubscriptionManager.isValidSlotIndex(slotIndex)
-                && slotIndex != SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB) {
-            if (DBG) logd("[getSubId]- invalid slotIndex=" + slotIndex);
-            return null;
-        }
-
-        // Check if we've got any SubscriptionInfo records using slotIndexToSubId as a surrogate.
-        int size = mSlotIndexToSubIds.size();
-        if (size == 0) {
-            if (VDBG) {
-                logd("[getSubId]- sSlotIndexToSubIds.size == 0, return null slotIndex="
-                        + slotIndex);
-            }
-            return null;
-        }
-
-        // Convert ArrayList to array
-        ArrayList<Integer> subIds = mSlotIndexToSubIds.getCopy(slotIndex);
-        if (subIds != null && subIds.size() > 0) {
-            int[] subIdArr = new int[subIds.size()];
-            for (int i = 0; i < subIds.size(); i++) {
-                subIdArr[i] = subIds.get(i);
-            }
-            if (VDBG) logd("[getSubId]- subIdArr=" + Arrays.toString(subIdArr));
-            return subIdArr;
-        } else {
-            if (DBG) logd("[getSubId]- numSubIds == 0, return null slotIndex=" + slotIndex);
-            return null;
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public int getPhoneId(int subId) {
-        if (VDBG) printStackTrace("[getPhoneId] subId=" + subId);
-        int phoneId;
-
-        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            subId = getDefaultSubId();
-            if (DBG) logd("[getPhoneId] asked for default subId=" + subId);
-        }
-
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            if (VDBG) {
-                logdl("[getPhoneId]- invalid subId return="
-                        + SubscriptionManager.INVALID_PHONE_INDEX);
-            }
-            return SubscriptionManager.INVALID_PHONE_INDEX;
-        }
-
-        int size = mSlotIndexToSubIds.size();
-        if (size == 0) {
-            phoneId = mDefaultPhoneId;
-            if (VDBG) logdl("[getPhoneId]- no sims, returning default phoneId=" + phoneId);
-            return phoneId;
-        }
-
-        // FIXME: Assumes phoneId == slotIndex
-        for (Entry<Integer, ArrayList<Integer>> entry: mSlotIndexToSubIds.entrySet()) {
-            int sim = entry.getKey();
-            ArrayList<Integer> subs = entry.getValue();
-
-            if (subs != null && subs.contains(subId)) {
-                if (VDBG) logdl("[getPhoneId]- found subId=" + subId + " phoneId=" + sim);
-                return sim;
-            }
-        }
-
-        phoneId = mDefaultPhoneId;
-        if (VDBG) {
-            logd("[getPhoneId]- subId=" + subId + " not found return default phoneId=" + phoneId);
-        }
-        return phoneId;
-
-    }
-
-    /**
-     * @return the number of records cleared
-     */
-    public int clearSubInfo() {
-        enforceModifyPhoneState("clearSubInfo");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            int size = mSlotIndexToSubIds.size();
-
-            if (size == 0) {
-                if (DBG) logdl("[clearSubInfo]- no simInfo size=" + size);
-                return 0;
-            }
-
-            mSlotIndexToSubIds.clear();
-            if (DBG) logdl("[clearSubInfo]- clear size=" + size);
-            return size;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    private void logvl(String msg) {
-        logv(msg);
-        mLocalLog.log(msg);
-    }
-
-    private void logv(String msg) {
-        Rlog.v(LOG_TAG, msg);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected void logdl(String msg) {
-        logd(msg);
-        mLocalLog.log(msg);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void logd(String msg) {
-        Rlog.d(LOG_TAG, msg);
-    }
-
-    private void logel(String msg) {
-        loge(msg);
-        mLocalLog.log(msg);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void loge(String msg) {
-        Rlog.e(LOG_TAG, msg);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public int getDefaultSubId() {
-        int subId;
-        boolean isVoiceCapable = mTelephonyManager.isVoiceCapable();
-        if (isVoiceCapable) {
-            subId = getDefaultVoiceSubId();
-            if (VDBG) logdl("[getDefaultSubId] isVoiceCapable subId=" + subId);
-        } else {
-            subId = getDefaultDataSubId();
-            if (VDBG) logdl("[getDefaultSubId] NOT VoiceCapable subId=" + subId);
-        }
-        if (!isActiveSubId(subId)) {
-            subId = mDefaultFallbackSubId.get();
-            if (VDBG) logdl("[getDefaultSubId] NOT active use fall back subId=" + subId);
-        }
-        if (VDBG) logv("[getDefaultSubId]- value = " + subId);
-        return subId;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public void setDefaultSmsSubId(int subId) {
-        enforceModifyPhoneState("setDefaultSmsSubId");
-
-        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            throw new RuntimeException("setDefaultSmsSubId called with DEFAULT_SUB_ID");
-        }
-        if (DBG) logdl("[setDefaultSmsSubId] subId=" + subId);
-        setGlobalSetting(Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION, subId);
-        broadcastDefaultSmsSubIdChanged(subId);
-    }
-
-    private void broadcastDefaultSmsSubIdChanged(int subId) {
-        // Broadcast an Intent for default sms sub change
-        if (DBG) logdl("[broadcastDefaultSmsSubIdChanged] subId=" + subId);
-        Intent intent = new Intent(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public int getDefaultSmsSubId() {
-        int subId = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        if (VDBG) logd("[getDefaultSmsSubId] subId=" + subId);
-        return subId;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public void setDefaultVoiceSubId(int subId) {
-        enforceModifyPhoneState("setDefaultVoiceSubId");
-
-        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            throw new RuntimeException("setDefaultVoiceSubId called with DEFAULT_SUB_ID");
-        }
-
-        logdl("[setDefaultVoiceSubId] subId=" + subId);
-
-        int previousDefaultSub = getDefaultSubId();
-
-        setGlobalSetting(Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION, subId);
-        broadcastDefaultVoiceSubIdChanged(subId);
-
-        PhoneAccountHandle newHandle =
-                subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                        ? null : mTelephonyManager.getPhoneAccountHandleForSubscriptionId(
-                        subId);
-
-        TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
-
-        telecomManager.setUserSelectedOutgoingPhoneAccount(newHandle);
-        logd("[setDefaultVoiceSubId] requesting change to phoneAccountHandle=" + newHandle);
-
-        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));
-        }
-    }
-
-    /**
-     * Broadcast intent of ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED.
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void broadcastDefaultVoiceSubIdChanged(int subId) {
-        // Broadcast an Intent for default voice sub change
-        if (DBG) logdl("[broadcastDefaultVoiceSubIdChanged] subId=" + subId);
-        Intent intent = new Intent(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public int getDefaultVoiceSubId() {
-        int subId = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        if (VDBG) logd("[getDefaultVoiceSubId] subId=" + subId);
-        return subId;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public int getDefaultDataSubId() {
-        int subId = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        if (VDBG) logd("[getDefaultDataSubId] subId=" + subId);
-        return subId;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Override
-    public void setDefaultDataSubId(int subId) {
-        enforceModifyPhoneState("setDefaultDataSubId");
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-                throw new RuntimeException("setDefaultDataSubId called with DEFAULT_SUB_ID");
-            }
-
-            ProxyController proxyController = ProxyController.getInstance();
-            int len = TelephonyManager.from(mContext).getActiveModemCount();
-            logdl("[setDefaultDataSubId] num phones=" + len + ", subId=" + subId);
-
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                // Only re-map modems if the new default data sub is valid
-                RadioAccessFamily[] rafs = new RadioAccessFamily[len];
-                boolean atLeastOneMatch = false;
-                for (int phoneId = 0; phoneId < len; phoneId++) {
-                    Phone phone = PhoneFactory.getPhone(phoneId);
-                    int raf;
-                    int id = phone.getSubId();
-                    if (id == subId) {
-                        // TODO Handle the general case of N modems and M subscriptions.
-                        raf = proxyController.getMaxRafSupported();
-                        atLeastOneMatch = true;
-                    } else {
-                        // TODO Handle the general case of N modems and M subscriptions.
-                        raf = proxyController.getMinRafSupported();
-                    }
-                    logdl("[setDefaultDataSubId] phoneId=" + phoneId + " subId=" + id + " RAF="
-                            + raf);
-                    rafs[phoneId] = new RadioAccessFamily(phoneId, raf);
-                }
-                if (atLeastOneMatch) {
-                    proxyController.setRadioCapability(rafs);
-                } else {
-                    if (DBG) logdl("[setDefaultDataSubId] no valid subId's found - not updating.");
-                }
-            }
-
-            int previousDefaultSub = getDefaultSubId();
-            setGlobalSetting(Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
-            MultiSimSettingController.getInstance().notifyDefaultDataSubChanged();
-            broadcastDefaultDataSubIdChanged(subId);
-            if (previousDefaultSub != getDefaultSubId()) {
-                sendDefaultChangedBroadcast(getDefaultSubId());
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void broadcastDefaultDataSubIdChanged(int subId) {
-        // Broadcast an Intent for default data sub change
-        if (DBG) logdl("[broadcastDefaultDataSubIdChanged] subId=" + subId);
-        Intent intent = new Intent(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /* Sets the default subscription. If only one sub is active that
-     * sub is set as default subId. If two or more  sub's are active
-     * the first sub is set as default subscription
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected void setDefaultFallbackSubId(int subId, int subscriptionType) {
-        if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            throw new RuntimeException("setDefaultSubId called with DEFAULT_SUB_ID");
-        }
-        if (DBG) {
-            logdl("[setDefaultFallbackSubId] subId=" + subId + ", subscriptionType="
-                    + subscriptionType);
-        }
-        int previousDefaultSub = getDefaultSubId();
-        if (isSubscriptionForRemoteSim(subscriptionType)) {
-            mDefaultFallbackSubId.set(subId);
-            return;
-        }
-        if (SubscriptionManager.isValidSubscriptionId(subId)) {
-            int phoneId = getPhoneId(subId);
-            if (phoneId >= 0 && (phoneId < mTelephonyManager.getPhoneCount()
-                    || mTelephonyManager.getSimCount() == 1)) {
-                if (DBG) logdl("[setDefaultFallbackSubId] set sDefaultFallbackSubId=" + subId);
-                mDefaultFallbackSubId.set(subId);
-                // Update MCC MNC device configuration information
-                String defaultMccMnc = mTelephonyManager.getSimOperatorNumericForPhone(phoneId);
-                MccTable.updateMccMncConfiguration(mContext, defaultMccMnc);
-            } else {
-                if (DBG) {
-                    logdl("[setDefaultFallbackSubId] not set invalid phoneId=" + phoneId
-                            + " subId=" + subId);
-                }
-            }
-        }
-        if (previousDefaultSub != getDefaultSubId()) {
-            sendDefaultChangedBroadcast(getDefaultSubId());
-        }
-    }
-
-    public void sendDefaultChangedBroadcast(int subId) {
-        // Broadcast an Intent for default sub change
-        int phoneId = SubscriptionManager.getPhoneId(subId);
-        Intent intent = new Intent(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId, subId);
-        if (DBG) {
-            logdl("[sendDefaultChangedBroadcast] broadcast default subId changed phoneId="
-                    + phoneId + " subId=" + subId);
-        }
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /**
-     * Whether a subscription is opportunistic or not.
-     */
-    public boolean isOpportunistic(int subId) {
-        SubscriptionInfo info = getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
-                mContext.getAttributionTag());
-        return (info != null) && info.isOpportunistic();
-    }
-
-    // FIXME: We need we should not be assuming phoneId == slotIndex as it will not be true
-    // when there are multiple subscriptions per sim and probably for other reasons.
-    public int getSubId(int phoneId) {
-        int[] subIds = getSubIds(phoneId);
-        if (subIds == null || subIds.length == 0) {
-            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        }
-        return subIds[0];
-    }
-
-    /** Must be public for access from instrumentation tests. */
-    @VisibleForTesting
-    public List<SubscriptionInfo> getSubInfoUsingSlotIndexPrivileged(int slotIndex) {
-        if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]+ slotIndex:" + slotIndex);
-        if (slotIndex == SubscriptionManager.DEFAULT_SIM_SLOT_INDEX) {
-            slotIndex = getSlotIndex(getDefaultSubId());
-        }
-        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
-            if (DBG) logd("[getSubInfoUsingSlotIndexPrivileged]- invalid slotIndex");
-            return null;
-        }
-
-        Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
-                null, SubscriptionManager.SIM_SLOT_INDEX + "=?",
-                new String[]{String.valueOf(slotIndex)}, null);
-        ArrayList<SubscriptionInfo> subList = null;
-        try {
-            if (cursor != null) {
-                while (cursor.moveToNext()) {
-                    SubscriptionInfo subInfo = getSubInfoRecord(cursor);
-                    if (subInfo != null) {
-                        if (subList == null) {
-                            subList = new ArrayList<SubscriptionInfo>();
-                        }
-                        subList.add(subInfo);
-                    }
-                }
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-        if (DBG) logd("[getSubInfoUsingSlotIndex]- null info return");
-
-        return subList;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void validateSubId(int subId) {
-        if (DBG) logd("validateSubId subId: " + subId);
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            throw new IllegalArgumentException("Invalid sub id passed as parameter");
-        } else if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            throw new IllegalArgumentException("Default sub id passed as parameter");
-        }
-    }
-
-    private synchronized ArrayList<Integer> getActiveSubIdArrayList() {
-        // Clone the sub id list so it can't change out from under us while iterating
-        List<Entry<Integer, ArrayList<Integer>>> simInfoList =
-                new ArrayList<>(mSlotIndexToSubIds.entrySet());
-
-        // Put the set of sub ids in slot index order
-        Collections.sort(simInfoList, (x, y) -> x.getKey().compareTo(y.getKey()));
-
-        // Collect the sub ids for each slot in turn
-        ArrayList<Integer> allSubs = new ArrayList<>();
-        for (Entry<Integer, ArrayList<Integer>> slot : simInfoList) {
-            allSubs.addAll(slot.getValue());
-        }
-        return allSubs;
-    }
-
-    private boolean isSubscriptionVisible(int subId) {
-        synchronized (mSubInfoListLock) {
-            for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) {
-                if (info.getSubscriptionId() == subId) {
-                    // If group UUID is null, it's stand alone opportunistic profile. So it's
-                    // visible. Otherwise, it's bundled opportunistic profile, and is not visible.
-                    return info.getGroupUuid() == null;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * @return the list of subId's that are active, is never null but the length maybe 0.
-     */
-    @Override
-    public int[] getActiveSubIdList(boolean visibleOnly) {
-        enforceReadPrivilegedPhoneState("getActiveSubIdList");
-
-        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);
-        }
-    }
-
-    @Override
-    public boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
-                callingFeatureId, "isActiveSubId")) {
-            throw new SecurityException("Requires READ_PHONE_STATE permission.");
-        }
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            return isActiveSubId(subId);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @Deprecated // This should be moved into isActiveSubId(int, String)
-    public boolean isActiveSubId(int subId) {
-        boolean retVal = SubscriptionManager.isValidSubscriptionId(subId)
-                && getActiveSubIdArrayList().contains(subId);
-
-        if (VDBG) logdl("[isActiveSubId]- " + retVal);
-        return retVal;
-    }
-
-    /**
-     * Store properties associated with SubscriptionInfo in database
-     * @param subId Subscription Id of Subscription
-     * @param propKey Column name in database associated with SubscriptionInfo
-     * @param propValue Value to store in DB for particular subId & column name
-     *
-     * @return number of rows updated.
-     * @hide
-     */
-    @Override
-    public int setSubscriptionProperty(int subId, String propKey, String propValue) {
-        enforceModifyPhoneState("setSubscriptionProperty");
-        final long token = Binder.clearCallingIdentity();
-
-        try {
-            validateSubId(subId);
-            ContentResolver resolver = mContext.getContentResolver();
-            int result = setSubscriptionPropertyIntoContentResolver(
-                    subId, propKey, propValue, resolver);
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            return result;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    private int setSubscriptionPropertyIntoContentResolver(
-            int subId, String propKey, String propValue, ContentResolver resolver) {
-        ContentValues value = new ContentValues();
-        boolean updateEntireGroup = GROUP_SHARING_PROPERTIES.contains(propKey);
-        switch (propKey) {
-            case SubscriptionManager.CB_EXTREME_THREAT_ALERT:
-            case SubscriptionManager.CB_SEVERE_THREAT_ALERT:
-            case SubscriptionManager.CB_AMBER_ALERT:
-            case SubscriptionManager.CB_EMERGENCY_ALERT:
-            case SubscriptionManager.CB_ALERT_SOUND_DURATION:
-            case SubscriptionManager.CB_ALERT_REMINDER_INTERVAL:
-            case SubscriptionManager.CB_ALERT_VIBRATE:
-            case SubscriptionManager.CB_ALERT_SPEECH:
-            case SubscriptionManager.CB_ETWS_TEST_ALERT:
-            case SubscriptionManager.CB_CHANNEL_50_ALERT:
-            case SubscriptionManager.CB_CMAS_TEST_ALERT:
-            case SubscriptionManager.CB_OPT_OUT_DIALOG:
-            case SubscriptionManager.ENHANCED_4G_MODE_ENABLED:
-            case SubscriptionManager.IS_OPPORTUNISTIC:
-            case SubscriptionManager.VT_IMS_ENABLED:
-            case SubscriptionManager.WFC_IMS_ENABLED:
-            case SubscriptionManager.WFC_IMS_MODE:
-            case SubscriptionManager.WFC_IMS_ROAMING_MODE:
-            case SubscriptionManager.WFC_IMS_ROAMING_ENABLED:
-            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:
-            case SubscriptionManager.USER_HANDLE:
-            case SubscriptionManager.SATELLITE_ENABLED:
-                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:
-                if (DBG) logd("Invalid column name");
-                break;
-        }
-
-        return updateDatabase(value, subId, updateEntireGroup);
-    }
-
-    /**
-     * Get properties associated with SubscriptionInfo from database
-     *
-     * @param subId Subscription Id of Subscription
-     * @param propKey Column name in SubscriptionInfo database
-     * @return Value associated with subId and propKey column in database
-     */
-    @Override
-    public String getSubscriptionProperty(int subId, String propKey, String callingPackage,
-            String callingFeatureId) {
-        switch (propKey) {
-            case SubscriptionManager.GROUP_UUID:
-                if (mContext.checkCallingOrSelfPermission(
-                        Manifest.permission.READ_PRIVILEGED_PHONE_STATE) != PERMISSION_GRANTED) {
-                    EventLog.writeEvent(0x534e4554, "213457638", Binder.getCallingUid());
-                    return null;
-                }
-                break;
-            default:
-                if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
-                        callingPackage, callingFeatureId, "getSubscriptionProperty")) {
-                    return null;
-                }
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            return getSubscriptionProperty(subId, propKey);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Get properties associated with SubscriptionInfo from database. Note this is the version
-     * without permission check for telephony internal use only.
-     *
-     * @param subId Subscription Id of Subscription
-     * @param propKey Column name in SubscriptionInfo database
-     * @return Value associated with subId and propKey column in database
-     */
-    public String getSubscriptionProperty(int subId, String propKey) {
-        String resultValue = null;
-        try (Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
-                new String[]{propKey},
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
-                new String[]{subId + ""}, null)) {
-            if (cursor != null) {
-                if (cursor.moveToFirst()) {
-                    switch (propKey) {
-                        case SubscriptionManager.CB_EXTREME_THREAT_ALERT:
-                        case SubscriptionManager.CB_SEVERE_THREAT_ALERT:
-                        case SubscriptionManager.CB_AMBER_ALERT:
-                        case SubscriptionManager.CB_EMERGENCY_ALERT:
-                        case SubscriptionManager.CB_ALERT_SOUND_DURATION:
-                        case SubscriptionManager.CB_ALERT_REMINDER_INTERVAL:
-                        case SubscriptionManager.CB_ALERT_VIBRATE:
-                        case SubscriptionManager.CB_ALERT_SPEECH:
-                        case SubscriptionManager.CB_ETWS_TEST_ALERT:
-                        case SubscriptionManager.CB_CHANNEL_50_ALERT:
-                        case SubscriptionManager.CB_CMAS_TEST_ALERT:
-                        case SubscriptionManager.CB_OPT_OUT_DIALOG:
-                        case SubscriptionManager.ENHANCED_4G_MODE_ENABLED:
-                        case SubscriptionManager.VT_IMS_ENABLED:
-                        case SubscriptionManager.WFC_IMS_ENABLED:
-                        case SubscriptionManager.WFC_IMS_MODE:
-                        case SubscriptionManager.WFC_IMS_ROAMING_MODE:
-                        case SubscriptionManager.WFC_IMS_ROAMING_ENABLED:
-                        case SubscriptionManager.IMS_RCS_UCE_ENABLED:
-                        case SubscriptionManager.CROSS_SIM_CALLING_ENABLED:
-                        case SubscriptionManager.IS_OPPORTUNISTIC:
-                        case SubscriptionManager.GROUP_UUID:
-                        case SubscriptionManager.ENABLED_MOBILE_DATA_POLICIES:
-                        case SubscriptionManager.ALLOWED_NETWORK_TYPES:
-                        case SubscriptionManager.D2D_STATUS_SHARING:
-                        case SubscriptionManager.VOIMS_OPT_IN_STATUS:
-                        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:
-                        case SubscriptionManager.USER_HANDLE:
-                        case SubscriptionManager.SATELLITE_ENABLED:
-                            resultValue = cursor.getString(0);
-                            break;
-                        default:
-                            if(DBG) logd("Invalid column name");
-                            break;
-                    }
-                } else {
-                    if(DBG) logd("Valid row not present in db");
-                }
-            } else {
-                if(DBG) logd("Query failed");
-            }
-        }
-
-        if (DBG) logd("getSubscriptionProperty Query value = " + resultValue);
-        return resultValue;
-    }
-
-    private void printStackTrace(String msg) {
-        RuntimeException re = new RuntimeException();
-        logd("StackTrace - " + msg);
-        StackTraceElement[] st = re.getStackTrace();
-        boolean first = true;
-        for (StackTraceElement ste : st) {
-            if (first) {
-                first = false;
-            } else {
-                logd(ste.toString());
-            }
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
-                "Requires DUMP");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            pw.println("SubscriptionController:");
-            pw.println(" mLastISubServiceRegTime=" + mLastISubServiceRegTime);
-            pw.println(" defaultSubId=" + getDefaultSubId());
-            pw.println(" defaultDataSubId=" + getDefaultDataSubId());
-            pw.println(" defaultVoiceSubId=" + getDefaultVoiceSubId());
-            pw.println(" defaultSmsSubId=" + getDefaultSmsSubId());
-            pw.println(" defaultVoicePhoneId=" + SubscriptionManager.getDefaultVoicePhoneId());
-            pw.flush();
-
-            for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
-                pw.println(" sSlotIndexToSubId[" + entry.getKey() + "]: subIds=" + entry);
-            }
-            pw.flush();
-            pw.println("++++++++++++++++++++++++++++++++");
-
-            List<SubscriptionInfo> sirl = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (sirl != null) {
-                pw.println(" ActiveSubInfoList:");
-                for (SubscriptionInfo entry : sirl) {
-                    pw.println("  " + entry.toString());
-                }
-            } else {
-                pw.println(" ActiveSubInfoList: is null");
-            }
-            pw.flush();
-            pw.println("++++++++++++++++++++++++++++++++");
-
-            sirl = getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (sirl != null) {
-                pw.println(" AllSubInfoList:");
-                for (SubscriptionInfo entry : sirl) {
-                    pw.println("  " + entry.toString());
-                }
-            } else {
-                pw.println(" AllSubInfoList: is null");
-            }
-            pw.flush();
-            pw.println("++++++++++++++++++++++++++++++++");
-
-            mLocalLog.dump(fd, pw, args);
-            pw.flush();
-            pw.println("++++++++++++++++++++++++++++++++");
-            pw.flush();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Migrating Ims settings from global setting to subscription DB, if not already done.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void migrateImsSettings() {
-        migrateImsSettingHelper(
-                Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                SubscriptionManager.ENHANCED_4G_MODE_ENABLED);
-        migrateImsSettingHelper(
-                Settings.Global.VT_IMS_ENABLED,
-                SubscriptionManager.VT_IMS_ENABLED);
-        migrateImsSettingHelper(
-                Settings.Global.WFC_IMS_ENABLED,
-                SubscriptionManager.WFC_IMS_ENABLED);
-        migrateImsSettingHelper(
-                Settings.Global.WFC_IMS_MODE,
-                SubscriptionManager.WFC_IMS_MODE);
-        migrateImsSettingHelper(
-                Settings.Global.WFC_IMS_ROAMING_MODE,
-                SubscriptionManager.WFC_IMS_ROAMING_MODE);
-        migrateImsSettingHelper(
-                Settings.Global.WFC_IMS_ROAMING_ENABLED,
-                SubscriptionManager.WFC_IMS_ROAMING_ENABLED);
-    }
-
-    private void migrateImsSettingHelper(String settingGlobal, String subscriptionProperty) {
-        ContentResolver resolver = mContext.getContentResolver();
-        int defaultSubId = getDefaultVoiceSubId();
-        if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-        try {
-            int prevSetting = Settings.Global.getInt(resolver, settingGlobal);
-
-            if (prevSetting != DEPRECATED_SETTING) {
-                // Write previous setting into Subscription DB.
-                setSubscriptionPropertyIntoContentResolver(defaultSubId, subscriptionProperty,
-                        Integer.toString(prevSetting), resolver);
-                // Write global setting value with DEPRECATED_SETTING making sure
-                // migration only happen once.
-                Settings.Global.putInt(resolver, settingGlobal, DEPRECATED_SETTING);
-            }
-        } catch (Settings.SettingNotFoundException e) {
-        }
-    }
-
-    /**
-     * Set whether a subscription is opportunistic.
-     *
-     * Throws SecurityException if doesn't have required permission.
-     *
-     * @param opportunistic whether it’s opportunistic subscription.
-     * @param subId the unique SubscriptionInfo index in database
-     * @param callingPackage The package making the IPC.
-     * @return the number of records updated
-     */
-    @Override
-    public int setOpportunistic(boolean opportunistic, int subId, String callingPackage) {
-        try {
-            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                    mContext, subId, callingPackage);
-        } catch (SecurityException e) {
-            // The subscription may be inactive eSIM profile. If so, check the access rule in
-            // database.
-            enforceCarrierPrivilegeOnInactiveSub(subId, callingPackage,
-                    "Caller requires permission on sub " + subId);
-        }
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            int ret = setSubscriptionProperty(subId, SubscriptionManager.IS_OPPORTUNISTIC,
-                    String.valueOf(opportunistic ? 1 : 0));
-            if (ret != 0) notifySubscriptionInfoChanged();
-            return ret;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Get subscription info from database, and check whether caller has carrier privilege
-     * permission with it. If checking fails, throws SecurityException.
-     */
-    private void enforceCarrierPrivilegeOnInactiveSub(int subId, String callingPackage,
-            String message) {
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-
-        SubscriptionManager subManager = (SubscriptionManager)
-                mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-
-        List<SubscriptionInfo> subInfo;
-        long token = Binder.clearCallingIdentity();
-        try {
-            subInfo = getSubInfo(
-                    SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        try {
-            if (!isActiveSubId(subId) && subInfo != null && subInfo.size() == 1
-                    && subManager.canManageSubscription(subInfo.get(0), callingPackage)) {
-                return;
-            }
-            throw new SecurityException(message);
-        } catch (IllegalArgumentException e) {
-            // canManageSubscription will throw IllegalArgumentException if sub is not embedded
-            // or package name is unknown. In this case, we also see it as permission check failure
-            // and throw a SecurityException.
-            throw new SecurityException(message);
-        }
-    }
-
-    @Override
-    public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
-            ISetOpportunisticDataCallback callback) {
-        enforceModifyPhoneState("setPreferredDataSubscriptionId");
-        final long token = Binder.clearCallingIdentity();
-
-        try {
-            PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
-            if (phoneSwitcher == null) {
-                logd("Set preferred data sub: phoneSwitcher is null.");
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString("a73fe57f-4178-4bc3-a7ae-9d7354939274"),
-                        "Set preferred data sub: phoneSwitcher is null.");
-                if (callback != null) {
-                    try {
-                        callback.onComplete(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION);
-                    } catch (RemoteException exception) {
-                        logd("RemoteException " + exception);
-                    }
-                }
-                return;
-            }
-
-            phoneSwitcher.trySetOpportunisticDataSubscription(subId, needValidation, callback);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public int getPreferredDataSubscriptionId() {
-        enforceReadPrivilegedPhoneState("getPreferredDataSubscriptionId");
-        final long token = Binder.clearCallingIdentity();
-
-        try {
-            PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
-            if (phoneSwitcher == null) {
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString("e72747ab-d0aa-4b0e-9dd5-cb99365c6d58"),
-                        "Get preferred data sub: phoneSwitcher is null.");
-                return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-            }
-
-            return phoneSwitcher.getAutoSelectedDataSubId();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage,
-            String callingFeatureId) {
-        return getSubscriptionInfoListFromCacheHelper(callingPackage, callingFeatureId,
-                makeCacheListCopyWithLock(mCacheOpportunisticSubInfoList));
-    }
-
-    /**
-     * Inform SubscriptionManager that subscriptions in the list are bundled
-     * as a group. Typically it's a primary subscription and an opportunistic
-     * subscription. It should only affect multi-SIM scenarios where primary
-     * and opportunistic subscriptions can be activated together.
-     * Being in the same group means they might be activated or deactivated
-     * together, some of them may be invisible to the users, etc.
-     *
-     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
-     * permission or had carrier privilege permission on the subscriptions:
-     * {@link TelephonyManager#hasCarrierPrivileges(int)} or
-     * {@link SubscriptionManager#canManageSubscription(SubscriptionInfo)}
-     *
-     * @throws SecurityException if the caller doesn't meet the requirements
-     *             outlined above.
-     * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist.
-     *
-     * @param subIdList list of subId that will be in the same group
-     * @return groupUUID a UUID assigned to the subscription group. It returns
-     * null if fails.
-     *
-     */
-    @Override
-    public ParcelUuid createSubscriptionGroup(int[] subIdList, String callingPackage) {
-        if (subIdList == null || subIdList.length == 0) {
-            throw new IllegalArgumentException("Invalid subIdList " + Arrays.toString(subIdList));
-        }
-
-        // Makes sure calling package matches caller UID.
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        // If it doesn't have modify phone state permission, or carrier privilege permission,
-        // a SecurityException will be thrown.
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-                != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList(
-                        subIdList, callingPackage)) {
-            throw new SecurityException("CreateSubscriptionGroup needs MODIFY_PHONE_STATE or"
-                    + " carrier privilege permission on all specified subscriptions");
-        }
-
-        long identity = Binder.clearCallingIdentity();
-
-        try {
-            // Generate a UUID.
-            ParcelUuid groupUUID = new ParcelUuid(UUID.randomUUID());
-
-            ContentValues value = new ContentValues();
-            value.put(SubscriptionManager.GROUP_UUID, groupUUID.toString());
-            value.put(SubscriptionManager.GROUP_OWNER, callingPackage);
-            int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
-                    value, getSelectionForSubIdList(subIdList), null);
-
-            if (DBG) logdl("createSubscriptionGroup update DB result: " + result);
-
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifySubscriptionInfoChanged();
-
-            MultiSimSettingController.getInstance().notifySubscriptionGroupChanged(groupUUID);
-
-            return groupUUID;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    private String getOwnerPackageOfSubGroup(ParcelUuid groupUuid) {
-        if (groupUuid == null) return null;
-
-        List<SubscriptionInfo> infoList = getSubInfo(SubscriptionManager.GROUP_UUID
-                + "=\'" + groupUuid.toString() + "\'", null);
-
-        return ArrayUtils.isEmpty(infoList) ? null : infoList.get(0).getGroupOwner();
-    }
-
-    /**
-     * @param groupUuid a UUID assigned to the subscription group.
-     * @param callingPackage the package making the IPC.
-     * @return if callingPackage has carrier privilege on sublist.
-     *
-     */
-    public boolean canPackageManageGroup(ParcelUuid groupUuid, String callingPackage) {
-        if (groupUuid == null) {
-            throw new IllegalArgumentException("Invalid groupUuid");
-        }
-
-        if (TextUtils.isEmpty(callingPackage)) {
-            throw new IllegalArgumentException("Empty callingPackage");
-        }
-
-        List<SubscriptionInfo> infoList;
-
-        // Getting all subscriptions in the group.
-        long identity = Binder.clearCallingIdentity();
-        try {
-            infoList = getSubInfo(SubscriptionManager.GROUP_UUID
-                    + "=\'" + groupUuid.toString() + "\'", null);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        // If the group does not exist, then by default the UUID is up for grabs so no need to
-        // restrict management of a group (that someone may be attempting to create).
-        if (ArrayUtils.isEmpty(infoList)) {
-            return true;
-        }
-
-        // If the calling package is the group owner, skip carrier permission check and return
-        // true as it was done before.
-        if (callingPackage.equals(infoList.get(0).getGroupOwner())) return true;
-
-        // Check carrier privilege for all subscriptions in the group.
-        int[] subIdArray = infoList.stream().mapToInt(info -> info.getSubscriptionId())
-                .toArray();
-        return (checkCarrierPrivilegeOnSubList(subIdArray, callingPackage));
-    }
-
-    private int updateGroupOwner(ParcelUuid groupUuid, String groupOwner) {
-        // If the existing group owner is different from current caller, make caller the new
-        // owner of all subscriptions in group.
-        // This is for use-case of:
-        // 1) Both package1 and package2 has permission (MODIFY_PHONE_STATE or carrier
-        // privilege permission) of all related subscriptions.
-        // 2) Package 1 created a group.
-        // 3) Package 2 wants to add a subscription into it.
-        // Step 3 should be granted as all operations are permission based. Which means as
-        // long as the package passes the permission check, it can modify the subscription
-        // and the group. And package 2 becomes the new group owner as it's the last to pass
-        // permission checks on all members.
-        ContentValues value = new ContentValues(1);
-        value.put(SubscriptionManager.GROUP_OWNER, groupOwner);
-        return mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
-                value, SubscriptionManager.GROUP_UUID + "=\"" + groupUuid + "\"", null);
-    }
-
-    @Override
-    public void addSubscriptionsIntoGroup(int[] subIdList, ParcelUuid groupUuid,
-            String callingPackage) {
-        if (subIdList == null || subIdList.length == 0) {
-            throw new IllegalArgumentException("Invalid subId list");
-        }
-
-        if (groupUuid == null || groupUuid.equals(INVALID_GROUP_UUID)) {
-            throw new IllegalArgumentException("Invalid groupUuid");
-        }
-
-        // Makes sure calling package matches caller UID.
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        // If it doesn't have modify phone state permission, or carrier privilege permission,
-        // a SecurityException will be thrown.
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-                != PERMISSION_GRANTED && !(checkCarrierPrivilegeOnSubList(subIdList, callingPackage)
-                && canPackageManageGroup(groupUuid, callingPackage))) {
-            throw new SecurityException("Requires MODIFY_PHONE_STATE or carrier privilege"
-                    + " permissions on subscriptions and the group.");
-        }
-
-        long identity = Binder.clearCallingIdentity();
-
-        try {
-            if (DBG) {
-                logdl("addSubscriptionsIntoGroup sub list "
-                        + Arrays.toString(subIdList) + " into group " + groupUuid);
-            }
-
-            ContentValues value = new ContentValues();
-            value.put(SubscriptionManager.GROUP_UUID, groupUuid.toString());
-            int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
-                    value, getSelectionForSubIdList(subIdList), null);
-
-            if (DBG) logdl("addSubscriptionsIntoGroup update DB result: " + result);
-
-            if (result > 0) {
-                updateGroupOwner(groupUuid, callingPackage);
-                refreshCachedActiveSubscriptionInfoList();
-                notifySubscriptionInfoChanged();
-                MultiSimSettingController.getInstance().notifySubscriptionGroupChanged(groupUuid);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Remove a list of subscriptions from their subscription group.
-     * See {@link SubscriptionManager#createSubscriptionGroup(List<Integer>)} for more details.
-     *
-     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
-     * permission or had carrier privilege permission on the subscriptions:
-     * {@link TelephonyManager#hasCarrierPrivileges()} or
-     * {@link SubscriptionManager#canManageSubscription(SubscriptionInfo)}
-     *
-     * @throws SecurityException if the caller doesn't meet the requirements
-     *             outlined above.
-     * @throws IllegalArgumentException if the some subscriptions in the list doesn't belong
-     *             the specified group.
-     *
-     * @param subIdList list of subId that need removing from their groups.
-     *
-     */
-    public void removeSubscriptionsFromGroup(int[] subIdList, ParcelUuid groupUuid,
-            String callingPackage) {
-        if (subIdList == null || subIdList.length == 0) {
-            return;
-        }
-
-        // Makes sure calling package matches caller UID.
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        // If it doesn't have modify phone state permission, or carrier privilege permission,
-        // a SecurityException will be thrown. If it's due to invalid parameter or internal state,
-        // it will return null.
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-                != PERMISSION_GRANTED && !(checkCarrierPrivilegeOnSubList(subIdList, callingPackage)
-                && canPackageManageGroup(groupUuid, callingPackage))) {
-            throw new SecurityException("removeSubscriptionsFromGroup needs MODIFY_PHONE_STATE or"
-                    + " carrier privilege permission on all specified subscriptions");
-        }
-
-        long identity = Binder.clearCallingIdentity();
-
-        try {
-            List<SubscriptionInfo> subInfoList = getSubInfo(getSelectionForSubIdList(subIdList),
-                    null);
-            for (SubscriptionInfo info : subInfoList) {
-                if (!groupUuid.equals(info.getGroupUuid())) {
-                    throw new IllegalArgumentException("Subscription " + info.getSubscriptionId()
-                        + " doesn't belong to group " + groupUuid);
-                }
-            }
-            ContentValues value = new ContentValues();
-            value.put(SubscriptionManager.GROUP_UUID, (String) null);
-            value.put(SubscriptionManager.GROUP_OWNER, (String) null);
-            int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
-                    value, getSelectionForSubIdList(subIdList), null);
-
-            if (DBG) logdl("removeSubscriptionsFromGroup update DB result: " + result);
-
-            if (result > 0) {
-                updateGroupOwner(groupUuid, callingPackage);
-                refreshCachedActiveSubscriptionInfoList();
-                notifySubscriptionInfoChanged();
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     *  Helper function to check if the caller has carrier privilege permissions on a list of subId.
-     *  The check can either be processed against access rules on currently active SIM cards, or
-     *  the access rules we keep in our database for currently inactive eSIMs.
-     *
-     * @throws IllegalArgumentException if the some subId is invalid or doesn't exist.
-     *
-     *  @return true if checking passes on all subId, false otherwise.
-     */
-    private boolean checkCarrierPrivilegeOnSubList(int[] subIdList, String callingPackage) {
-        // Check carrier privilege permission on active subscriptions first.
-        // If it fails, they could be inactive. So keep them in a HashSet and later check
-        // access rules in our database.
-        Set<Integer> checkSubList = new HashSet<>();
-        for (int subId : subIdList) {
-            if (isActiveSubId(subId)) {
-                if (!mTelephonyManager.hasCarrierPrivileges(subId)) {
-                    return false;
-                }
-            } else {
-                checkSubList.add(subId);
-            }
-        }
-
-        if (checkSubList.isEmpty()) {
-            return true;
-        }
-
-        long identity = Binder.clearCallingIdentity();
-
-        try {
-            // Check access rules for each sub info.
-            SubscriptionManager subscriptionManager = (SubscriptionManager)
-                    mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-            List<SubscriptionInfo> subInfoList = getSubInfo(
-                    getSelectionForSubIdList(subIdList), null);
-
-            // Didn't find all the subscriptions specified in subIdList.
-            if (subInfoList == null || subInfoList.size() != subIdList.length) {
-                throw new IllegalArgumentException("Invalid subInfoList.");
-            }
-
-            for (SubscriptionInfo subInfo : subInfoList) {
-                if (checkSubList.contains(subInfo.getSubscriptionId())) {
-                    if (subInfo.isEmbedded() && subscriptionManager.canManageSubscription(
-                            subInfo, callingPackage)) {
-                        checkSubList.remove(subInfo.getSubscriptionId());
-                    } else {
-                        return false;
-                    }
-                }
-            }
-
-            return checkSubList.isEmpty();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Helper function to create selection argument of a list of subId.
-     * The result should be: "in (subId1, subId2, ...)".
-     */
-    public static String getSelectionForSubIdList(int[] subId) {
-        StringBuilder selection = new StringBuilder();
-        selection.append(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID);
-        selection.append(" IN (");
-        for (int i = 0; i < subId.length - 1; i++) {
-            selection.append(subId[i] + ", ");
-        }
-        selection.append(subId[subId.length - 1]);
-        selection.append(")");
-
-        return selection.toString();
-    }
-
-    /**
-     * Helper function to create selection argument of a list of subId.
-     * The result should be: "in (iccId1, iccId2, ...)".
-     */
-    private String getSelectionForIccIdList(String[] iccIds) {
-        StringBuilder selection = new StringBuilder();
-        selection.append(SubscriptionManager.ICC_ID);
-        selection.append(" IN (");
-        for (int i = 0; i < iccIds.length - 1; i++) {
-            selection.append("'" + iccIds[i] + "', ");
-        }
-        selection.append("'" + iccIds[iccIds.length - 1] + "'");
-        selection.append(")");
-
-        return selection.toString();
-    }
-
-    /**
-     * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
-     * See {@link #createSubscriptionGroup(int[], String)} for more details.
-     *
-     * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE}
-     * or carrier privilege permission on the subscription.
-     * {@link TelephonyManager#hasCarrierPrivileges(int)}
-     *
-     * <p>Starting with API level 33, the caller needs READ_PHONE_STATE and access to device
-     * identifiers to get the list of subscriptions associated with a group UUID.
-     * This method can be invoked if one of the following requirements is met:
-     * <ul>
-     *     <li>If the app has carrier privilege permission.
-     *     {@link TelephonyManager#hasCarrierPrivileges()}
-     *     <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} and
-     *     access to device identifiers.
-     * </ul>
-     *
-     * @throws SecurityException if the caller doesn't meet the requirements
-     *             outlined above.
-     *
-     * @param groupUuid of which list of subInfo will be returned.
-     * @return list of subscriptionInfo that belong to the same group, including the given
-     * subscription itself. It will return an empty list if no subscription belongs to the group.
-     *
-     */
-    @Override
-    public List<SubscriptionInfo> getSubscriptionsInGroup(ParcelUuid groupUuid,
-            String callingPackage, String callingFeatureId) {
-        long identity = Binder.clearCallingIdentity();
-        List<SubscriptionInfo> subInfoList;
-
-        try {
-            // need to bypass removing identifier check because that will remove the subList without
-            // group id.
-            subInfoList = getAllSubInfoList(mContext.getOpPackageName(),
-                    mContext.getAttributionTag(), true);
-            if (groupUuid == null || subInfoList == null || subInfoList.isEmpty()) {
-                return new ArrayList<>();
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        // If the calling app neither has carrier privileges nor READ_PHONE_STATE and access to
-        // device identifiers, it will return an empty list.
-        if (CompatChanges.isChangeEnabled(
-                REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID, Binder.getCallingUid())) {
-            try {
-                if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
-                        callingPackage, callingFeatureId, "getSubscriptionsInGroup")) {
-                    EventLog.writeEvent(0x534e4554, "213902861", Binder.getCallingUid());
-                    return new ArrayList<>();
-                }
-            } catch (SecurityException e) {
-                EventLog.writeEvent(0x534e4554, "213902861", Binder.getCallingUid());
-                return new ArrayList<>();
-            }
-        }
-        return subInfoList.stream().filter(info -> {
-            if (!groupUuid.equals(info.getGroupUuid())) return false;
-            int subId = info.getSubscriptionId();
-            return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
-                    callingPackage, callingFeatureId, "getSubscriptionsInGroup")
-                    || info.canManageSubscription(mContext, callingPackage);
-        }).map(subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo,
-                callingPackage, callingFeatureId, "getSubscriptionsInGroup"))
-        .collect(Collectors.toList());
-
-    }
-
-    /**
-     * Check if the passed in phoneId has a sub that belongs to the same group as the sub
-     * corresponding to the passed in iccid.
-     * @param phoneId phone id to check
-     * @param iccid ICCID to check
-     * @return true if sub/group is the same, false otherwise
-     */
-    public boolean checkPhoneIdAndIccIdMatch(int phoneId, String iccid) {
-        int subId = getSubId(phoneId);
-        if (!SubscriptionManager.isUsableSubIdValue(subId)) return false;
-        ParcelUuid groupUuid = getGroupUuid(subId);
-        List<SubscriptionInfo> subInfoList;
-        if (groupUuid != null) {
-            subInfoList = getSubInfo(SubscriptionManager.GROUP_UUID
-                    + "=\'" + groupUuid.toString() + "\'", null);
-        } else {
-            subInfoList = getSubInfo(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID
-                    + "=" + subId, null);
-        }
-        return subInfoList != null && subInfoList.stream().anyMatch(
-                subInfo -> IccUtils.stripTrailingFs(subInfo.getIccId()).equals(
-                IccUtils.stripTrailingFs(iccid)));
-    }
-
-    public ParcelUuid getGroupUuid(int subId) {
-        ParcelUuid groupUuid;
-        List<SubscriptionInfo> subInfo = getSubInfo(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID
-                        + "=" + subId, null);
-        if (subInfo == null || subInfo.size() == 0) {
-            groupUuid = null;
-        } else {
-            groupUuid = subInfo.get(0).getGroupUuid();
-        }
-
-        return groupUuid;
-    }
-
-
-    /**
-     * Enable/Disable a subscription
-     * @param enable true if enabling, false if disabling
-     * @param subId the unique SubInfoRecord index in database
-     *
-     * @return true if success, false if fails or the further action is
-     * needed hence it's redirected to Euicc.
-     */
-    @Override
-    public boolean setSubscriptionEnabled(boolean enable, int subId) {
-        enforceModifyPhoneState("setSubscriptionEnabled");
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            logd("setSubscriptionEnabled" + (enable ? " enable " : " disable ")
-                    + " subId " + subId);
-
-            // Error checking.
-            if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
-                throw new IllegalArgumentException(
-                        "setSubscriptionEnabled not usable subId " + subId);
-            }
-
-            // Nothing to do if it's already active or inactive.
-            if (enable == isActiveSubscriptionId(subId)) return true;
-
-            SubscriptionInfo info = SubscriptionController.getInstance()
-                    .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag())
-                    .stream()
-                    .filter(subInfo -> subInfo.getSubscriptionId() == subId)
-                    .findFirst()
-                    .get();
-
-            if (info == null) {
-                logd("setSubscriptionEnabled subId " + subId + " doesn't exist.");
-                return false;
-            }
-
-            // TODO: make sure after slot mapping, we enable the uicc applications for the
-            // subscription we are enabling.
-            if (info.isEmbedded()) {
-                return enableEmbeddedSubscription(info, enable);
-            } else {
-                return enablePhysicalSubscription(info, enable);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    private boolean enableEmbeddedSubscription(SubscriptionInfo info, boolean enable) {
-        // We need to send intents to Euicc for operations:
-
-        // 1) In single SIM mode, turning on a eSIM subscription while pSIM is the active slot.
-        //    Euicc will ask user to switch to DSDS if supported or to confirm SIM slot
-        //    switching.
-        // 2) In DSDS mode, turning on / off an eSIM profile. Euicc can ask user whether
-        //    to turn on DSDS, or whether to switch from current active eSIM profile to it, or
-        //    to simply show a progress dialog.
-        // 3) In future, similar operations on triple SIM devices.
-        enableSubscriptionOverEuiccManager(info.getSubscriptionId(), enable,
-                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        // returning false to indicate state is not changed. If changed, a subscriptionInfo
-        // change will be filed separately.
-        return false;
-
-        // TODO: uncomment or clean up if we decide whether to support standalone CBRS for Q.
-        // subId = enable ? subId : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        // updateEnabledSubscriptionGlobalSetting(subId, physicalSlotIndex);
-    }
-
-    private boolean enablePhysicalSubscription(SubscriptionInfo info, boolean enable) {
-        if (info == null || !SubscriptionManager.isValidSubscriptionId(info.getSubscriptionId())) {
-            return false;
-        }
-
-        int subId = info.getSubscriptionId();
-
-        UiccSlotInfo slotInfo = null;
-        int physicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-        UiccSlotInfo[] slotsInfo = mTelephonyManager.getUiccSlotsInfo();
-        if (slotsInfo == null) return false;
-        for (int i = 0; i < slotsInfo.length; i++) {
-            UiccSlotInfo curSlotInfo = slotsInfo[i];
-            if (curSlotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT) {
-                if (TextUtils.equals(IccUtils.stripTrailingFs(curSlotInfo.getCardId()),
-                        IccUtils.stripTrailingFs(info.getCardString()))) {
-                    slotInfo = curSlotInfo;
-                    physicalSlotIndex = i;
-                    break;
-                }
-            }
-        }
-
-        // Can't find the existing SIM.
-        if (slotInfo == null) {
-            loge("Can't find the existing SIM.");
-            return false;
-        }
-
-        // this for physical slot which has only one port
-        if (enable && !slotInfo.getPorts().stream().findFirst().get().isActive()) {
-            // 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.
-            EuiccManager euiccManager =
-                    (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE);
-            if (euiccManager != null && euiccManager.isEnabled()) {
-                enableSubscriptionOverEuiccManager(subId, enable, physicalSlotIndex);
-            } else {
-                // Enable / disable uicc applications.
-                if (!info.areUiccApplicationsEnabled()) setUiccApplicationsEnabled(enable, subId);
-                // If euiccManager is not enabled, we try to switch to DSDS if possible,
-                // or switch slot if not.
-                if (mTelephonyManager.isMultiSimSupported() == MULTISIM_ALLOWED) {
-                    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);
-                }
-            }
-            return true;
-        } else {
-            // Enable / disable uicc applications.
-            setUiccApplicationsEnabled(enable, subId);
-            return true;
-        }
-    }
-
-    private void enableSubscriptionOverEuiccManager(int subId, boolean enable,
-            int physicalSlotIndex) {
-        logdl("enableSubscriptionOverEuiccManager" + (enable ? " enable " : " disable ")
-                + "subId " + subId + " on slotIndex " + physicalSlotIndex);
-        Intent intent = new Intent(EuiccManager.ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(EuiccManager.EXTRA_SUBSCRIPTION_ID, subId);
-        intent.putExtra(EuiccManager.EXTRA_ENABLE_SUBSCRIPTION, enable);
-        if (physicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-            intent.putExtra(EuiccManager.EXTRA_PHYSICAL_SLOT_ID, physicalSlotIndex);
-        }
-        mContext.startActivity(intent);
-    }
-
-    private void updateEnabledSubscriptionGlobalSetting(int subId, int physicalSlotIndex) {
-        // Write the value which subscription is enabled into global setting.
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + physicalSlotIndex, subId);
-    }
-
-    private void updateModemStackEnabledGlobalSetting(boolean enabled, int physicalSlotIndex) {
-        // Write the whether a modem stack is disabled into global setting.
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.MODEM_STACK_ENABLED_FOR_SLOT
-                        + physicalSlotIndex, enabled ? 1 : 0);
-    }
-
-    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;
-                }
-            }
-        }
-
-        return physicalSlotIndex;
-    }
-
-    @Override
-    public boolean isSubscriptionEnabled(int subId) {
-        // TODO: b/123314365 support multi-eSIM and removable eSIM.
-        enforceReadPrivilegedPhoneState("isSubscriptionEnabled");
-
-        long identity = Binder.clearCallingIdentity();
-        try {
-            // Error checking.
-            if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
-                throw new IllegalArgumentException(
-                        "isSubscriptionEnabled not usable subId " + subId);
-            }
-
-            List<SubscriptionInfo> infoList = getSubInfo(
-                    SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null);
-            if (infoList == null || infoList.isEmpty()) {
-                // Subscription doesn't exist.
-                return false;
-            }
-
-            boolean isEmbedded = infoList.get(0).isEmbedded();
-
-            if (isEmbedded) {
-                return isActiveSubId(subId);
-            } else {
-                // For pSIM, we also need to check if modem is disabled or not.
-                return isActiveSubId(subId) && PhoneConfigurationManager.getInstance()
-                        .getPhoneStatus(PhoneFactory.getPhone(getPhoneId(subId)));
-            }
-
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public int getEnabledSubscriptionId(int logicalSlotIndex) {
-        // TODO: b/123314365 support multi-eSIM and removable eSIM.
-        enforceReadPrivilegedPhoneState("getEnabledSubscriptionId");
-
-        long identity = Binder.clearCallingIdentity();
-        try {
-            if (!SubscriptionManager.isValidPhoneId(logicalSlotIndex)) {
-                throw new IllegalArgumentException(
-                        "getEnabledSubscriptionId with invalid logicalSlotIndex "
-                                + logicalSlotIndex);
-            }
-
-            // Getting and validating the physicalSlotIndex.
-            int physicalSlotIndex = getPhysicalSlotIndexFromLogicalSlotIndex(logicalSlotIndex);
-            if (physicalSlotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-            }
-
-            // if modem stack is disabled, return INVALID_SUBSCRIPTION_ID without reading
-            // Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT.
-            int modemStackEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.MODEM_STACK_ENABLED_FOR_SLOT + physicalSlotIndex, 1);
-            if (modemStackEnabled != 1) {
-                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-            }
-
-            int subId;
-            try {
-                subId = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + physicalSlotIndex);
-            } catch (Settings.SettingNotFoundException e) {
-                // Value never set. Return whether it's currently active.
-                subId = getSubId(logicalSlotIndex);
-            }
-
-            return subId;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Helper function of getOpportunisticSubscriptions and getActiveSubscriptionInfoList.
-     * They are doing similar things except operating on different cache.
-     *
-     * NOTE: the cacheSubList passed in is a *copy* of mCacheActiveSubInfoList or
-     * mCacheOpportunisticSubInfoList, so mSubInfoListLock is not required to access it. Also, this
-     * method may modify cacheSubList depending on the permissions the caller has.
-     */
-    private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper(
-            String callingPackage, String callingFeatureId, List<SubscriptionInfo> cacheSubList) {
-        boolean canReadPhoneState = false;
-        boolean canReadIdentifiers = false;
-        boolean canReadPhoneNumber = false;
-        try {
-            canReadPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
-                    SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
-                    Binder.getCallingUid(), callingPackage, callingFeatureId,
-                    "getSubscriptionInfoList");
-            // If the calling package has the READ_PHONE_STATE permission then check if the caller
-            // also has access to subscriber identifiers and the phone number to ensure that the ICC
-            // ID and any other unique identifiers are removed if the caller should not have access.
-            if (canReadPhoneState) {
-                canReadIdentifiers = hasSubscriberIdentifierAccess(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                        callingFeatureId, "getSubscriptionInfoList", false);
-                canReadPhoneNumber = hasPhoneNumberAccess(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                        callingFeatureId, "getSubscriptionInfoList");
-            }
-        } catch (SecurityException e) {
-            // If a SecurityException is thrown during the READ_PHONE_STATE check then the only way
-            // to access a subscription is to have carrier privileges for its subId; an app with
-            // carrier privileges for a subscription is also granted access to all identifiers so
-            // the identifier and phone number access checks are not required.
-        }
-
-        if (canReadIdentifiers && canReadPhoneNumber) {
-            return cacheSubList;
-        }
-        // Filter the list to only include subscriptions which the caller can manage.
-        for (int subIndex = cacheSubList.size() - 1; subIndex >= 0; subIndex--) {
-            SubscriptionInfo subscriptionInfo = cacheSubList.get(subIndex);
-
-            int subId = subscriptionInfo.getSubscriptionId();
-            boolean hasCarrierPrivileges = TelephonyPermissions.checkCarrierPrivilegeForSubId(
-                    mContext, subId);
-            // If the caller has carrier privileges then they are granted access to all
-            // identifiers for their subscription.
-            if (hasCarrierPrivileges) continue;
-
-            cacheSubList.remove(subIndex);
-            if (canReadPhoneState) {
-                // The caller does not have carrier privileges for this subId, filter the
-                // identifiers in the subscription based on the results of the initial
-                // permission checks.
-                cacheSubList.add(subIndex, conditionallyRemoveIdentifiers(
-                        subscriptionInfo, canReadIdentifiers, canReadPhoneNumber));
-            }
-        }
-        return cacheSubList;
-    }
-
-    /**
-     * Conditionally removes identifiers from the provided {@code subInfo} if the {@code
-     * callingPackage} does not meet the access requirements for identifiers and returns the
-     * potentially modified object..
-     *
-     * <p>If the caller does not meet the access requirements for identifiers a clone of the
-     * provided SubscriptionInfo is created and modified to avoid altering SubscriptionInfo objects
-     * in a cache.
-     */
-    private SubscriptionInfo conditionallyRemoveIdentifiers(SubscriptionInfo subInfo,
-            String callingPackage, String callingFeatureId, String message) {
-        SubscriptionInfo result = subInfo;
-        int subId = subInfo.getSubscriptionId();
-        boolean hasIdentifierAccess = hasSubscriberIdentifierAccess(subId, callingPackage,
-                callingFeatureId, message, true);
-        boolean hasPhoneNumberAccess = hasPhoneNumberAccess(subId, callingPackage, callingFeatureId,
-                message);
-        return conditionallyRemoveIdentifiers(subInfo, hasIdentifierAccess, hasPhoneNumberAccess);
-    }
-
-    /**
-     * Conditionally removes identifiers from the provided {@code subInfo} based on if the calling
-     * package {@code hasIdentifierAccess} and {@code hasPhoneNumberAccess} and returns the
-     * potentially modified object.
-     *
-     * <p>If the caller specifies the package does not have identifier or phone number access
-     * a clone of the provided SubscriptionInfo is created and modified to avoid altering
-     * SubscriptionInfo objects in a cache.
-     */
-    private SubscriptionInfo conditionallyRemoveIdentifiers(SubscriptionInfo subInfo,
-            boolean hasIdentifierAccess, boolean hasPhoneNumberAccess) {
-        if (hasIdentifierAccess && hasPhoneNumberAccess) {
-            return subInfo;
-        }
-        SubscriptionInfo.Builder result = new SubscriptionInfo.Builder(subInfo);
-        if (!hasIdentifierAccess) {
-            result.setIccId(null);
-            result.setCardString(null);
-            result.setGroupUuid(null);
-        }
-        if (!hasPhoneNumberAccess) {
-            result.setNumber(null);
-        }
-        return result.build();
-    }
-
-    private synchronized boolean addToSubIdList(int slotIndex, int subId, int subscriptionType) {
-        ArrayList<Integer> subIdsList = mSlotIndexToSubIds.getCopy(slotIndex);
-        if (subIdsList == null) {
-            subIdsList = new ArrayList<>();
-            mSlotIndexToSubIds.put(slotIndex, subIdsList);
-        }
-
-        // add the given subId unless it already exists
-        if (subIdsList.contains(subId)) {
-            logdl("slotIndex, subId combo already exists in the map. Not adding it again.");
-            return false;
-        }
-        if (isSubscriptionForRemoteSim(subscriptionType)) {
-            // For Remote SIM subscriptions, a slot can have multiple subscriptions.
-            mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
-        } else {
-            // for all other types of subscriptions, a slot can have only one subscription at a time
-            mSlotIndexToSubIds.clearSubIdList(slotIndex);
-            mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
-        }
-
-
-        // Remove the slot from sSlotIndexToSubIds if it has the same sub id with the added slot
-        for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
-            if (entry.getKey() != slotIndex && entry.getValue() != null
-                    && entry.getValue().contains(subId)) {
-                logdl("addToSubIdList - remove " + entry.getKey());
-                mSlotIndexToSubIds.remove(entry.getKey());
-            }
-        }
-
-        if (DBG) logdl("slotIndex, subId combo is added to the map.");
-        return true;
-    }
-
-    private boolean isSubscriptionForRemoteSim(int subscriptionType) {
-        return subscriptionType == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM;
-    }
-
-    /**
-     * This is only for testing
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public Map<Integer, ArrayList<Integer>> getSlotIndexToSubIdsMap() {
-        return mSlotIndexToSubIds.getMap();
-    }
-
-    private void notifyOpportunisticSubscriptionInfoChanged() {
-        TelephonyRegistryManager trm =
-                (TelephonyRegistryManager)
-                        mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
-        if (DBG) logd("notifyOpptSubscriptionInfoChanged:");
-        trm.notifyOpportunisticSubscriptionInfoChanged();
-    }
-
-    private void refreshCachedOpportunisticSubscriptionInfoList() {
-        synchronized (mSubInfoListLock) {
-            List<SubscriptionInfo> subList = getSubInfo(
-                    SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND ("
-                            + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
-                            + SubscriptionManager.IS_EMBEDDED + "=1)", null);
-            List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList;
-
-            if (subList != null) {
-                subList.sort(SUBSCRIPTION_INFO_COMPARATOR);
-            } else {
-                subList = new ArrayList<>();
-            }
-
-            mCacheOpportunisticSubInfoList = subList;
-
-            for (int i = 0; i < mCacheOpportunisticSubInfoList.size(); i++) {
-                SubscriptionInfo info = mCacheOpportunisticSubInfoList.get(i);
-                if (shouldDisableSubGroup(info.getGroupUuid())) {
-                    SubscriptionInfo.Builder builder = new SubscriptionInfo.Builder(info);
-                    builder.setGroupDisabled(true);
-                    mCacheOpportunisticSubInfoList.set(i, builder.build());
-                }
-            }
-
-            if (DBG_CACHE) {
-                if (!mCacheOpportunisticSubInfoList.isEmpty()) {
-                    for (SubscriptionInfo si : mCacheOpportunisticSubInfoList) {
-                        logd("[refreshCachedOpportunisticSubscriptionInfoList] Setting Cached "
-                                + "info=" + si);
-                    }
-                } else {
-                    logdl("[refreshCachedOpportunisticSubscriptionInfoList]- no info return");
-                }
-            }
-
-            if (!oldOpptCachedList.equals(mCacheOpportunisticSubInfoList)) {
-                mOpptSubInfoListChangedDirtyBit.set(true);
-            }
-        }
-    }
-
-    private boolean shouldDisableSubGroup(ParcelUuid groupUuid) {
-        if (groupUuid == null) return false;
-
-        synchronized (mSubInfoListLock) {
-            for (SubscriptionInfo activeInfo : mCacheActiveSubInfoList) {
-                if (!activeInfo.isOpportunistic() && groupUuid.equals(activeInfo.getGroupUuid())) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Set enabled mobile data policies.
-     *
-     * @param subId Subscription index
-     * @param policies Mobile data policies in string format.
-     *                 See {@link TelephonyManager.MobileDataPolicy} for details.
-     * @return {@code true} if settings changed, otherwise {@code false}.
-     */
-    public boolean setEnabledMobileDataPolicies(int subId, @NonNull String policies) {
-        if (DBG) logd("[setEnabledMobileDataPolicies]+ policies:" + policies + " subId:" + subId);
-
-        validateSubId(subId);
-        ContentValues value = new ContentValues(1);
-        value.put(SubscriptionManager.ENABLED_MOBILE_DATA_POLICIES, policies);
-
-        boolean result = updateDatabase(value, subId, true) > 0;
-
-        if (result) {
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-            notifySubscriptionInfoChanged();
-        }
-
-        return result;
-    }
-
-    /**
-     * Get enabled mobile data policies.
-     *
-     * @param subId Subscription index
-     * @return Enabled mobile data policies joined by "," (ie. "1,2") or an empty string if no
-     * policies are enabled.
-     */
-    @NonNull
-    public String getEnabledMobileDataPolicies(int subId) {
-        return TelephonyUtils.emptyIfNull(getSubscriptionProperty(subId,
-                SubscriptionManager.ENABLED_MOBILE_DATA_POLICIES));
-    }
-
-    /**
-     * Get active data subscription id.
-     *
-     * @return Active data subscription id
-     *
-     * @hide
-     */
-    @Override
-    public int getActiveDataSubscriptionId() {
-        final long token = Binder.clearCallingIdentity();
-
-        try {
-            PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
-            if (phoneSwitcher != null) {
-                int activeDataSubId = phoneSwitcher.getActiveDataSubId();
-                if (SubscriptionManager.isUsableSubscriptionId(activeDataSubId)) {
-                    return activeDataSubId;
-                }
-            }
-            // If phone switcher isn't ready, or active data sub id is not available, use default
-            // sub id from settings.
-            return getDefaultDataSubId();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Whether it's supported to disable / re-enable a subscription on a physical (non-euicc) SIM.
-     */
-    @Override
-    public boolean canDisablePhysicalSubscription() {
-        enforceReadPrivilegedPhoneState("canToggleUiccApplicationsEnablement");
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            Phone phone = PhoneFactory.getDefaultPhone();
-            return phone != null && phone.canDisablePhysicalSubscription();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /*
-     * 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;
-    }
-
-    /**
-     * Querying last used TP - MessageRef for particular subId from SIMInfo table.
-     * @return messageRef
-     */
-    public int getMessageRef(int subId) {
-        try (Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
-                new String[]{SubscriptionManager.TP_MESSAGE_REF},
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=\"" + subId
-                        + "\"", null, null)) {
-            try {
-                if (cursor != null && cursor.moveToFirst()) {
-                    do {
-                        return cursor.getInt(cursor.getColumnIndexOrThrow(
-                                SubscriptionManager.TP_MESSAGE_REF));
-                    } while (cursor.moveToNext());
-                } else {
-                    if (DBG) logd("Valid row not present in db");
-                }
-            } catch (Exception e) {
-                if (DBG) logd("Query failed " + e.getMessage());
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Update the TP - Message Reference value for every SMS Sent
-     * @param messageRef
-     * @param subId
-     */
-    public void updateMessageRef(int subId, int messageRef) {
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                mContext, subId, mContext.getOpPackageName());
-
-        if (mContext == null) {
-            logel("[updateMessageRef] mContext is null");
-            return;
-        }
-        try {
-            if (SubscriptionManager.CONTENT_URI != null) {
-                ContentValues values = new ContentValues(1);
-                values.put(SubscriptionManager.TP_MESSAGE_REF, messageRef);
-                mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, values,
-                        SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=\"" + subId
-                                + "\"", null);
-            } else {
-                if (DBG) logd("TP - Message reference value not updated to DB");
-            }
-        } finally {
-            if (DBG) logd("TP - Message reference updated to DB Successfully :" + messageRef);
-        }
-    }
-
-    /**
-     * Set UserHandle for this subscription
-     *
-     * @param userHandle the userHandle associated with the subscription
-     * Pass {@code null} user handle to clear the association
-     * @param subId the unique SubscriptionInfo index in database
-     * @return the number of records updated.
-     *
-     * @throws SecurityException if doesn't have required permission.
-     * @throws IllegalArgumentException if subId is invalid.
-     */
-    @Override
-    public int setSubscriptionUserHandle(@Nullable UserHandle userHandle, int subId) {
-        enforceManageSubscriptionUserAssociation("setSubscriptionUserHandle");
-
-        if (userHandle == null) {
-            userHandle = UserHandle.of(UserHandle.USER_NULL);
-        }
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            int ret = setSubscriptionProperty(subId, SubscriptionManager.USER_HANDLE,
-                    String.valueOf(userHandle.getIdentifier()));
-            // ret is the number of records updated in the DB
-            if (ret != 0) {
-                notifySubscriptionInfoChanged();
-            } else {
-                throw new IllegalArgumentException("[setSubscriptionUserHandle]: Invalid subId: "
-                        + subId);
-            }
-            return ret;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Get UserHandle of this subscription.
-     *
-     * @param subId the unique SubscriptionInfo index in database
-     * @return userHandle associated with this subscription
-     * or {@code null} if subscription is not associated with any user.
-     *
-     * @throws SecurityException if doesn't have required permission.
-     * @throws IllegalArgumentException if subId is invalid.
-     */
-    @Override
-    @Nullable
-    public UserHandle getSubscriptionUserHandle(int subId) {
-        enforceManageSubscriptionUserAssociation("getSubscriptionUserHandle");
-
-        if (!mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enable_get_subscription_user_handle)) {
-            return null;
-        }
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            String userHandleStr = getSubscriptionProperty(subId, SubscriptionManager.USER_HANDLE);
-            if (userHandleStr == null) {
-                throw new IllegalArgumentException("[getSubscriptionUserHandle]: Invalid subId: "
-                        + subId);
-            }
-            UserHandle userHandle = UserHandle.of(Integer.parseInt(userHandleStr));
-            if (userHandle.getIdentifier() == UserHandle.USER_NULL) {
-                return null;
-            }
-            return userHandle;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Check if subscription and user are associated with each other.
-     *
-     * @param subscriptionId the subId of the subscription
-     * @param userHandle user handle of the user
-     * @return {@code true} if subscription is associated with user
-     * {code true} if there are no subscriptions on device
-     * else {@code false} if subscription is not associated with user.
-     *
-     * @throws SecurityException if the caller doesn't have permissions required.
-     * @throws IllegalStateException if subscription service is not available.
-     *
-     */
-    @Override
-    public boolean isSubscriptionAssociatedWithUser(int subscriptionId,
-            @NonNull UserHandle userHandle) {
-        enforceManageSubscriptionUserAssociation("isSubscriptionAssociatedWithUser");
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            // Return true if there are no subscriptions on the device.
-            List<SubscriptionInfo> subInfoList = getAllSubInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (subInfoList == null || subInfoList.isEmpty()) {
-                return true;
-            }
-
-            // Get list of subscriptions associated with this user.
-            List<SubscriptionInfo> associatedSubscriptionsList =
-                    getSubscriptionInfoListAssociatedWithUser(userHandle);
-            if (associatedSubscriptionsList.isEmpty()) {
-                return false;
-            }
-
-            // Return true if required subscription is present in associated subscriptions list.
-            for (SubscriptionInfo subInfo: associatedSubscriptionsList) {
-                if (subInfo.getSubscriptionId() == subscriptionId){
-                    return true;
-                }
-            }
-            return false;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Get list of subscriptions associated with user.
-     *
-     * If user handle is associated with some subscriptions, return subscriptionsAssociatedWithUser
-     * else return all the subscriptions which are not associated with any user.
-     *
-     * @param userHandle user handle of the user
-     * @return list of subscriptionInfo associated with the user.
-     *
-     * @throws SecurityException if the caller doesn't have permissions required.
-     * @throws IllegalStateException if subscription service is not available.
-     *
-     */
-    @Override
-    public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(
-            @NonNull UserHandle userHandle) {
-        enforceManageSubscriptionUserAssociation("getActiveSubscriptionInfoListAssociatedWithUser");
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            List<SubscriptionInfo> subInfoList =  getAllSubInfoList(
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-            if (subInfoList == null || subInfoList.isEmpty()) {
-                return new ArrayList<>();
-            }
-
-            List<SubscriptionInfo> subscriptionsAssociatedWithUser = new ArrayList<>();
-            List<SubscriptionInfo> subscriptionsWithNoAssociation = new ArrayList<>();
-            for (SubscriptionInfo subInfo : subInfoList) {
-                int subId = subInfo.getSubscriptionId();
-                UserHandle subIdUserHandle = getSubscriptionUserHandle(subId);
-                if (userHandle.equals(subIdUserHandle)) {
-                    // Store subscriptions whose user handle matches with required user handle.
-                    subscriptionsAssociatedWithUser.add(subInfo);
-                } else if (subIdUserHandle == null) {
-                    // Store subscriptions whose user handle is set to null.
-                    subscriptionsWithNoAssociation.add(subInfo);
-                }
-            }
-
-            return subscriptionsAssociatedWithUser.isEmpty() ?
-                    subscriptionsWithNoAssociation : subscriptionsAssociatedWithUser;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * @return {@code true} if using {@link SubscriptionManagerService} instead of
-     * {@link SubscriptionController}.
-     */
-    //TODO: Removed before U AOSP public release.
-    @Override
-    public boolean isSubscriptionManagerServiceEnabled() {
-        return false;
-    }
-
-    /**
-     * @hide
-     */
-    private void setGlobalSetting(String name, int value) {
-        Settings.Global.putInt(mContext.getContentResolver(), name, value);
-        if (TextUtils.equals(name, Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION)) {
-            invalidateDefaultDataSubIdCaches();
-            invalidateActiveDataSubIdCaches();
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION)) {
-            invalidateDefaultSubIdCaches();
-            invalidateSlotIndexCaches();
-        } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION)) {
-            invalidateDefaultSmsSubIdCaches();
-        }
-    }
-
-    private static void invalidateDefaultSubIdCaches() {
-        SubscriptionManager.invalidateDefaultSubIdCaches();
-    }
-
-    private static void invalidateDefaultDataSubIdCaches() {
-        SubscriptionManager.invalidateDefaultDataSubIdCaches();
-    }
-
-    private static void invalidateDefaultSmsSubIdCaches() {
-        SubscriptionManager.invalidateDefaultSmsSubIdCaches();
-    }
-
-    private static void invalidateActiveDataSubIdCaches() {
-        SubscriptionManager.invalidateActiveDataSubIdCaches();
-    }
-
-    private static void invalidateSlotIndexCaches() {
-        SubscriptionManager.invalidateSlotIndexCaches();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
deleted file mode 100644
index d8e9a7e..0000000
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ /dev/null
@@ -1,1356 +0,0 @@
-/*
-* Copyright (C) 2014 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package com.android.internal.telephony;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-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;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelUuid;
-import android.os.PersistableBundle;
-import android.os.UserHandle;
-import android.preference.PreferenceManager;
-import android.service.carrier.CarrierIdentifier;
-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.UiccAccessRule;
-import android.telephony.euicc.EuiccManager;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.euicc.EuiccController;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.uicc.IccRecords;
-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;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-/**
- *@hide
- */
-public class SubscriptionInfoUpdater extends Handler {
-    private static final String LOG_TAG = "SubscriptionInfoUpdater";
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private static final int SUPPORTED_MODEM_COUNT = TelephonyManager.getDefault()
-            .getSupportedModemCount();
-
-    private static final boolean DBG = true;
-
-    private static final int EVENT_INVALID = -1;
-    private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 2;
-    private static final int EVENT_SIM_LOADED = 3;
-    private static final int EVENT_SIM_ABSENT = 4;
-    private static final int EVENT_SIM_LOCKED = 5;
-    private static final int EVENT_SIM_IO_ERROR = 6;
-    private static final int EVENT_SIM_UNKNOWN = 7;
-    private static final int EVENT_SIM_RESTRICTED = 8;
-    private static final int EVENT_SIM_NOT_READY = 9;
-    private static final int EVENT_SIM_READY = 10;
-    private static final int EVENT_SIM_IMSI = 11;
-    private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12;
-    private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 13;
-    private static final int EVENT_INACTIVE_SLOT_ICC_STATE_CHANGED = 14;
-
-    private static final String ICCID_STRING_FOR_NO_SIM = "";
-
-    private static final ParcelUuid REMOVE_GROUP_UUID =
-            ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING);
-
-    // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED.
-    public static final String CURR_SUBID = "curr_subid";
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private static Context sContext = null;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-
-    protected static String[] sIccId = new String[SUPPORTED_MODEM_COUNT];
-    protected SubscriptionController mSubscriptionController = null;
-    private static String[] sInactiveIccIds = new String[SUPPORTED_MODEM_COUNT];
-    private static int[] sSimCardState = new int[SUPPORTED_MODEM_COUNT];
-    private static int[] sSimApplicationState = new int[SUPPORTED_MODEM_COUNT];
-    private static boolean sIsSubInfoInitialized = false;
-    private SubscriptionManager mSubscriptionManager = null;
-    private EuiccManager mEuiccManager;
-    private Handler mBackgroundHandler;
-
-    // The current foreground user ID.
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    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).
-     */
-    protected interface UpdateEmbeddedSubsCallback {
-        /**
-         * Callback of the Runnable.
-         * @param hasChanges Whether there is any subscription info change. If yes, we need to
-         * notify the listeners.
-         */
-        void run(boolean hasChanges);
-    }
-
-    @VisibleForTesting
-    public SubscriptionInfoUpdater(Looper looper, Context context, SubscriptionController sc) {
-        logd("Constructor invoked");
-        mBackgroundHandler = new Handler(looper);
-
-        sContext = context;
-        mSubscriptionController = sc;
-        mSubscriptionManager = SubscriptionManager.from(sContext);
-        mEuiccManager = (EuiccManager) sContext.getSystemService(Context.EUICC_SERVICE);
-
-        mCarrierServiceBindHelper = new CarrierServiceBindHelper(sContext);
-
-        sContext.registerReceiver(
-                mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-
-        initializeCarrierApps();
-
-        PhoneConfigurationManager.registerForMultiSimConfigChange(
-                this, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
-    }
-
-    private void initializeCarrierApps() {
-        // Initialize carrier apps:
-        // -Now (on system startup)
-        // -Whenever new carrier privilege rules might change (new SIM is loaded)
-        // -Whenever we switch to a new user
-        mCurrentlyActiveUserId = 0;
-        sContext.registerReceiverForAllUsers(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                // Remove this line after testing
-                if (Intent.ACTION_USER_FOREGROUND.equals(intent.getAction())) {
-                    UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
-                    // If couldn't get current user ID, guess it's 0.
-                    mCurrentlyActiveUserId = userHandle != null ? userHandle.getIdentifier() : 0;
-                    CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
-                            TelephonyManager.getDefault(), mCurrentlyActiveUserId, sContext);
-                }
-            }
-        }, new IntentFilter(Intent.ACTION_USER_FOREGROUND), null, null);
-        ActivityManager am = (ActivityManager) sContext.getSystemService(Context.ACTIVITY_SERVICE);
-        mCurrentlyActiveUserId = am.getCurrentUser();
-        CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
-                TelephonyManager.getDefault(), mCurrentlyActiveUserId, sContext);
-    }
-
-    /**
-     * Update subscriptions when given a new ICC state.
-     */
-    public void updateInternalIccState(String simStatus, String reason, int phoneId) {
-        logd("updateInternalIccState to simStatus " + simStatus + " reason " + reason
-                + " phoneId " + phoneId);
-        int message = internalIccStateToMessage(simStatus);
-        if (message != EVENT_INVALID) {
-            sendMessage(obtainMessage(message, phoneId, 0, reason));
-        }
-    }
-
-    /**
-     * 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
-     *                          active. It could be INVALID if it was already inactive.
-     * @param iccId iccId in that port, if any.
-     */
-    public void updateInternalIccStateForInactivePort(int prevActivePhoneId, String iccId) {
-        sendMessage(obtainMessage(EVENT_INACTIVE_SLOT_ICC_STATE_CHANGED, prevActivePhoneId,
-                0, iccId));
-    }
-
-    private int internalIccStateToMessage(String simStatus) {
-        switch(simStatus) {
-            case IccCardConstants.INTENT_VALUE_ICC_ABSENT: return EVENT_SIM_ABSENT;
-            case IccCardConstants.INTENT_VALUE_ICC_UNKNOWN: return EVENT_SIM_UNKNOWN;
-            case IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR: return EVENT_SIM_IO_ERROR;
-            case IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED: return EVENT_SIM_RESTRICTED;
-            case IccCardConstants.INTENT_VALUE_ICC_NOT_READY: return EVENT_SIM_NOT_READY;
-            case IccCardConstants.INTENT_VALUE_ICC_LOCKED: return EVENT_SIM_LOCKED;
-            case IccCardConstants.INTENT_VALUE_ICC_LOADED: return EVENT_SIM_LOADED;
-            case IccCardConstants.INTENT_VALUE_ICC_READY: return EVENT_SIM_READY;
-            case IccCardConstants.INTENT_VALUE_ICC_IMSI: return EVENT_SIM_IMSI;
-            default:
-                logd("Ignoring simStatus: " + simStatus);
-                return EVENT_INVALID;
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected boolean isAllIccIdQueryDone() {
-        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) {
-                    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)));
-                }
-                return false;
-            }
-        }
-        logd("All IccIds query complete");
-
-        return true;
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        List<Integer> cardIds = new ArrayList<>();
-        switch (msg.what) {
-            case EVENT_GET_NETWORK_SELECTION_MODE_DONE: {
-                AsyncResult ar = (AsyncResult)msg.obj;
-                Integer slotId = (Integer)ar.userObj;
-                if (ar.exception == null && ar.result != null) {
-                    int[] modes = (int[])ar.result;
-                    if (modes[0] == 1) {  // Manual mode.
-                        PhoneFactory.getPhone(slotId).setNetworkSelectionModeAutomatic(null);
-                    }
-                } else {
-                    logd("EVENT_GET_NETWORK_SELECTION_MODE_DONE: error getting network mode.");
-                }
-                break;
-            }
-
-            case EVENT_SIM_LOADED:
-                handleSimLoaded(msg.arg1);
-                break;
-
-            case EVENT_SIM_ABSENT:
-                handleSimAbsent(msg.arg1);
-                break;
-
-            case EVENT_INACTIVE_SLOT_ICC_STATE_CHANGED:
-                handleInactivePortIccStateChange(msg.arg1, (String) msg.obj);
-                break;
-
-            case EVENT_SIM_LOCKED:
-                handleSimLocked(msg.arg1, (String) msg.obj);
-                break;
-
-            case EVENT_SIM_UNKNOWN:
-                broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null);
-                broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN);
-                broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN);
-                updateSubscriptionCarrierId(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN);
-                updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN);
-                break;
-
-            case EVENT_SIM_IO_ERROR:
-                handleSimError(msg.arg1);
-                break;
-
-            case EVENT_SIM_RESTRICTED:
-                broadcastSimStateChanged(msg.arg1,
-                        IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED,
-                        IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED);
-                broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_CARD_RESTRICTED);
-                broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_NOT_READY);
-                updateSubscriptionCarrierId(msg.arg1,
-                        IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED);
-                updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED);
-                break;
-
-            case EVENT_SIM_READY:
-                handleSimReady(msg.arg1);
-                break;
-
-            case EVENT_SIM_IMSI:
-                broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_IMSI, null);
-                break;
-
-            case EVENT_SIM_NOT_READY:
-                // an eUICC with no active subscriptions never becomes ready, so we need to trigger
-                // the embedded subscriptions update here
-                cardIds.add(getCardIdFromPhoneId(msg.arg1));
-                updateEmbeddedSubscriptions(cardIds, (hasChanges) -> {
-                    if (hasChanges) {
-                        mSubscriptionController.notifySubscriptionInfoChanged();
-                    }
-                });
-                handleSimNotReady(msg.arg1);
-                break;
-
-            case EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS:
-                cardIds.add(msg.arg1);
-                Runnable r = (Runnable) msg.obj;
-                updateEmbeddedSubscriptions(cardIds, (hasChanges) -> {
-                    if (hasChanges) {
-                        mSubscriptionController.notifySubscriptionInfoChanged();
-                    }
-                    if (r != null) {
-                        r.run();
-                    }
-                });
-                break;
-
-            case EVENT_MULTI_SIM_CONFIG_CHANGED:
-                onMultiSimConfigChanged();
-                break;
-
-            default:
-                logd("Unknown msg:" + msg.what);
-        }
-    }
-
-    private void onMultiSimConfigChanged() {
-        int activeModemCount = ((TelephonyManager) sContext.getSystemService(
-                Context.TELEPHONY_SERVICE)).getActiveModemCount();
-        // For inactive modems, reset its states.
-        for (int phoneId = activeModemCount; phoneId < SUPPORTED_MODEM_COUNT; phoneId++) {
-            sIccId[phoneId] = null;
-            sSimCardState[phoneId] = TelephonyManager.SIM_STATE_UNKNOWN;
-            sSimApplicationState[phoneId] = TelephonyManager.SIM_STATE_UNKNOWN;
-        }
-    }
-
-    protected int getCardIdFromPhoneId(int phoneId) {
-        UiccController uiccController = UiccController.getInstance();
-        UiccCard card = uiccController.getUiccCardForPhone(phoneId);
-        if (card != null) {
-            return uiccController.convertToPublicCardId(card.getCardId());
-        }
-        return TelephonyManager.UNINITIALIZED_CARD_ID;
-    }
-
-    void requestEmbeddedSubscriptionInfoListRefresh(int cardId, @Nullable Runnable callback) {
-        sendMessage(obtainMessage(
-                EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS, cardId, 0 /* arg2 */, callback));
-    }
-
-    protected void handleSimLocked(int phoneId, String reason) {
-        if (sIccId[phoneId] != null && sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
-            logd("SIM" + (phoneId + 1) + " hot plug in");
-            sIccId[phoneId] = null;
-        }
-
-        IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-        if (iccCard == null) {
-            logd("handleSimLocked: IccCard null");
-            return;
-        }
-        IccRecords records = iccCard.getIccRecords();
-        if (records == null) {
-            logd("handleSimLocked: IccRecords null");
-            return;
-        }
-        if (IccUtils.stripTrailingFs(records.getFullIccId()) == null) {
-            logd("handleSimLocked: IccID null");
-            return;
-        }
-        sIccId[phoneId] = IccUtils.stripTrailingFs(records.getFullIccId());
-
-        updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
-
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
-        broadcastSimApplicationStateChanged(phoneId, getSimStateFromLockedReason(reason));
-        updateSubscriptionCarrierId(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOCKED);
-        updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOCKED);
-    }
-
-    private static int getSimStateFromLockedReason(String lockedReason) {
-        switch (lockedReason) {
-            case IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN:
-                return TelephonyManager.SIM_STATE_PIN_REQUIRED;
-            case IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK:
-                return TelephonyManager.SIM_STATE_PUK_REQUIRED;
-            case IccCardConstants.INTENT_VALUE_LOCKED_NETWORK:
-                return TelephonyManager.SIM_STATE_NETWORK_LOCKED;
-            case IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED:
-                return TelephonyManager.SIM_STATE_PERM_DISABLED;
-            default:
-                Rlog.e(LOG_TAG, "Unexpected SIM locked reason " + lockedReason);
-                return TelephonyManager.SIM_STATE_UNKNOWN;
-        }
-    }
-
-    protected void handleSimReady(int phoneId) {
-        List<Integer> cardIds = new ArrayList<>();
-        logd("handleSimReady: phoneId: " + phoneId);
-
-        if (sIccId[phoneId] != null && sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
-            logd(" SIM" + (phoneId + 1) + " hot plug in");
-            sIccId[phoneId] = null;
-        }
-
-        // 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());
-
-        if (!TextUtils.isEmpty(iccId)) {
-            sIccId[phoneId] = iccId;
-            updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
-        }
-
-        cardIds.add(getCardIdFromPhoneId(phoneId));
-        updateEmbeddedSubscriptions(cardIds, (hasChanges) -> {
-            if (hasChanges) {
-                mSubscriptionController.notifySubscriptionInfoChanged();
-            }
-        });
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_READY, null);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
-        broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_NOT_READY);
-    }
-
-    protected void handleSimNotReady(int phoneId) {
-        logd("handleSimNotReady: phoneId: " + phoneId);
-        boolean isFinalState = false;
-
-        IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-        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);
-            }
-            isFinalState = true;
-            // ICC_NOT_READY is a terminal state for
-            // 1) It's an empty profile as there's no uicc applications. Or
-            // 2) Its uicc applications are set to be disabled.
-            // At this phase, the subscription list is accessible. Treating NOT_READY
-            // as equivalent to ABSENT, once the rest of the system can handle it.
-            sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
-            updateSubscriptionInfoByIccId(phoneId, false /* updateEmbeddedSubs */);
-        } else {
-            sIccId[phoneId] = null;
-        }
-
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY,
-                null);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
-        broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_NOT_READY);
-        if (isFinalState) {
-            updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY);
-        }
-    }
-
-    private boolean areUiccAppsDisabledOnCard(int phoneId) {
-        // When uicc apps are disabled(supported in IRadio 1.5), we will still get IccId from
-        // 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;
-        }
-        SubscriptionInfo info =
-                mSubscriptionController.getSubInfoForIccId(
-                        IccUtils.stripTrailingFs(iccId));
-        return info != null && !info.areUiccApplicationsEnabled();
-    }
-
-    protected void handleSimLoaded(int phoneId) {
-        logd("handleSimLoaded: phoneId: " + phoneId);
-
-        // The SIM should be loaded at this state, but it is possible in cases such as SIM being
-        // removed or a refresh RESET that the IccRecords could be null. The right behavior is to
-        // not broadcast the SIM loaded.
-        IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-        if (iccCard == null) {  // Possibly a race condition.
-            logd("handleSimLoaded: IccCard null");
-            return;
-        }
-        IccRecords records = iccCard.getIccRecords();
-        if (records == null) {  // Possibly a race condition.
-            logd("handleSimLoaded: IccRecords null");
-            return;
-        }
-        if (IccUtils.stripTrailingFs(records.getFullIccId()) == null) {
-            logd("handleSimLoaded: IccID null");
-            return;
-        }
-
-        // Call updateSubscriptionInfoByIccId() only if was not done earlier from SIM READY event
-        if (sIccId[phoneId] == null) {
-            sIccId[phoneId] = IccUtils.stripTrailingFs(records.getFullIccId());
-
-            updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
-        }
-
-        List<SubscriptionInfo> subscriptionInfos =
-                mSubscriptionController.getSubInfoUsingSlotIndexPrivileged(phoneId);
-        if (subscriptionInfos == null || subscriptionInfos.isEmpty()) {
-            loge("empty subinfo for phoneId: " + phoneId + "could not update ContentResolver");
-        } else {
-            for (SubscriptionInfo sub : subscriptionInfos) {
-                int subId = sub.getSubscriptionId();
-                TelephonyManager tm = (TelephonyManager)
-                        sContext.getSystemService(Context.TELEPHONY_SERVICE);
-                String operator = tm.getSimOperatorNumeric(subId);
-
-                if (!TextUtils.isEmpty(operator)) {
-                    if (subId == mSubscriptionController.getDefaultSubId()) {
-                        MccTable.updateMccMncConfiguration(sContext, operator);
-                    }
-                    mSubscriptionController.setMccMnc(operator, subId);
-                } else {
-                    logd("EVENT_RECORDS_LOADED Operator name is null");
-                }
-
-                String iso = tm.getSimCountryIsoForPhone(phoneId);
-
-                if (!TextUtils.isEmpty(iso)) {
-                    mSubscriptionController.setCountryIso(iso, subId);
-                } else {
-                    logd("EVENT_RECORDS_LOADED sim country iso is null");
-                }
-
-                String msisdn = tm.getLine1Number(subId);
-                if (msisdn != null) {
-                    mSubscriptionController.setDisplayNumber(msisdn, subId);
-                }
-
-                String imsi = tm.createForSubscriptionId(subId).getSubscriberId();
-                if (imsi != null) {
-                    mSubscriptionController.setImsi(imsi, subId);
-                }
-
-                String[] ehplmns = records.getEhplmns();
-                String[] hplmns = records.getPlmnsFromHplmnActRecord();
-                if (ehplmns != null || hplmns != null) {
-                    mSubscriptionController.setAssociatedPlmns(ehplmns, hplmns, subId);
-                }
-
-                /* Update preferred network type and network selection mode on SIM change.
-                 * Storing last subId in SharedPreference for now to detect SIM change.
-                 */
-                SharedPreferences sp =
-                        PreferenceManager.getDefaultSharedPreferences(sContext);
-                int storedSubId = sp.getInt(CURR_SUBID + phoneId, -1);
-
-                if (storedSubId != subId) {
-                    // Only support automatic selection mode on SIM change.
-                    PhoneFactory.getPhone(phoneId).getNetworkSelectionMode(
-                            obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE,
-                                    new Integer(phoneId)));
-                    // Update stored subId
-                    SharedPreferences.Editor editor = sp.edit();
-                    editor.putInt(CURR_SUBID + phoneId, subId);
-                    editor.apply();
-                }
-            }
-        }
-
-        /**
-         * The sim loading sequence will be
-         *  1. OnSubscriptionsChangedListener is called through updateSubscriptionInfoByIccId()
-         *  above.
-         *  2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED
-         *  /ACTION_SIM_APPLICATION_STATE_CHANGED
-         *  3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED
-         *  4. restore sim-specific settings
-         *  5. ACTION_CARRIER_CONFIG_CHANGED
-         */
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
-        broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_LOADED);
-        updateSubscriptionCarrierId(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
-        /* Sim-specific settings restore depends on knowing both the mccmnc and the carrierId of the
-        sim which is why it must be done after #updateSubscriptionCarrierId(). It is done before
-        carrier config update to avoid any race conditions with user settings that depend on
-        carrier config*/
-        restoreSimSpecificSettingsForPhone(phoneId);
-        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);
-        mCarrierServiceBindHelper.updateForPhoneId(phoneId, simState);
-    }
-
-    private void updateSubscriptionCarrierId(int phoneId, String simState) {
-        if (PhoneFactory.getPhone(phoneId) != null) {
-            PhoneFactory.getPhone(phoneId).resolveSubscriptionCarrierId(simState);
-        }
-    }
-
-    /**
-     * PhoneId is the corresponding phoneId of the port if port was previously active.
-     * It could be INVALID if it was already inactive.
-     */
-    private void handleInactivePortIccStateChange(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.
-            if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
-                logd("Slot of SIM" + (phoneId + 1) + " becomes inactive");
-            }
-            cleanSubscriptionInPhone(phoneId, false);
-        }
-        if (!TextUtils.isEmpty(iccId)) {
-            // If iccId is new, add a subscription record in the db.
-            String strippedIccId = IccUtils.stripTrailingFs(iccId);
-            if (mSubscriptionController.getSubInfoForIccId(strippedIccId) == null) {
-                mSubscriptionController.insertEmptySubInfoRecord(
-                        strippedIccId, "CARD", SubscriptionManager.INVALID_PHONE_INDEX,
-                        SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-            }
-        }
-    }
-
-    /**
-     * Clean subscription info when sim state becomes ABSENT. There are 2 scenarios for this:
-     * 1. SIM is actually removed
-     * 2. Slot becomes inactive, which results in SIM being treated as ABSENT, but SIM may not
-     * have been removed.
-     * @param phoneId phoneId for which the cleanup needs to be done
-     * @param isSimAbsent boolean to indicate if the SIM is actually ABSENT (case 1 above)
-     */
-    private void cleanSubscriptionInPhone(int phoneId, boolean isSimAbsent) {
-        if (sInactiveIccIds[phoneId] != null || (isSimAbsent && sIccId[phoneId] != null
-                && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM))) {
-            // When a SIM is unplugged, mark uicc applications enabled. This is to make sure when
-            // user unplugs and re-inserts the SIM card, we re-enable it.
-            // In certain cases this can happen before sInactiveIccIds is updated, which is why we
-            // check for sIccId as well (in case of isSimAbsent). The scenario is: after SIM
-            // deactivate request is sent to RIL, SIM is removed before SIM state is updated to
-            // NOT_READY. We do not need to check if this exact scenario is hit, because marking
-            // uicc applications enabled when SIM is removed should be okay to do regardless.
-            logd("cleanSubscriptionInPhone: " + phoneId + ", inactive iccid "
-                    + sInactiveIccIds[phoneId]);
-            if (sInactiveIccIds[phoneId] == null) {
-                logd("cleanSubscriptionInPhone: " + phoneId + ", isSimAbsent=" + isSimAbsent
-                        + ", iccid=" + sIccId[phoneId]);
-            }
-            String iccId = sInactiveIccIds[phoneId] != null
-                    ? sInactiveIccIds[phoneId] : sIccId[phoneId];
-            ContentValues value = new ContentValues();
-            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;
-        }
-        sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
-        updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
-    }
-
-    protected void handleSimAbsent(int phoneId) {
-        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-            logd("handleSimAbsent on invalid phoneId");
-            return;
-        }
-        if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
-            logd("SIM" + (phoneId + 1) + " hot plug out");
-        }
-        cleanSubscriptionInPhone(phoneId, true);
-
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_ABSENT);
-        broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_UNKNOWN);
-        updateSubscriptionCarrierId(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT);
-        updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT);
-    }
-
-    protected void handleSimError(int phoneId) {
-        if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
-            logd("SIM" + (phoneId + 1) + " Error ");
-        }
-        sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
-        updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
-        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR,
-                IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
-        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_CARD_IO_ERROR);
-        broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_NOT_READY);
-        updateSubscriptionCarrierId(phoneId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
-        updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
-    }
-
-    protected synchronized void updateSubscriptionInfoByIccId(int phoneId,
-            boolean updateEmbeddedSubs) {
-        logd("updateSubscriptionInfoByIccId:+ Start - phoneId: " + phoneId);
-        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-            loge("[updateSubscriptionInfoByIccId]- invalid phoneId=" + phoneId);
-            return;
-        }
-        logd("updateSubscriptionInfoByIccId: removing subscription info record: phoneId "
-                + phoneId);
-        // Clear phoneId only when sim absent is not enough. It's possible to switch SIM profile
-        // within the same slot. Need to clear the slot index of the previous sub. Thus always clear
-        // for the changing slot first.
-        mSubscriptionController.clearSubInfoRecord(phoneId);
-
-        // If SIM is not absent, insert new record or update existing record.
-        if (!ICCID_STRING_FOR_NO_SIM.equals(sIccId[phoneId]) && sIccId[phoneId] != null) {
-            logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "
-                    + sIccId[phoneId] + ", phoneId:" + phoneId);
-            mSubscriptionManager.addSubscriptionInfoRecord(sIccId[phoneId], phoneId);
-        }
-
-        List<SubscriptionInfo> subInfos =
-                mSubscriptionController.getSubInfoUsingSlotIndexPrivileged(phoneId);
-        if (subInfos != null) {
-            boolean changed = false;
-            for (int i = 0; i < subInfos.size(); i++) {
-                SubscriptionInfo temp = subInfos.get(i);
-                ContentValues value = new ContentValues(1);
-
-                String msisdn = TelephonyManager.getDefault().getLine1Number(
-                        temp.getSubscriptionId());
-
-                if (!TextUtils.equals(msisdn, temp.getNumber())) {
-                    value.put(SubscriptionManager.NUMBER, msisdn);
-                    sContext.getContentResolver().update(SubscriptionManager
-                            .getUriForSubscriptionId(temp.getSubscriptionId()), value, null, null);
-                    changed = true;
-                }
-            }
-            if (changed) {
-                // refresh Cached Active Subscription Info List
-                mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
-            }
-        }
-
-        // TODO investigate if we can update for each slot separately.
-        if (isAllIccIdQueryDone()) {
-            // Ensure the modems are mapped correctly
-            if (mSubscriptionManager.isActiveSubId(
-                    mSubscriptionManager.getDefaultDataSubscriptionId())) {
-                mSubscriptionManager.setDefaultDataSubId(
-                        mSubscriptionManager.getDefaultDataSubscriptionId());
-            } else {
-                logd("bypass reset default data sub if inactive");
-            }
-            setSubInfoInitialized();
-        }
-
-        UiccController uiccController = UiccController.getInstance();
-        UiccSlot[] uiccSlots = uiccController.getUiccSlots();
-        if (uiccSlots != null && updateEmbeddedSubs) {
-            List<Integer> cardIds = new ArrayList<>();
-            for (UiccSlot uiccSlot : uiccSlots) {
-                if (uiccSlot != null && uiccSlot.getUiccCard() != null) {
-                    int cardId = uiccController.convertToPublicCardId(
-                            uiccSlot.getUiccCard().getCardId());
-                    cardIds.add(cardId);
-                }
-            }
-            updateEmbeddedSubscriptions(cardIds, (hasChanges) -> {
-                if (hasChanges) {
-                    mSubscriptionController.notifySubscriptionInfoChanged();
-                }
-                if (DBG) logd("updateSubscriptionInfoByIccId: SubscriptionInfo update complete");
-            });
-        }
-
-        mSubscriptionController.notifySubscriptionInfoChanged();
-        if (DBG) logd("updateSubscriptionInfoByIccId: SubscriptionInfo update complete");
-    }
-
-    private void setSubInfoInitialized() {
-        // Should only be triggered once.
-        if (!sIsSubInfoInitialized) {
-            if (DBG) logd("SubInfo Initialized");
-            sIsSubInfoInitialized = true;
-            mSubscriptionController.notifySubInfoReady();
-        }
-        MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded();
-    }
-
-    /**
-     * Whether subscriptions of all SIMs are initialized.
-     */
-    public static boolean isSubInfoInitialized() {
-        return sIsSubInfoInitialized;
-    }
-
-    /**
-     * Updates the cached list of embedded subscription for the eUICC with the given list of card
-     * IDs {@code cardIds}. The step of reading the embedded subscription list from eUICC card is
-     * executed in background thread. The callback {@code callback} is executed after the cache is
-     * refreshed. The callback is executed in main thread.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void updateEmbeddedSubscriptions(List<Integer> cardIds,
-            @Nullable UpdateEmbeddedSubsCallback callback) {
-        // 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;
-        }
-
-        mBackgroundHandler.post(() -> {
-            List<Pair<Integer, GetEuiccProfileInfoListResult>> results = new ArrayList<>();
-            for (int cardId : cardIds) {
-                GetEuiccProfileInfoListResult result =
-                        EuiccController.get().blockingGetEuiccProfileInfoList(cardId);
-                if (DBG) logd("blockingGetEuiccProfileInfoList cardId " + cardId);
-                results.add(Pair.create(cardId, result));
-            }
-
-            // The runnable will be executed in the main thread.
-            this.post(() -> {
-                boolean hasChanges = false;
-                for (Pair<Integer, GetEuiccProfileInfoListResult> cardIdAndResult : results) {
-                    if (updateEmbeddedSubscriptionsCache(cardIdAndResult.first,
-                            cardIdAndResult.second)) {
-                        hasChanges = true;
-                    }
-                }
-                // The latest state in the main thread may be changed when the callback is
-                // triggered.
-                if (callback != null) {
-                    callback.run(hasChanges);
-                }
-            });
-        });
-    }
-
-    /**
-     * Update the cached list of embedded subscription based on the passed in
-     * GetEuiccProfileInfoListResult {@code result}.
-     *
-     * @return true if changes may have been made. This is not a guarantee that changes were made,
-     * but notifications about subscription changes may be skipped if this returns false as an
-     * optimization to avoid spurious notifications.
-     */
-    private boolean updateEmbeddedSubscriptionsCache(int cardId,
-            GetEuiccProfileInfoListResult result) {
-        if (DBG) logd("updateEmbeddedSubscriptionsCache");
-
-        if (result == null) {
-            if (DBG) logd("updateEmbeddedSubscriptionsCache: IPC to the eUICC controller failed");
-            retryUpdateEmbeddedSubscriptionCards.add(cardId);
-            shouldRetryUpdateEmbeddedSubscriptions = true;
-            return false;
-        }
-
-        // If the returned result is not RESULT_OK or the profile list is null, don't update cache.
-        // Otherwise, update the cache.
-        final EuiccProfileInfo[] embeddedProfiles;
-        List<EuiccProfileInfo> list = result.getProfiles();
-        if (result.getResult() == EuiccService.RESULT_OK && list != null) {
-            embeddedProfiles = list.toArray(new EuiccProfileInfo[list.size()]);
-            if (DBG) {
-                logd("blockingGetEuiccProfileInfoList: got " + result.getProfiles().size()
-                        + " profiles");
-            }
-        } else {
-            if (DBG) {
-                logd("blockingGetEuiccProfileInfoList returns an error. "
-                        + "Result code=" + result.getResult()
-                        + ". Null profile list=" + (result.getProfiles() == null));
-            }
-            return false;
-        }
-
-        final boolean isRemovable = result.getIsRemovable();
-
-        final String[] embeddedIccids = new String[embeddedProfiles.length];
-        for (int i = 0; i < embeddedProfiles.length; i++) {
-            embeddedIccids[i] = embeddedProfiles[i].getIccid();
-        }
-
-        if (DBG) logd("Get eUICC profile list of size " + embeddedProfiles.length);
-
-        // Note that this only tracks whether we make any writes to the DB. It's possible this will
-        // be set to true for an update even when the row contents remain exactly unchanged from
-        // before, since we don't compare against the previous value. Since this is only intended to
-        // avoid some spurious broadcasts (particularly for users who don't use eSIM at all), this
-        // is fine.
-        boolean hasChanges = false;
-
-        // Update or insert records for all embedded subscriptions (except non-removable ones if the
-        // current eUICC is non-removable, since we assume these are still accessible though not
-        // returned by the eUICC controller).
-        List<SubscriptionInfo> existingSubscriptions =
-                mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
-                        embeddedIccids, isRemovable);
-        ContentResolver contentResolver = sContext.getContentResolver();
-        for (EuiccProfileInfo embeddedProfile : embeddedProfiles) {
-            int index =
-                    findSubscriptionInfoForIccid(existingSubscriptions, embeddedProfile.getIccid());
-            int prevCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-            int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER_ID;
-            if (index < 0) {
-                // No existing entry for this ICCID; create an empty one.
-                mSubscriptionController.insertEmptySubInfoRecord(
-                        embeddedProfile.getIccid(), SubscriptionManager.SIM_NOT_INSERTED);
-            } else {
-                nameSource = existingSubscriptions.get(index).getDisplayNameSource();
-                prevCarrierId = existingSubscriptions.get(index).getCarrierId();
-                existingSubscriptions.remove(index);
-            }
-
-            if (DBG) {
-                logd("embeddedProfile " + embeddedProfile + " existing record "
-                        + (index < 0 ? "not found" : "found"));
-            }
-
-            ContentValues values = new ContentValues();
-            values.put(SubscriptionManager.IS_EMBEDDED, 1);
-            List<UiccAccessRule> ruleList = embeddedProfile.getUiccAccessRules();
-            boolean isRuleListEmpty = false;
-            if (ruleList == null || ruleList.size() == 0) {
-                isRuleListEmpty = true;
-            }
-            values.put(SubscriptionManager.ACCESS_RULES,
-                    isRuleListEmpty ? null : UiccAccessRule.encodeRules(
-                            ruleList.toArray(new UiccAccessRule[ruleList.size()])));
-            values.put(SubscriptionManager.IS_REMOVABLE, isRemovable);
-            // override DISPLAY_NAME if the priority of existing nameSource is <= carrier
-            if (SubscriptionController.getNameSourcePriority(nameSource)
-                    <= SubscriptionController.getNameSourcePriority(
-                            SubscriptionManager.NAME_SOURCE_CARRIER)) {
-                values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.getNickname());
-                values.put(SubscriptionManager.NAME_SOURCE,
-                        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
-                // not be accurate compared with CarrierResolver. Only update carrier id if there
-                // is no valid carrier id present.
-                if (prevCarrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
-                    values.put(SubscriptionManager.CARRIER_ID,
-                            CarrierResolver.getCarrierIdFromIdentifier(sContext, cid));
-                }
-                String mcc = cid.getMcc();
-                String mnc = cid.getMnc();
-                values.put(SubscriptionManager.MCC_STRING, mcc);
-                values.put(SubscriptionManager.MCC, mcc);
-                values.put(SubscriptionManager.MNC_STRING, mnc);
-                values.put(SubscriptionManager.MNC, mnc);
-            }
-            // If cardId = unsupported or unitialized, we have no reason to update DB.
-            // Additionally, if the device does not support cardId for default eUICC, the CARD_ID
-            // field should not contain the EID
-            UiccController uiccController = UiccController.getInstance();
-            if (cardId >= 0 && uiccController.getCardIdForDefaultEuicc()
-                    != TelephonyManager.UNSUPPORTED_CARD_ID) {
-                values.put(SubscriptionManager.CARD_ID, uiccController.convertToCardString(cardId));
-            }
-            hasChanges = true;
-            contentResolver.update(SubscriptionManager.CONTENT_URI, values,
-                    SubscriptionManager.ICC_ID + "='" + embeddedProfile.getIccid() + "'", null);
-
-            // refresh Cached Active Subscription Info List
-            mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
-        }
-
-        // Remove all remaining subscriptions which have embedded = true. We set embedded to false
-        // to ensure they are not returned in the list of embedded subscriptions (but keep them
-        // around in case the subscription is added back later, which is equivalent to a removable
-        // SIM being removed and reinserted).
-        if (!existingSubscriptions.isEmpty()) {
-            if (DBG) {
-                logd("Removing existing embedded subscriptions of size"
-                        + existingSubscriptions.size());
-            }
-            List<String> iccidsToRemove = new ArrayList<>();
-            for (int i = 0; i < existingSubscriptions.size(); i++) {
-                SubscriptionInfo info = existingSubscriptions.get(i);
-                if (info.isEmbedded()) {
-                    if (DBG) logd("Removing embedded subscription of IccId " + info.getIccId());
-                    iccidsToRemove.add("'" + info.getIccId() + "'");
-                }
-            }
-            String whereClause = SubscriptionManager.ICC_ID + " IN ("
-                    + TextUtils.join(",", iccidsToRemove) + ")";
-            ContentValues values = new ContentValues();
-            values.put(SubscriptionManager.IS_EMBEDDED, 0);
-            hasChanges = true;
-            contentResolver.update(SubscriptionManager.CONTENT_URI, values, whereClause, null);
-
-            // refresh Cached Active Subscription Info List
-            mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
-        }
-
-        if (DBG) logd("updateEmbeddedSubscriptions done hasChanges=" + hasChanges);
-        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.
-     */
-    public void updateSubscriptionByCarrierConfigAndNotifyComplete(int phoneId,
-            String configPackageName, PersistableBundle config, Message onComplete) {
-        post(() -> {
-            updateSubscriptionByCarrierConfig(phoneId, configPackageName, config);
-            onComplete.sendToTarget();
-        });
-    }
-
-    private String getDefaultCarrierServicePackageName() {
-        CarrierConfigManager configManager =
-                (CarrierConfigManager) sContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        return configManager.getDefaultCarrierServicePackageName();
-    }
-
-    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);
-    }
-
-    /**
-     * Update the currently active Subscription based on information from CarrierConfig
-     */
-    @VisibleForTesting
-    public void updateSubscriptionByCarrierConfig(
-            int phoneId, String configPackageName, PersistableBundle config) {
-        if (!SubscriptionManager.isValidPhoneId(phoneId)
-                || TextUtils.isEmpty(configPackageName) || config == null) {
-            if (DBG) {
-                logd("In updateSubscriptionByCarrierConfig(): phoneId=" + phoneId
-                        + " configPackageName=" + configPackageName + " config="
-                        + ((config == null) ? "null" : config.hashCode()));
-            }
-            return;
-        }
-
-        int currentSubId = mSubscriptionController.getSubId(phoneId);
-        if (!SubscriptionManager.isValidSubscriptionId(currentSubId)
-                || currentSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            if (DBG) logd("No subscription is active for phone being updated");
-            return;
-        }
-
-        SubscriptionInfo currentSubInfo = mSubscriptionController.getSubscriptionInfo(currentSubId);
-        if (currentSubInfo == null) {
-            loge("Couldn't retrieve subscription info for current subscription");
-            return;
-        }
-
-        ContentValues cv = new ContentValues();
-        ParcelUuid groupUuid = null;
-
-        // carrier certificates are not subscription-specific, so we want to load them even if
-        // this current package is not a CarrierServicePackage
-        String[] certs = config.getStringArray(
-            CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
-        UiccAccessRule[] carrierConfigAccessRules = UiccAccessRule.decodeRulesFromCarrierConfig(
-            certs);
-        cv.put(SubscriptionManager.ACCESS_RULES_FROM_CARRIER_CONFIGS,
-                UiccAccessRule.encodeRules(carrierConfigAccessRules));
-
-        if (!isCarrierServicePackage(phoneId, configPackageName)) {
-            loge("Cannot manage subId=" + currentSubId + ", carrierPackage=" + configPackageName);
-        } else {
-            boolean isOpportunistic = config.getBoolean(
-                    CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL,
-                    currentSubInfo.isOpportunistic());
-            if (currentSubInfo.isOpportunistic() != isOpportunistic) {
-                if (DBG) logd("Set SubId=" + currentSubId + " isOpportunistic=" + isOpportunistic);
-                cv.put(SubscriptionManager.IS_OPPORTUNISTIC, isOpportunistic ? "1" : "0");
-            }
-
-            String groupUuidString =
-                config.getString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, "");
-            if (!TextUtils.isEmpty(groupUuidString)) {
-                try {
-                    // Update via a UUID Structure to ensure consistent formatting
-                    groupUuid = ParcelUuid.fromString(groupUuidString);
-                    if (groupUuid.equals(REMOVE_GROUP_UUID)
-                            && currentSubInfo.getGroupUuid() != null) {
-                        cv.put(SubscriptionManager.GROUP_UUID, (String) null);
-                        if (DBG) logd("Group Removed for" + currentSubId);
-                    } else if (mSubscriptionController.canPackageManageGroup(
-                            groupUuid, configPackageName)) {
-                        cv.put(SubscriptionManager.GROUP_UUID, groupUuid.toString());
-                        cv.put(SubscriptionManager.GROUP_OWNER, configPackageName);
-                        if (DBG) logd("Group Added for" + currentSubId);
-                    } else {
-                        loge("configPackageName " + configPackageName + " doesn't own grouUuid "
-                            + groupUuid);
-                    }
-                } catch (IllegalArgumentException e) {
-                    loge("Invalid Group UUID=" + groupUuidString);
-                }
-            }
-        }
-
-        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();
-            mSubscriptionController.notifySubscriptionInfoChanged();
-            MultiSimSettingController.getInstance().notifySubscriptionGroupChanged(groupUuid);
-        }
-    }
-
-    private static int findSubscriptionInfoForIccid(List<SubscriptionInfo> list, String iccid) {
-        for (int i = 0; i < list.size(); i++) {
-            if (TextUtils.equals(iccid, list.get(i).getIccId())) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    protected void broadcastSimStateChanged(int phoneId, String state, String reason) {
-        // Note: This intent is way deprecated and is only being kept around because there's no
-        // graceful way to deprecate a sticky broadcast that has a lot of listeners.
-        // DO NOT add any new extras to this broadcast -- it is not protected by any permissions.
-        Intent i = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        i.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
-        i.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, state);
-        i.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
-        SubscriptionManager.putPhoneIdAndSubIdExtra(i, phoneId);
-        logd("Broadcasting intent ACTION_SIM_STATE_CHANGED " + state + " reason " + reason +
-                " for phone: " + phoneId);
-        IntentBroadcaster.getInstance().broadcastStickyIntent(sContext, i, phoneId);
-    }
-
-    protected void broadcastSimCardStateChanged(int phoneId, int state) {
-        if (state != sSimCardState[phoneId]) {
-            sSimCardState[phoneId] = state;
-            Intent i = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
-            i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            i.putExtra(TelephonyManager.EXTRA_SIM_STATE, state);
-            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 "
-                    + TelephonyManager.simStateToString(state) + " for phone: " + phoneId
-                    + " slot: " + slotId + " port: " + slot.getPortIndexFromPhoneId(phoneId));
-            sContext.sendBroadcast(i, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
-            TelephonyMetrics.getInstance().updateSimState(phoneId, state);
-        }
-    }
-
-    protected void broadcastSimApplicationStateChanged(int phoneId, int state) {
-        // Broadcast if the state has changed, except if old state was UNKNOWN and new is NOT_READY,
-        // because that's the initial state and a broadcast should be sent only on a transition
-        // after SIM is PRESENT. The only exception is eSIM boot profile, where NOT_READY is the
-        // terminal state.
-        boolean isUnknownToNotReady =
-                (sSimApplicationState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN
-                        && state == TelephonyManager.SIM_STATE_NOT_READY);
-        IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-        boolean emptyProfile = iccCard != null && iccCard.isEmptyProfile();
-        if (state != sSimApplicationState[phoneId] && (!isUnknownToNotReady || emptyProfile)) {
-            sSimApplicationState[phoneId] = state;
-            Intent i = new Intent(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
-            i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            i.putExtra(TelephonyManager.EXTRA_SIM_STATE, state);
-            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 "
-                    + TelephonyManager.simStateToString(state) + " for phone: " + phoneId
-                    + " slot: " + slotId + "port: " + slot.getPortIndexFromPhoneId(phoneId));
-            sContext.sendBroadcast(i, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
-            TelephonyMetrics.getInstance().updateSimState(phoneId, state);
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private static void logd(String message) {
-        Rlog.d(LOG_TAG, message);
-    }
-
-    private static void loge(String message) {
-        Rlog.e(LOG_TAG, message);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("SubscriptionInfoUpdater:");
-        mCarrierServiceBindHelper.dump(fd, pw, args);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/TelephonyAdminReceiver.java b/src/java/com/android/internal/telephony/TelephonyAdminReceiver.java
new file mode 100644
index 0000000..994405b
--- /dev/null
+++ b/src/java/com/android/internal/telephony/TelephonyAdminReceiver.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 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.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserManager;
+import android.telephony.Rlog;
+
+/**
+ * A BroadcastReceiver for device administration events.
+ */
+public class TelephonyAdminReceiver extends BroadcastReceiver {
+    private static final String TAG = "TelephonyAdminReceiver";
+    private final Phone mPhone;
+    // We keep track of the last value to avoid updating when unrelated user restrictions change
+    private boolean mDisallowCellular2gRestriction = false;
+    private final Context mContext;
+    private UserManager mUserManager;
+
+    public TelephonyAdminReceiver(Context context, Phone phone) {
+        mContext = context;
+        mPhone = phone;
+        mUserManager = null;
+        if (ensureUserManagerExists()) {
+            mDisallowCellular2gRestriction = mUserManager.hasUserRestriction(
+                    UserManager.DISALLOW_CELLULAR_2G);
+        }
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
+        context.registerReceiver(this, filter);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Rlog.d(TAG, "Processing onReceive");
+        if (context == null || intent == null) return;
+        if (!intent.getAction().equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) {
+            Rlog.d(TAG, "Ignoring unexpected action: " + intent.getAction());
+            return;
+        }
+        if (!ensureUserManagerExists()) {
+            return;
+        }
+        boolean shouldDisallow2g = mUserManager.hasUserRestriction(
+                UserManager.DISALLOW_CELLULAR_2G);
+
+        if (shouldDisallow2g != mDisallowCellular2gRestriction) {
+            Rlog.i(TAG,
+                    "Updating allowed network types with new admin 2g restriction. no_cellular_2g: "
+                            + shouldDisallow2g);
+            mDisallowCellular2gRestriction = shouldDisallow2g;
+            mPhone.sendSubscriptionSettings(false);
+        } else {
+            Rlog.i(TAG, "Skipping update of allowed network types. Restriction no_cellular_2g "
+                    + "unchanged: " + mDisallowCellular2gRestriction);
+        }
+    }
+
+    /**
+     * Returns the current state of the {@link UserManager#DISALLOW_CELLULAR_2G} user restriction.
+     */
+    public boolean isCellular2gDisabled() {
+        return mDisallowCellular2gRestriction;
+    }
+
+    /**
+     * Tries to resolve the user manager system service. Returns true if successful, false
+     * otherwise.
+     */
+    private boolean ensureUserManagerExists() {
+        if (mUserManager == null) {
+            Rlog.d(TAG, "No user manager. Attempting to resolve one.");
+            mUserManager = mContext.getSystemService(UserManager.class);
+        }
+        if (mUserManager == null) {
+            Rlog.e(TAG,
+                    "Could not get a user manager instance. All operations will be no-ops until "
+                            + "one is resolved");
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 08c02e2..f7f24a2 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -41,6 +41,7 @@
 import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
+import com.android.internal.telephony.imsphone.ImsNrSaModeHandler;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
 import com.android.internal.telephony.nitz.NitzStateMachineImpl;
@@ -386,6 +387,14 @@
     }
 
     /**
+     * Create an ImsNrSaModeHandler.
+     */
+    public ImsNrSaModeHandler makeImsNrSaModeHandler(ImsPhone imsPhone) {
+
+        return new ImsNrSaModeHandler(imsPhone, imsPhone.getLooper());
+    }
+
+    /**
      * Create an AppSmsManager for per-app SMS message.
      */
     public AppSmsManager makeAppSmsManager(Context context) {
@@ -425,10 +434,6 @@
                 telephonyComponentFactory);
     }
 
-    public SubscriptionController initSubscriptionController(Context c) {
-        return SubscriptionController.init(c);
-    }
-
     public PhoneSwitcher makePhoneSwitcher(int maxDataAttachModemCount, Context context,
             Looper looper) {
         return PhoneSwitcher.make(maxDataAttachModemCount, context, looper);
@@ -441,9 +446,14 @@
         return new DisplayInfoController(phone);
     }
 
-    public MultiSimSettingController initMultiSimSettingController(Context c,
-            SubscriptionController sc) {
-        return MultiSimSettingController.init(c, sc);
+    /**
+     * Initialize multi sim settings controller.
+     *
+     * @param c The context.
+     * @return The multi sim settings controller instance.
+     */
+    public MultiSimSettingController initMultiSimSettingController(Context c) {
+        return MultiSimSettingController.init(c);
     }
 
     /**
@@ -453,11 +463,6 @@
         return new SignalStrengthController(phone);
     }
 
-    public SubscriptionInfoUpdater makeSubscriptionInfoUpdater(Looper looper, Context context,
-            SubscriptionController sc) {
-        return new SubscriptionInfoUpdater(looper, context, sc);
-    }
-
     /**
      * Create a new LinkBandwidthEstimator.
      */
diff --git a/src/java/com/android/internal/telephony/TelephonyTester.java b/src/java/com/android/internal/telephony/TelephonyTester.java
index c81a4c3..b9e04c8 100644
--- a/src/java/com/android/internal/telephony/TelephonyTester.java
+++ b/src/java/com/android/internal/telephony/TelephonyTester.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.annotation.NonNull;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -200,11 +201,7 @@
                     sendTestSuppServiceNotification(intent);
                 } else if (action.equals(ACTION_TEST_SERVICE_STATE)) {
                     log("handle test service state changed intent");
-                    // Trigger the service state update. The replacement will be done in
-                    // overrideServiceState().
-                    mServiceStateTestIntent = intent;
-                    mPhone.getServiceStateTracker().sendEmptyMessage(
-                            ServiceStateTracker.EVENT_NETWORK_STATE_CHANGED);
+                    setServiceStateTestIntent(intent);
                 } else if (action.equals(ACTION_TEST_IMS_E_CALL)) {
                     log("handle test IMS ecall intent");
                     testImsECall();
@@ -388,6 +385,19 @@
         }
     }
 
+    /**
+     * Set the service state test intent.
+     *
+     * @param intent The service state test intent.
+     */
+    public void setServiceStateTestIntent(@NonNull Intent intent) {
+        mServiceStateTestIntent = intent;
+        // Trigger the service state update. The replacement will be done in
+        // overrideServiceState().
+        mPhone.getServiceStateTracker().sendEmptyMessage(
+                ServiceStateTracker.EVENT_NETWORK_STATE_CHANGED);
+    }
+
     void overrideServiceState(ServiceState ss) {
         if (mServiceStateTestIntent == null || ss == null) return;
         if (mPhone.getPhoneId() != mServiceStateTestIntent.getIntExtra(
@@ -401,13 +411,36 @@
         }
 
         if (mServiceStateTestIntent.hasExtra(EXTRA_VOICE_REG_STATE)) {
+            int state = mServiceStateTestIntent.getIntExtra(EXTRA_DATA_REG_STATE,
+                    ServiceState.STATE_OUT_OF_SERVICE);
             ss.setVoiceRegState(mServiceStateTestIntent.getIntExtra(EXTRA_VOICE_REG_STATE,
                     ServiceState.STATE_OUT_OF_SERVICE));
+            NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+            NetworkRegistrationInfo.Builder builder = new NetworkRegistrationInfo.Builder(nri);
+            if (state == ServiceState.STATE_IN_SERVICE) {
+                builder.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+            } else {
+                builder.setRegistrationState(
+                        NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+            }
+            ss.addNetworkRegistrationInfo(builder.build());
             log("Override voice service state with " + ss.getState());
         }
         if (mServiceStateTestIntent.hasExtra(EXTRA_DATA_REG_STATE)) {
-            ss.setDataRegState(mServiceStateTestIntent.getIntExtra(EXTRA_DATA_REG_STATE,
-                    ServiceState.STATE_OUT_OF_SERVICE));
+            int state = mServiceStateTestIntent.getIntExtra(EXTRA_DATA_REG_STATE,
+                    ServiceState.STATE_OUT_OF_SERVICE);
+            ss.setDataRegState(state);
+            NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+            NetworkRegistrationInfo.Builder builder = new NetworkRegistrationInfo.Builder(nri);
+            if (state == ServiceState.STATE_IN_SERVICE) {
+                builder.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+            } else {
+                builder.setRegistrationState(
+                        NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+            }
+            ss.addNetworkRegistrationInfo(builder.build());
             log("Override data service state with " + ss.getDataRegistrationState());
         }
         if (mServiceStateTestIntent.hasExtra(EXTRA_OPERATOR)) {
diff --git a/src/java/com/android/internal/telephony/UiccPhoneBookController.java b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
index 8b8457c..96fd208 100644
--- a/src/java/com/android/internal/telephony/UiccPhoneBookController.java
+++ b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
@@ -147,12 +147,7 @@
     private IccPhoneBookInterfaceManager
             getIccPhoneBookInterfaceManager(int subId) {
 
-        int phoneId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            phoneId = SubscriptionManagerService.getInstance().getPhoneId(subId);
-        } else {
-            phoneId = SubscriptionController.getInstance().getPhoneId(subId);
-        }
+        int phoneId = SubscriptionManagerService.getInstance().getPhoneId(subId);
         try {
             return PhoneFactory.getPhone(phoneId).getIccPhoneBookInterfaceManager();
         } catch (NullPointerException e) {
diff --git a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
index 0b10651..e374811 100644
--- a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
+++ b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
@@ -21,6 +21,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.UserHandle;
 import android.provider.VoicemailContract;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.PhoneNumberUtils;
@@ -60,7 +61,7 @@
         /**
          * Convert the subId to a {@link PhoneAccountHandle}
          */
-        PhoneAccountHandle fromSubId(int subId);
+        PhoneAccountHandle fromSubId(int subId, Context context);
     }
 
     private static final String TAG = "VvmSmsFilter";
@@ -77,7 +78,7 @@
             new PhoneAccountHandleConverter() {
 
                 @Override
-                public PhoneAccountHandle fromSubId(int subId) {
+                public PhoneAccountHandle fromSubId(int subId, Context context) {
                     if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                         return null;
                     }
@@ -85,6 +86,15 @@
                     if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
                         return null;
                     }
+                    SubscriptionManager subscriptionManager =
+                            (SubscriptionManager) context.getSystemService(
+                                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+                    UserHandle userHandle = subscriptionManager.getSubscriptionUserHandle(subId);
+                    if (userHandle != null) {
+                        return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
+                            Integer.toString(PhoneFactory.getPhone(phoneId).getSubId()),
+                            userHandle);
+                    }
                     return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
                             Integer.toString(PhoneFactory.getPhone(phoneId).getSubId()));
                 }
@@ -138,7 +148,8 @@
             return false;
         }
 
-        PhoneAccountHandle phoneAccountHandle = sPhoneAccountHandleConverter.fromSubId(subId);
+        PhoneAccountHandle phoneAccountHandle = sPhoneAccountHandleConverter.fromSubId(subId,
+                context);
 
         if (phoneAccountHandle == null) {
             Log.e(TAG, "Unable to convert subId " + subId + " to PhoneAccountHandle");
diff --git a/src/java/com/android/internal/telephony/VoiceIndication.java b/src/java/com/android/internal/telephony/VoiceIndication.java
index 984d2a0..9720bb7 100644
--- a/src/java/com/android/internal/telephony/VoiceIndication.java
+++ b/src/java/com/android/internal/telephony/VoiceIndication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
+
 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;
@@ -63,7 +65,7 @@
      */
     public void callRing(int indicationType, boolean isGsm,
             android.hardware.radio.voice.CdmaSignalInfoRecord record) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         char[] response = null;
 
@@ -90,7 +92,7 @@
      * @param indicationType Type of radio indication
      */
     public void callStateChanged(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
 
@@ -104,7 +106,7 @@
      */
     public void cdmaCallWaiting(int indicationType,
             android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         // TODO: create a CdmaCallWaitingNotification constructor that takes in these fields to make
         // sure no fields are missing
@@ -134,7 +136,7 @@
      */
     public void cdmaInfoRec(int indicationType,
             android.hardware.radio.voice.CdmaInformationRecord[] records) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         for (int i = 0; i < records.length; i++) {
             android.hardware.radio.voice.CdmaInformationRecord record = records[i];
@@ -233,7 +235,7 @@
      * @param status CDMA OTA provision status
      */
     public void cdmaOtaProvisionStatus(int indicationType, int status) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         int[] response = new int[] {status};
 
@@ -252,7 +254,7 @@
      */
     public void currentEmergencyNumberList(int indicationType,
             android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.length);
         for (android.hardware.radio.voice.EmergencyNumber enHal : emergencyNumberList) {
@@ -279,7 +281,7 @@
      * @param indicationType Type of radio indication
      */
     public void enterEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
 
@@ -294,7 +296,7 @@
      * @param indicationType Type of radio indication
      */
     public void exitEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
 
@@ -307,7 +309,7 @@
      * @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);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
 
@@ -322,7 +324,7 @@
      */
     public void onSupplementaryServiceIndication(int indicationType,
             android.hardware.radio.voice.StkCcUnsolSsResult ss) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         int num;
         SsData ssData = new SsData();
@@ -374,7 +376,7 @@
      * @param msg Message string in UTF-8, if applicable
      */
     public void onUssd(int indicationType, int ussdModeType, String msg) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
 
@@ -390,7 +392,7 @@
      * @param indicationType Type of radio indication
      */
     public void resendIncallMute(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
 
@@ -403,7 +405,7 @@
      * @param state New SRVCC State
      */
     public void srvccStateNotify(int indicationType, int state) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         int[] response = new int[] {state};
 
@@ -419,7 +421,7 @@
      * @param alpha ALPHA string from UICC in UTF-8 format
      */
     public void stkCallControlAlphaNotify(int indicationType, String alpha) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
 
@@ -434,7 +436,7 @@
      * @param timeout Timeout value in milliseconds for setting up voice call
      */
     public void stkCallSetup(int indicationType, long timeout) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
+        mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
 
         if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
 
diff --git a/src/java/com/android/internal/telephony/VoiceResponse.java b/src/java/com/android/internal/telephony/VoiceResponse.java
index b1ba9d9..d1e060e 100644
--- a/src/java/com/android/internal/telephony/VoiceResponse.java
+++ b/src/java/com/android/internal/telephony/VoiceResponse.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
+
 import android.hardware.radio.RadioError;
 import android.hardware.radio.RadioResponseInfo;
 import android.hardware.radio.voice.IRadioVoiceResponse;
@@ -47,49 +49,49 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void acceptCallResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, mRil, responseInfo);
     }
 
     /**
@@ -99,7 +101,7 @@
      */
     public void getCallForwardStatusResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.voice.CallForwardInfo[] callForwardInfos) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_VOICE, responseInfo);
         if (rr != null) {
             CallForwardInfo[] ret = new CallForwardInfo[callForwardInfos.length];
             for (int i = 0; i < callForwardInfos.length; i++) {
@@ -129,7 +131,7 @@
     public void getCallWaitingResponse(RadioResponseInfo responseInfo, boolean enable,
             int serviceClass) {
         RadioResponse.responseInts(
-                RIL.VOICE_SERVICE, mRil, responseInfo, enable ? 1 : 0, serviceClass);
+                HAL_SERVICE_VOICE, mRil, responseInfo, enable ? 1 : 0, serviceClass);
     }
 
     /**
@@ -137,7 +139,7 @@
      * @param status indicates CLIP status
      */
     public void getClipResponse(RadioResponseInfo responseInfo, int status) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, status);
+        RadioResponse.responseInts(HAL_SERVICE_VOICE, mRil, responseInfo, status);
     }
 
     /**
@@ -146,7 +148,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);
+        RadioResponse.responseInts(HAL_SERVICE_VOICE, mRil, responseInfo, n, m);
     }
 
     /**
@@ -155,7 +157,7 @@
      */
     public void getCurrentCallsResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.voice.Call[] calls) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_VOICE, responseInfo);
 
         if (rr != null) {
             int num = calls.length;
@@ -198,7 +200,7 @@
      */
     public void getLastCallFailCauseResponse(RadioResponseInfo responseInfo,
             android.hardware.radio.voice.LastCallFailCauseInfo fcInfo) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_VOICE, responseInfo);
 
         if (rr != null) {
             LastCallFailCause ret = new LastCallFailCause();
@@ -216,7 +218,7 @@
      * @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);
+        RadioResponse.responseInts(HAL_SERVICE_VOICE, mRil, responseInfo, enable ? 1 : 0);
     }
 
     /**
@@ -225,7 +227,7 @@
      *        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);
+        RadioResponse.responseInts(HAL_SERVICE_VOICE, mRil, responseInfo, enable ? 1 : 0);
     }
 
     /**
@@ -233,35 +235,35 @@
      * @param mode TTY mode
      */
     public void getTtyModeResponse(RadioResponseInfo responseInfo, int mode) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, mode);
+        RadioResponse.responseInts(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, mRil, responseInfo);
     }
 
     /**
@@ -269,7 +271,7 @@
      * @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);
+        RILRequest rr = mRil.processResponse(HAL_SERVICE_VOICE, responseInfo);
 
         if (rr != null) {
             if (responseInfo.error == RadioError.NONE) {
@@ -283,112 +285,112 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void rejectCallResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, 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);
+        RadioResponse.responseVoid(HAL_SERVICE_VOICE, mRil, responseInfo);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
old mode 100755
new mode 100644
index 08c7acd..d6ea4ad
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -46,6 +46,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 import com.google.android.mms.pdu.GenericPdu;
@@ -392,7 +393,10 @@
 
         // Direct the intent to only the default MMS app. If we can't find a default MMS app
         // then sent it to all broadcast receivers.
-        ComponentName componentName = SmsApplication.getDefaultMmsApplication(mContext, true);
+        UserHandle userHandle = TelephonyUtils.getSubscriptionUserHandle(mContext, subId);
+        ComponentName componentName = SmsApplication.getDefaultMmsApplicationAsUser(mContext,
+                true, userHandle);
+
         Bundle options = null;
         if (componentName != null) {
             // Deliver MMS message only to this receiver
@@ -410,9 +414,12 @@
             options = bopts.toBundle();
         }
 
+        if (userHandle == null) {
+            userHandle = UserHandle.SYSTEM;
+        }
         handler.dispatchIntent(intent, getPermissionForType(result.mimeType),
                 getAppOpsStringPermissionForIntent(result.mimeType), options, receiver,
-                UserHandle.SYSTEM, subId);
+                userHandle, subId);
         return Activity.RESULT_OK;
     }
 
diff --git a/src/java/com/android/internal/telephony/WspTypeDecoder.java b/src/java/com/android/internal/telephony/WspTypeDecoder.java
old mode 100755
new mode 100644
diff --git a/src/java/com/android/internal/telephony/cat/AppInterface.java b/src/java/com/android/internal/telephony/cat/AppInterface.java
old mode 100755
new mode 100644
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 3d21270..4447c07 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -40,6 +40,7 @@
     private ToneSettings mToneSettings = null;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private CallSettings mCallSettings = null;
+    private SMSSettings mSMSSettings =  null;
     private SetupEventListSettings mSetupEventListSettings = null;
     private boolean mLoadIconFailed = false;
 
@@ -61,6 +62,14 @@
         public TextMessage callMsg;
     }
 
+    /**
+     * Container for SEND SMS  command settings.
+     */
+    public class SMSSettings {
+        public TextMessage smsText;
+        public TextMessage destAddr;
+    }
+
     public class SetupEventListSettings {
         @UnsupportedAppUsage
         public int[] eventList;
@@ -84,57 +93,69 @@
         mCmdDet = cmdParams.mCmdDet;
         mLoadIconFailed =  cmdParams.mLoadIconFailed;
         switch(getCmdType()) {
-        case SET_UP_MENU:
-        case SELECT_ITEM:
-            mMenu = ((SelectItemParams) cmdParams).mMenu;
-            break;
-        case DISPLAY_TEXT:
-        case SET_UP_IDLE_MODE_TEXT:
-        case SEND_DTMF:
-        case SEND_SMS:
-        case REFRESH:
-        case RUN_AT:
-        case SEND_SS:
-        case SEND_USSD:
-            mTextMsg = ((DisplayTextParams) cmdParams).mTextMsg;
-            break;
-        case GET_INPUT:
-        case GET_INKEY:
-            mInput = ((GetInputParams) cmdParams).mInput;
-            break;
-        case LAUNCH_BROWSER:
-            mTextMsg = ((LaunchBrowserParams) cmdParams).mConfirmMsg;
-            mBrowserSettings = new BrowserSettings();
-            mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).mUrl;
-            mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mMode;
-            break;
-        case PLAY_TONE:
-            PlayToneParams params = (PlayToneParams) cmdParams;
-            mToneSettings = params.mSettings;
-            mTextMsg = params.mTextMsg;
-            break;
-        case GET_CHANNEL_STATUS:
-            mTextMsg = ((CallSetupParams) cmdParams).mConfirmMsg;
-            break;
-        case SET_UP_CALL:
-            mCallSettings = new CallSettings();
-            mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).mConfirmMsg;
-            mCallSettings.callMsg = ((CallSetupParams) cmdParams).mCallMsg;
-            break;
-        case OPEN_CHANNEL:
-        case CLOSE_CHANNEL:
-        case RECEIVE_DATA:
-        case SEND_DATA:
-            BIPClientParams param = (BIPClientParams) cmdParams;
-            mTextMsg = param.mTextMsg;
-            break;
-        case SET_UP_EVENT_LIST:
-            mSetupEventListSettings = new SetupEventListSettings();
-            mSetupEventListSettings.eventList = ((SetEventListParams) cmdParams).mEventInfo;
-            break;
-        case PROVIDE_LOCAL_INFORMATION:
-        default:
-            break;
+            case SET_UP_MENU:
+            case SELECT_ITEM:
+                mMenu = ((SelectItemParams) cmdParams).mMenu;
+                break;
+            case SEND_SMS:
+                /* If cmdParams  is an instanceof SendSMSParams , then it means config value
+                 * config_stk_sms_send_support is true and the SMS should be sent by framework
+                 */
+                if (cmdParams instanceof SendSMSParams) {
+                    mSMSSettings = new SMSSettings();
+                    mSMSSettings.smsText = ((SendSMSParams) cmdParams).mTextSmsMsg;
+                    mSMSSettings.destAddr = ((SendSMSParams) cmdParams).mDestAddress;
+                    mTextMsg = ((SendSMSParams) cmdParams).mDisplayText.mTextMsg;
+                } else {
+                    mTextMsg = ((DisplayTextParams) cmdParams).mTextMsg;
+                }
+                break;
+            case DISPLAY_TEXT:
+            case SET_UP_IDLE_MODE_TEXT:
+            case SEND_DTMF:
+            case REFRESH:
+            case RUN_AT:
+            case SEND_SS:
+            case SEND_USSD:
+                mTextMsg = ((DisplayTextParams) cmdParams).mTextMsg;
+                break;
+            case GET_INPUT:
+            case GET_INKEY:
+                mInput = ((GetInputParams) cmdParams).mInput;
+                break;
+            case LAUNCH_BROWSER:
+                mTextMsg = ((LaunchBrowserParams) cmdParams).mConfirmMsg;
+                mBrowserSettings = new BrowserSettings();
+                mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).mUrl;
+                mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mMode;
+                break;
+            case PLAY_TONE:
+                PlayToneParams params = (PlayToneParams) cmdParams;
+                mToneSettings = params.mSettings;
+                mTextMsg = params.mTextMsg;
+                break;
+            case GET_CHANNEL_STATUS:
+                mTextMsg = ((CallSetupParams) cmdParams).mConfirmMsg;
+                break;
+            case SET_UP_CALL:
+                mCallSettings = new CallSettings();
+                mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).mConfirmMsg;
+                mCallSettings.callMsg = ((CallSetupParams) cmdParams).mCallMsg;
+                break;
+            case OPEN_CHANNEL:
+            case CLOSE_CHANNEL:
+            case RECEIVE_DATA:
+            case SEND_DATA:
+                BIPClientParams param = (BIPClientParams) cmdParams;
+                mTextMsg = param.mTextMsg;
+                break;
+            case SET_UP_EVENT_LIST:
+                mSetupEventListSettings = new SetupEventListSettings();
+                mSetupEventListSettings.eventList = ((SetEventListParams) cmdParams).mEventInfo;
+                break;
+            case PROVIDE_LOCAL_INFORMATION:
+            default:
+                break;
         }
     }
 
@@ -145,29 +166,34 @@
         mInput = in.readParcelable(Input.class.getClassLoader());
         mLoadIconFailed = (in.readByte() == 1);
         switch (getCmdType()) {
-        case LAUNCH_BROWSER:
-            mBrowserSettings = new BrowserSettings();
-            mBrowserSettings.url = in.readString();
-            mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()];
-            break;
-        case PLAY_TONE:
-            mToneSettings = in.readParcelable(ToneSettings.class.getClassLoader());
-            break;
-        case SET_UP_CALL:
-            mCallSettings = new CallSettings();
-            mCallSettings.confirmMsg = in.readParcelable(TextMessage.class.getClassLoader());
-            mCallSettings.callMsg = in.readParcelable(TextMessage.class.getClassLoader());
-            break;
-        case SET_UP_EVENT_LIST:
-            mSetupEventListSettings = new SetupEventListSettings();
-            int length = in.readInt();
-            mSetupEventListSettings.eventList = new int[length];
-            for (int i = 0; i < length; i++) {
-                mSetupEventListSettings.eventList[i] = in.readInt();
-            }
-            break;
-        default:
-            break;
+            case LAUNCH_BROWSER:
+                mBrowserSettings = new BrowserSettings();
+                mBrowserSettings.url = in.readString();
+                mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()];
+                break;
+            case PLAY_TONE:
+                mToneSettings = in.readParcelable(ToneSettings.class.getClassLoader());
+                break;
+            case SET_UP_CALL:
+                mCallSettings = new CallSettings();
+                mCallSettings.confirmMsg = in.readParcelable(TextMessage.class.getClassLoader());
+                mCallSettings.callMsg = in.readParcelable(TextMessage.class.getClassLoader());
+                break;
+            case SET_UP_EVENT_LIST:
+                mSetupEventListSettings = new SetupEventListSettings();
+                int length = in.readInt();
+                mSetupEventListSettings.eventList = new int[length];
+                for (int i = 0; i < length; i++) {
+                    mSetupEventListSettings.eventList[i] = in.readInt();
+                }
+                break;
+            case SEND_SMS:
+                mSMSSettings = new SMSSettings();
+                mSMSSettings.smsText = in.readParcelable(SendSMSParams.class.getClassLoader());
+                mSMSSettings.destAddr = in.readParcelable(SendSMSParams.class.getClassLoader());
+                break;
+            default:
+                break;
         }
     }
 
@@ -178,23 +204,29 @@
         dest.writeParcelable(mMenu, 0);
         dest.writeParcelable(mInput, 0);
         dest.writeByte((byte) (mLoadIconFailed ? 1 : 0));
-        switch(getCmdType()) {
-        case LAUNCH_BROWSER:
-            dest.writeString(mBrowserSettings.url);
-            dest.writeInt(mBrowserSettings.mode.ordinal());
-            break;
-        case PLAY_TONE:
-            dest.writeParcelable(mToneSettings, 0);
-            break;
-        case SET_UP_CALL:
-            dest.writeParcelable(mCallSettings.confirmMsg, 0);
-            dest.writeParcelable(mCallSettings.callMsg, 0);
-            break;
-        case SET_UP_EVENT_LIST:
-            dest.writeIntArray(mSetupEventListSettings.eventList);
-            break;
-        default:
-            break;
+        switch (getCmdType()) {
+            case LAUNCH_BROWSER:
+                dest.writeString(mBrowserSettings.url);
+                dest.writeInt(mBrowserSettings.mode.ordinal());
+                break;
+            case PLAY_TONE:
+                dest.writeParcelable(mToneSettings, 0);
+                break;
+            case SET_UP_CALL:
+                dest.writeParcelable(mCallSettings.confirmMsg, 0);
+                dest.writeParcelable(mCallSettings.callMsg, 0);
+                break;
+            case SET_UP_EVENT_LIST:
+                dest.writeIntArray(mSetupEventListSettings.eventList);
+                break;
+            case SEND_SMS:
+                if (mSMSSettings != null) {
+                    dest.writeParcelable(mSMSSettings.smsText, 0);
+                    dest.writeParcelable(mSMSSettings.destAddr, 0);
+                }
+                break;
+            default:
+                break;
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index 4798a97..fa2b19b 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -20,26 +20,35 @@
 import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
 import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.USER_ACTIVITY_EVENT;
 
+import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.PendingIntent;
 import android.app.backup.BackupManager;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources.NotFoundException;
 import android.os.AsyncResult;
 import android.os.Build;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.LocaleList;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.ProxyController;
+import com.android.internal.telephony.SmsController;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.IccFileHandler;
@@ -140,12 +149,21 @@
 
     static final String STK_DEFAULT = "Default Message";
 
+    private static final String SMS_DELIVERY_ACTION =
+            "com.android.internal.telephony.cat.SMS_DELIVERY_ACTION";
+    private static final String SMS_SENT_ACTION =
+            "com.android.internal.telephony.cat.SMS_SENT_ACTION";
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private int mSlotId;
+    private static HandlerThread sCatServiceThread;
 
     /* For multisim catservice should not be singleton */
     private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir,
-            Context context, IccFileHandler fh, UiccProfile uiccProfile, int slotId) {
+            Context context, IccFileHandler fh, UiccProfile uiccProfile, int slotId,
+            Looper looper) {
+        //creating new thread to avoid deadlock conditions with the framework thread.
+        super(looper);
         if (ci == null || ca == null || ir == null || context == null || fh == null
                 || uiccProfile == null) {
             throw new NullPointerException(
@@ -189,6 +207,9 @@
 
         CatLog.d(this, "Running CAT service on Slotid: " + mSlotId +
                 ". STK app installed:" + mStkAppInstalled);
+
+        mContext.registerReceiver(mSmsBroadcastReceiver, new IntentFilter(SMS_DELIVERY_ACTION));
+        mContext.registerReceiver(mSmsBroadcastReceiver, new IntentFilter(SMS_SENT_ACTION));
     }
 
     /**
@@ -202,6 +223,10 @@
      */
     public static CatService getInstance(CommandsInterface ci,
             Context context, UiccProfile uiccProfile, int slotId) {
+        if (sCatServiceThread == null) {
+            sCatServiceThread = new HandlerThread("CatServiceThread");
+            sCatServiceThread.start();
+        }
         UiccCardApplication ca = null;
         IccFileHandler fh = null;
         IccRecords ir = null;
@@ -229,8 +254,8 @@
                         || uiccProfile == null) {
                     return null;
                 }
-
-                sInstance[slotId] = new CatService(ci, ca, ir, context, fh, uiccProfile, slotId);
+                sInstance[slotId] = new CatService(ci, ca, ir, context, fh, uiccProfile, slotId,
+                        sCatServiceThread.getLooper());
             } else if ((ir != null) && (mIccRecords != ir)) {
                 if (mIccRecords != null) {
                     mIccRecords.unregisterForRecordsLoaded(sInstance[slotId]);
@@ -449,8 +474,49 @@
                     ((DisplayTextParams)cmdParams).mTextMsg.text = null;
                 }
                 break;
-            case SEND_DTMF:
             case SEND_SMS:
+                /* If cmdParams  is an instanceof SendSMSParams , then it means config value
+                 * config_stk_sms_send_support is true and the SMS should be sent by framework
+                 */
+                if (cmdParams instanceof SendSMSParams) {
+                    String text = null, destAddr = null;
+                    if (((SendSMSParams) cmdParams).mTextSmsMsg != null) {
+                        text = ((SendSMSParams) cmdParams).mTextSmsMsg.text;
+                    }
+                    if (((SendSMSParams) cmdParams).mDestAddress != null) {
+                        destAddr = ((SendSMSParams) cmdParams).mDestAddress.text;
+                    }
+                    if (text != null && destAddr != null) {
+                        ProxyController proxyController = ProxyController.getInstance(mContext);
+                        SubscriptionManager subscriptionManager = (SubscriptionManager)
+                                mContext.getSystemService(
+                                        Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+                        SubscriptionInfo subInfo =
+                                subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(
+                                        mSlotId);
+                        if (subInfo != null) {
+                            sendStkSms(text, destAddr, subInfo.getSubscriptionId(), cmdParams,
+                                    proxyController);
+                        } else {
+                            sendTerminalResponse(cmdParams.mCmdDet,
+                                    ResultCode.CMD_DATA_NOT_UNDERSTOOD, false, 0x00, null);
+                            CatLog.d(this, "Subscription info is null");
+                        }
+                    } else {
+                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
+                                false, 0x00, null);
+                        CatLog.d(this, "Sms text or Destination Address is null");
+                    }
+                } else {
+                    if ((((DisplayTextParams) cmdParams).mTextMsg.text != null)
+                            && (((DisplayTextParams) cmdParams).mTextMsg.text.equals(
+                            STK_DEFAULT))) {
+                        message = mContext.getText(com.android.internal.R.string.sending);
+                        ((DisplayTextParams) cmdParams).mTextMsg.text = message.toString();
+                    }
+                }
+                break;
+            case SEND_DTMF:
             case SEND_SS:
             case SEND_USSD:
                 if ((((DisplayTextParams)cmdParams).mTextMsg.text != null)
@@ -538,6 +604,94 @@
         broadcastCatCmdIntent(cmdMsg);
     }
 
+    /**
+     * Used to send STK based sms via CATService
+     * @param text The message body
+     * @param destAddr The destination Address
+     * @param subId Subscription Id
+     * @param cmdParams Send SMS Command Params
+     * @param proxyController ProxyController
+     * @hide
+     */
+    public void sendStkSms(String text, String destAddr, int subId, CommandParams cmdParams,
+            ProxyController proxyController) {
+        PendingIntent sentPendingIntent = PendingIntent.getBroadcast(mContext, 0,
+                new Intent(SMS_SENT_ACTION)
+                        .putExtra("cmdDetails", cmdParams.mCmdDet)
+                        .setPackage(mContext.getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
+        PendingIntent deliveryPendingIntent = PendingIntent.getBroadcast(mContext, 0,
+                new Intent(SMS_DELIVERY_ACTION)
+                        .putExtra("cmdDetails", cmdParams.mCmdDet)
+                        .setPackage(mContext.getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
+        SmsController smsController = proxyController.getSmsController();
+        smsController.sendTextForSubscriber(subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), destAddr, null, text, sentPendingIntent,
+                deliveryPendingIntent, false, 0L, true, true);
+    }
+
+    /**
+     * BroadcastReceiver class to handle error and success cases of
+     * SEND and DELIVERY pending intents used for sending of STK SMS
+     */
+    @VisibleForTesting
+    public final BroadcastReceiver mSmsBroadcastReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            CommandDetails commandDetails = (CommandDetails) intent.getExtra("cmdDetails");
+            if (intent.getAction().equals(SMS_SENT_ACTION)) {
+                int resultCode = getResultCode();
+                ResultCode terminalResponseResultCode = ResultCode.NETWORK_CRNTLY_UNABLE_TO_PROCESS;
+                CatLog.d(this, "STK SMS errorCode : " + resultCode);
+                int additionalInfo = 0;
+                if (resultCode != Activity.RESULT_OK) {
+                    /**
+                     * The Terminal Response Result code is assigned as per Section 12.12.3
+                     * and 12.12.5 TS 101.267. The Result code SMS_RP_ERROR is added in Ims Case
+                     * and additional information is added as per RP-Cause Values in TS 124.011.
+                     * The Result code NETWORK_CRNTLY_UNABLE_TO_PROCESS is added in non-Ims Case
+                     * and additional information added as per cause values in TS 04.08.
+                     */
+                    if (intent.hasExtra("ims") && intent.getBooleanExtra("ims", false)) {
+                        terminalResponseResultCode = ResultCode.SMS_RP_ERROR;
+                        //Additional information's 8th bit is 0 as per section 12.12.5 of TS 101.267
+                        if (intent.hasExtra("errorCode")) {
+                            additionalInfo = (int) intent.getExtra("errorCode");
+                            if ((additionalInfo & 0x80) != 0) additionalInfo = 0;
+                        }
+                    } else {
+                        //Additional information's 8th bit is 1 as per section 12.12.3 of TS 101.267
+                        if (intent.hasExtra("errorCode")) {
+                            additionalInfo = (int) intent.getExtra("errorCode");
+                            additionalInfo |= 0x80;
+                        }
+                    }
+                    CatLog.d(this, "Error delivering STK SMS errorCode : " + additionalInfo
+                            + " terminalResponseResultCode = " + terminalResponseResultCode);
+                    sendTerminalResponse(commandDetails, terminalResponseResultCode,
+                            true, additionalInfo, null);
+                } else {
+                    CatLog.d(this, " STK SMS sent successfully ");
+                }
+            }
+            if (intent.getAction().equals(SMS_DELIVERY_ACTION)) {
+                int resultCode = getResultCode();
+                switch (resultCode) {
+                    case Activity.RESULT_OK:
+                        sendTerminalResponse(commandDetails, ResultCode.OK, false, 0, null);
+                        CatLog.d(this, " STK SMS delivered successfully ");
+                        break;
+                    default:
+                        CatLog.d(this, "Error delivering STK SMS : " + resultCode);
+                        sendTerminalResponse(commandDetails,
+                                ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS, false,
+                                0, null);
+                }
+            }
+        }
+    };
 
     private void broadcastCatCmdIntent(CatCmdMessage cmdMsg) {
         Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
@@ -810,16 +964,9 @@
     //TODO Need to take care for MSIM
     public static AppInterface getInstance() {
         int slotId = PhoneConstants.DEFAULT_SLOT_INDEX;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            if (SubscriptionManagerService.getInstance() != null) {
-                slotId = SubscriptionManagerService.getInstance().getSlotIndex(
-                        SubscriptionManagerService.getInstance().getDefaultSubId());
-            }
-        } else {
-            SubscriptionController sControl = SubscriptionController.getInstance();
-            if (sControl != null) {
-                slotId = sControl.getSlotIndex(sControl.getDefaultSubId());
-            }
+        if (SubscriptionManagerService.getInstance() != null) {
+            slotId = SubscriptionManagerService.getInstance().getSlotIndex(
+                    SubscriptionManagerService.getInstance().getDefaultSubId());
         }
         return getInstance(null, null, null, slotId);
     }
@@ -854,7 +1001,11 @@
                     }
                 }
             }
-            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
+            if (mMsgDecoder != null) {
+                mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
+            } else {
+                CatLog.e(this, "Error in handleMessage (" + msg.what + ") mMsgDecoder is NULL");
+            }
             break;
         case MSG_ID_CALL_SETUP:
             mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
diff --git a/src/java/com/android/internal/telephony/cat/CommandParams.java b/src/java/com/android/internal/telephony/cat/CommandParams.java
old mode 100755
new mode 100644
index b9de4d1..8530ee2
--- a/src/java/com/android/internal/telephony/cat/CommandParams.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParams.java
@@ -22,16 +22,16 @@
 
 /**
  * Container class for proactive command parameters.
- *
+ * @hide
  */
-class CommandParams {
+public class CommandParams {
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     CommandDetails mCmdDet;
     // Variable to track if an optional icon load has failed.
     boolean mLoadIconFailed = false;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    CommandParams(CommandDetails cmdDet) {
+    public CommandParams(CommandDetails cmdDet) {
         mCmdDet = cmdDet;
     }
 
diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index 7fbebfa..65f3c4a 100644
--- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -29,6 +29,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
+import android.telephony.SmsMessage;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.GsmAlphabet;
@@ -40,9 +41,9 @@
 /**
  * Factory class, used for decoding raw byte arrays, received from baseband,
  * into a CommandParams object.
- *
+ * @hide
  */
-class CommandParamsFactory extends Handler {
+public class CommandParamsFactory extends Handler {
     private static CommandParamsFactory sInstance = null;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private IconLoader mIconLoader;
@@ -53,6 +54,7 @@
     private String mSavedLanguage;
     private String mRequestedLanguage;
     private boolean mNoAlphaUsrCnf = false;
+    private boolean mStkSmsSendViaTelephony = false;
 
     // constants
     static final int MSG_ID_LOAD_ICON_DONE = 1;
@@ -86,7 +88,15 @@
     private static final int MAX_GSM7_DEFAULT_CHARS = 239;
     private static final int MAX_UCS2_CHARS = 118;
 
-    static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
+    /**
+     * Returns a singleton instance of CommandParamsFactory
+     * @param caller Class used for queuing raw ril messages, decoding them into
+     *               CommandParams objects and sending the result back to the CAT Service.
+     * @param fh IccFileHandler Object
+     * @param context The Context
+     * @return CommandParamsFactory instance
+     */
+    public static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
             IccFileHandler fh, Context context) {
         if (sInstance != null) {
             return sInstance;
@@ -106,6 +116,12 @@
         } catch (NotFoundException e) {
             mNoAlphaUsrCnf = false;
         }
+        try {
+            mStkSmsSendViaTelephony = context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_stk_sms_send_support);
+        } catch (NotFoundException e) {
+            mStkSmsSendViaTelephony = false;
+        }
     }
 
     private CommandDetails processCommandDetails(List<ComprehensionTlv> ctlvs) {
@@ -187,8 +203,14 @@
                 case GET_INPUT:
                     cmdPending = processGetInput(cmdDet, ctlvs);
                     break;
-                case SEND_DTMF:
                 case SEND_SMS:
+                    if (mStkSmsSendViaTelephony) {
+                        cmdPending = processSMSEventNotify(cmdDet, ctlvs);
+                    } else {
+                        cmdPending = processEventNotify(cmdDet, ctlvs);
+                    }
+                    break;
+                case SEND_DTMF:
                 case REFRESH:
                 case RUN_AT:
                 case SEND_SS:
@@ -735,6 +757,62 @@
         return false;
     }
 
+
+    /**
+     * Processes SMS_EVENT_NOTIFY message from baseband.
+     *
+     * Method extracts values such as Alpha Id,Icon Id,Sms Tpdu etc from the ComprehensionTlv,
+     * in order to create the CommandParams i.e. SendSMSParams.
+     *
+     * @param cmdDet Command Details container object.
+     * @param ctlvs List of ComprehensionTlv objects following Command Details
+     *        object and Device Identities object within the proactive command
+     * @return true if the command is processing is pending and additional
+     *         asynchronous processing is required.
+     * @hide
+     */
+    public boolean processSMSEventNotify(CommandDetails cmdDet,
+            List<ComprehensionTlv> ctlvs) throws ResultException {
+        CatLog.d(this, "processSMSEventNotify");
+
+        TextMessage textMsg = new TextMessage();
+        IconId iconId = null;
+
+        ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID,
+                ctlvs);
+        /* Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV object.
+         *
+         * String corresponding to the alpha identifier is obtained and saved as part of
+         * the DisplayTextParams.
+         */
+        textMsg.text = ValueParser.retrieveAlphaId(ctlv, mNoAlphaUsrCnf);
+
+        ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
+        if (ctlv != null) {
+            // Retrieves icon id from the Icon Identifier COMPREHENSION-TLV object
+            iconId = ValueParser.retrieveIconId(ctlv);
+            textMsg.iconSelfExplanatory = iconId.selfExplanatory;
+        }
+
+        textMsg.responseNeeded = false;
+        DisplayTextParams displayTextParams = new DisplayTextParams(cmdDet, textMsg);
+        ComprehensionTlv ctlvTpdu = searchForTag(ComprehensionTlvTag.SMS_TPDU,
+                ctlvs);
+        // Retrieves smsMessage from the SMS TPDU COMPREHENSION-TLV object
+        SmsMessage smsMessage = ValueParser.retrieveTpduAsSmsMessage(ctlvTpdu);
+        if (smsMessage != null) {
+            TextMessage smsText = new TextMessage();
+            // Obtains the sms message content.
+            smsText.text = smsMessage.getMessageBody();
+            TextMessage destAddr = new TextMessage();
+            // Obtains the destination Address.
+            destAddr.text = smsMessage.getRecipientAddress();
+            mCmdParams = new SendSMSParams(cmdDet, smsText, destAddr, displayTextParams);
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Processes SET_UP_EVENT_LIST proactive command from the SIM card.
      *
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index 5542b65..416c669 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -50,7 +50,7 @@
      * @param data Byte array containing the value
      * @param valueIndex Index in data at which the value starts
      */
-    protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data,
+    public ComprehensionTlv(int tag, boolean cr, int length, byte[] data,
             int valueIndex) {
         mTag = tag;
         mCr = cr;
diff --git a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
old mode 100755
new mode 100644
index c25b59e..4b10cae
--- a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
+++ b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -32,8 +32,9 @@
 /**
  * Class used for queuing raw ril messages, decoding them into CommanParams
  * objects and sending the result back to the CAT Service.
+ * @hide
  */
-class RilMessageDecoder extends StateMachine {
+public class RilMessageDecoder extends StateMachine {
 
     // constants
     private static final int CMD_START = 1;
diff --git a/src/java/com/android/internal/telephony/cat/SendSMSParams.java b/src/java/com/android/internal/telephony/cat/SendSMSParams.java
new file mode 100644
index 0000000..f5108f0
--- /dev/null
+++ b/src/java/com/android/internal/telephony/cat/SendSMSParams.java
@@ -0,0 +1,33 @@
+/*
+ * 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.cat;
+
+class SendSMSParams extends CommandParams {
+
+    TextMessage mTextSmsMsg;
+    TextMessage mDestAddress;
+    DisplayTextParams mDisplayText;
+
+    SendSMSParams(CommandDetails cmdDet, TextMessage textMsg, TextMessage destAddress,
+            DisplayTextParams displayText) {
+        super(cmdDet);
+        mTextSmsMsg = textMsg;
+        mDestAddress = destAddress;
+        mDisplayText = displayText;
+    }
+
+}
diff --git a/src/java/com/android/internal/telephony/cat/ValueParser.java b/src/java/com/android/internal/telephony/cat/ValueParser.java
index 7c09136..bd17f48 100644
--- a/src/java/com/android/internal/telephony/cat/ValueParser.java
+++ b/src/java/com/android/internal/telephony/cat/ValueParser.java
@@ -18,16 +18,24 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
+import android.telephony.SmsMessage;
 
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.cat.Duration.TimeUnit;
 import com.android.internal.telephony.uicc.IccUtils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
-abstract class ValueParser {
+
+/**
+ *  Util class that parses different entities from the ctlvs ComprehensionTlv List
+ * @hide
+ */
+public abstract class ValueParser {
 
     /**
      * Search for a Command Details object from a list.
@@ -352,4 +360,42 @@
             throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
         }
     }
+
+    /**
+     * Retrieve's the tpdu from the ctlv and creates the SmsMessage from pdu.
+     * @param ctlv  ComprehensionTlv value
+     * @return message SmsMessage to retrieve the destAddress and Text
+     * @throws ResultException
+     * @hide
+     */
+    public static SmsMessage retrieveTpduAsSmsMessage(ComprehensionTlv ctlv)
+            throws ResultException {
+        if (ctlv != null) {
+            byte[] rawValue = ctlv.getRawValue();
+            int valueIndex = ctlv.getValueIndex();
+            int length = ctlv.getLength();
+            if (length != 0) {
+                try {
+                    byte[] pdu = Arrays.copyOfRange(rawValue, valueIndex, (valueIndex + length));
+                    ByteArrayOutputStream bo = new ByteArrayOutputStream(pdu.length + 1);
+                    /* Framework's TPdu Parser expects the TPdu be prepended with SC-Address.
+                     * else the parser will throw an exception. So prepending TPdu with 0,
+                     * which indicates that there is no SC address and its length is 0.
+                     * This way Parser will skip parsing for SC-Address
+                     */
+                    bo.write(0x00);
+                    bo.write(pdu, 0, pdu.length);
+                    byte[] frameworkPdu = bo.toByteArray();
+                    //ToDO handle for 3GPP2 format bug: b/243123533
+                    SmsMessage message = SmsMessage.createFromPdu(frameworkPdu,
+                            SmsMessage.FORMAT_3GPP);
+                    return message;
+                } catch (IndexOutOfBoundsException e) {
+                    throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
+                }
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index eb5f866..784c974 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Resources;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
 import android.os.SystemProperties;
@@ -77,8 +78,8 @@
      * Create a new inbound SMS handler for CDMA.
      */
     private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
-            Phone phone, CdmaSMSDispatcher smsDispatcher) {
-        super("CdmaInboundSmsHandler", context, storageMonitor, phone);
+            Phone phone, CdmaSMSDispatcher smsDispatcher, Looper looper) {
+        super("CdmaInboundSmsHandler", context, storageMonitor, phone, looper);
         mSmsDispatcher = smsDispatcher;
         phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null);
 
@@ -169,9 +170,10 @@
      * Wait for state machine to enter startup state. We can't send any messages until then.
      */
     public static CdmaInboundSmsHandler makeInboundSmsHandler(Context context,
-            SmsStorageMonitor storageMonitor, Phone phone, CdmaSMSDispatcher smsDispatcher) {
+            SmsStorageMonitor storageMonitor, Phone phone, CdmaSMSDispatcher smsDispatcher,
+            Looper looper) {
         CdmaInboundSmsHandler handler = new CdmaInboundSmsHandler(context, storageMonitor,
-                phone, smsDispatcher);
+                phone, smsDispatcher, looper);
         handler.start();
         return handler;
     }
@@ -194,7 +196,8 @@
      * @return true if the message was handled here; false to continue processing
      */
     @Override
-    protected int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource) {
+    protected int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource,
+            int token) {
         SmsMessage sms = (SmsMessage) smsb;
         boolean isBroadcastType = (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType());
 
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo.java b/src/java/com/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo.java
old mode 100755
new mode 100644
index b31df59..24ee56d
--- a/src/java/com/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo.java
@@ -17,6 +17,8 @@
 
 package com.android.internal.telephony.cdma;
 
+import java.util.Objects;
+
 /**
  * CdmaSmsBroadcastConfigInfo defines one configuration of Cdma Broadcast
  * Message to be received by the ME
@@ -84,4 +86,22 @@
             mFromServiceCategory + ", " + mToServiceCategory + "] " +
             (isSelected() ? "ENABLED" : "DISABLED");
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mFromServiceCategory, mToServiceCategory, mLanguage, mSelected);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof CdmaSmsBroadcastConfigInfo)) {
+            return false;
+        }
+
+        CdmaSmsBroadcastConfigInfo other = (CdmaSmsBroadcastConfigInfo) obj;
+
+        return mFromServiceCategory == other.mFromServiceCategory
+                && mToServiceCategory == other.mToServiceCategory
+                && mLanguage == other.mLanguage && mSelected == other.mSelected;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
index d034abd..267f70b 100644
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
@@ -19,23 +19,19 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-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.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.SystemProperties;
-import android.os.UserHandle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
@@ -56,14 +52,11 @@
 import android.util.SparseArray;
 
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.SlidingWindowEventCounter;
 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.List;
@@ -81,35 +74,9 @@
  */
 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";
+    /** Event to guide a transport type for initial data connection of emergency data network. */
+    private static final int EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY = 1;
 
     /**
      * The counters to detect frequent QNS attempt to change preferred network transport by ApnType.
@@ -154,22 +121,6 @@
 
     private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();
 
-    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 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.
@@ -210,6 +161,19 @@
         }
     }
 
+    @Override
+    public void handleMessage(@NonNull Message msg) {
+        switch (msg.what) {
+            case EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY:
+                AsyncResult ar = (AsyncResult) msg.obj;
+                int transport = (int) ar.result;
+                onEmergencyDataNetworkPreferredTransportChanged(transport);
+                break;
+            default:
+                loge("Unexpected event " + msg.what);
+        }
+    }
+
     private class AccessNetworksManagerDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
@@ -332,6 +296,20 @@
         }
     }
 
+    private void onEmergencyDataNetworkPreferredTransportChanged(
+            @AccessNetworkConstants.TransportType int transportType) {
+        try {
+            logl("onEmergencyDataNetworkPreferredTransportChanged: "
+                    + AccessNetworkConstants.transportTypeToString(transportType));
+            if (mIQualifiedNetworksService != null) {
+                mIQualifiedNetworksService.reportEmergencyDataNetworkPreferredTransportChanged(
+                        mPhone.getPhoneId(), transportType);
+            }
+        } catch (Exception ex) {
+            loge("onEmergencyDataNetworkPreferredTransportChanged: ", ex);
+        }
+    }
+
     /**
      * Access networks manager callback. This should be only used by {@link DataNetworkController}.
      */
@@ -366,28 +344,21 @@
                 Context.CARRIER_CONFIG_SERVICE);
         mLogTag = "ANM-" + mPhone.getPhoneId();
         mApnTypeToQnsChangeNetworkCounter = new SparseArray<>();
+        mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
 
-        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();
-        }
+        // bindQualifiedNetworksService posts real work to handler thread. So here we can
+        // let the callback execute in binder thread to avoid post twice.
+        mCarrierConfigManager.registerCarrierConfigChangeListener(Runnable::run,
+                (slotIndex, subId, carrierId, specificCarrierId) -> {
+                    if (slotIndex != mPhone.getPhoneId()) return;
+                    // 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();
+                });
+        bindQualifiedNetworksService();
 
         // Using post to delay the registering because data retry manager and data config
         // manager instances are created later than access networks manager.
@@ -415,6 +386,8 @@
                             mApnTypeToQnsChangeNetworkCounter.clear();
                         }
                     });
+            mPhone.registerForEmergencyDomainSelected(
+                    this, EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY, null);
         });
     }
 
@@ -490,24 +463,29 @@
     /**
      * 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).
+     * @return package name of the qualified networks service package.
      */
     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;
+        PersistableBundle b;
+        try {
+            b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
+                    CarrierConfigManager
+                            .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING);
+            if (b != null && !b.isEmpty()) {
+                // 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;
+                }
             }
+        } catch (RuntimeException e) {
+            loge("Carrier config loader is not available.");
         }
 
         return packageName;
@@ -523,16 +501,22 @@
         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;
+        PersistableBundle b;
+        try {
+            b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
+                    CarrierConfigManager
+                            .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING);
+            if (b != null && !b.isEmpty()) {
+                // 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;
+                }
             }
+        } catch (RuntimeException e) {
+            loge("Carrier config loader is not available.");
         }
 
         return className;
@@ -568,30 +552,9 @@
     }
 
     /**
-     * @return {@code true} if the device operates in legacy mode, otherwise {@code false}.
+     * @return The available transports.
      */
-    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() {
+    public @NonNull int[] getAvailableTransports() {
         return mAvailableTransports;
     }
 
@@ -626,11 +589,6 @@
      * @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);
     }
@@ -733,9 +691,6 @@
         }
 
         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);
diff --git a/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java b/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java
index aa830ae..c1d1203 100644
--- a/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java
+++ b/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java
@@ -40,7 +40,6 @@
 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;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
@@ -166,17 +165,9 @@
 
         private String getValidationNetworkIdentity(int subId) {
             if (!SubscriptionManager.isUsableSubscriptionId(subId)) return null;
-            Phone phone;
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                if (SubscriptionManagerService.getInstance() == null) return null;
-                phone = PhoneFactory.getPhone(SubscriptionManagerService.getInstance()
-                        .getPhoneId(subId));
-            } else {
-                SubscriptionController subController = SubscriptionController.getInstance();
-                if (subController == null) return null;
-                phone = PhoneFactory.getPhone(subController.getPhoneId(subId));
-            }
-
+            if (SubscriptionManagerService.getInstance() == null) return null;
+            Phone phone = PhoneFactory.getPhone(SubscriptionManagerService.getInstance()
+                    .getPhoneId(subId));
             if (phone == null || phone.getServiceState() == null) return null;
 
             NetworkRegistrationInfo regInfo = phone.getServiceState().getNetworkRegistrationInfo(
@@ -267,20 +258,12 @@
         // If it's already validating the same subscription, do nothing.
         if (subId == mSubId) return;
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo == null || !subInfo.isActive()) {
-                logd("Failed to start validation. Inactive subId " + subId);
-                callback.onValidationDone(false, subId);
-                return;
-            }
-        } else {
-            if (!SubscriptionController.getInstance().isActiveSubId(subId)) {
-                logd("Failed to start validation. Inactive subId " + subId);
-                callback.onValidationDone(false, subId);
-                return;
-            }
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo == null || !subInfo.isActive()) {
+            logd("Failed to start validation. Inactive subId " + subId);
+            callback.onValidationDone(false, subId);
+            return;
         }
 
         if (isValidating()) {
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 731aac7..78450a8 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -72,12 +72,6 @@
     /** The default timeout in ms for data network stuck in a transit state. */
     private static final int DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS = 300000;
 
-    /** Default time threshold in ms to define a internet connection status to be stable. */
-    public static int DEFAULT_AUTO_DATA_SWITCH_STABILITY_TIME_MS = 10000;
-
-    /** The max number of retries when a pre-switching validation fails. */
-    public static int DEFAULT_AUTO_DATA_SWITCH_MAX_RETRY = 7;
-
     /** Event for carrier config changed. */
     private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;
 
@@ -268,18 +262,6 @@
      */
     private boolean mIsApnConfigAnomalyReportEnabled;
 
-    /**
-     * Time threshold in ms to define a internet connection status to be stable(e.g. out of service,
-     * in service, wifi is the default active network.etc), while -1 indicates auto switch feature
-     * disabled.
-     */
-    private long mAutoDataSwitchAvailabilityStabilityTimeThreshold;
-
-    /**
-     * The maximum number of retries when a pre-switching validation fails.
-     */
-    private int mAutoDataSwitchValidationMaxRetry;
-
     private @NonNull final Phone mPhone;
     private @NonNull final String mLogTag;
 
@@ -438,12 +420,6 @@
                 KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT, DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
         mIsApnConfigAnomalyReportEnabled = properties.getBoolean(
                 KEY_ANOMALY_APN_CONFIG_ENABLED, false);
-        mAutoDataSwitchAvailabilityStabilityTimeThreshold = properties.getInt(
-                KEY_AUTO_DATA_SWITCH_AVAILABILITY_STABILITY_TIME_THRESHOLD,
-                DEFAULT_AUTO_DATA_SWITCH_STABILITY_TIME_MS);
-        mAutoDataSwitchValidationMaxRetry = properties.getInt(
-                KEY_AUTO_DATA_SWITCH_VALIDATION_MAX_RETRY,
-                DEFAULT_AUTO_DATA_SWITCH_MAX_RETRY);
     }
 
     /**
@@ -712,6 +688,12 @@
         return mShouldKeepNetworkUpInNonVops;
     }
 
+    /** {@code True} requires ping test to pass on the target slot before switching to it.*/
+    public boolean isPingTestBeforeAutoDataSwitchRequired() {
+        return mResources.getBoolean(com.android.internal.R.bool
+                .auto_data_switch_ping_test_before_switch);
+    }
+
     /**
      * @return Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED}
      * is supported by the carrier.
@@ -939,7 +921,8 @@
      * @return The maximum number of retries when a validation for switching failed.
      */
     public int getAutoDataSwitchValidationMaxRetry() {
-        return mAutoDataSwitchValidationMaxRetry;
+        return mResources.getInteger(com.android.internal.R.integer
+                .auto_data_switch_validation_max_retry);
     }
 
     /**
@@ -948,7 +931,8 @@
      * auto switch feature disabled.
      */
     public long getAutoDataSwitchAvailabilityStabilityTimeThreshold() {
-        return mAutoDataSwitchAvailabilityStabilityTimeThreshold;
+        return mResources.getInteger(com.android.internal.R.integer
+                .auto_data_switch_availability_stability_time_threshold_millis);
     }
 
     /**
@@ -1006,7 +990,7 @@
      * @return {@code true} if tearing down IMS data network should be delayed until the voice call
      * ends.
      */
-    public boolean isImsDelayTearDownEnabled() {
+    public boolean isImsDelayTearDownUntilVoiceCallEndEnabled() {
         return mCarrierConfig.getBoolean(
                 CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL);
     }
@@ -1331,9 +1315,9 @@
         pw.println("mNetworkDisconnectingTimeout=" + mNetworkDisconnectingTimeout);
         pw.println("mNetworkHandoverTimeout=" + mNetworkHandoverTimeout);
         pw.println("mIsApnConfigAnomalyReportEnabled=" + mIsApnConfigAnomalyReportEnabled);
-        pw.println("mAutoDataSwitchAvailabilityStabilityTimeThreshold="
-                + mAutoDataSwitchAvailabilityStabilityTimeThreshold);
-        pw.println("mAutoDataSwitchValidationMaxRetry=" + mAutoDataSwitchValidationMaxRetry);
+        pw.println("getAutoDataSwitchAvailabilityStabilityTimeThreshold="
+                + getAutoDataSwitchAvailabilityStabilityTimeThreshold());
+        pw.println("getAutoDataSwitchValidationMaxRetry=" + getAutoDataSwitchValidationMaxRetry());
         pw.println("Metered APN types=" + mMeteredApnTypes.stream()
                 .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
         pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
@@ -1344,6 +1328,8 @@
                 .stream().map(DataUtils::networkCapabilityToString)
                 .collect(Collectors.joining(",")));
         pw.println("mShouldKeepNetworkUpInNoVops=" + mShouldKeepNetworkUpInNonVops);
+        pw.println("isPingTestBeforeAutoDataSwitchRequired="
+                + isPingTestBeforeAutoDataSwitchRequired());
         pw.println("Unmetered network types=" + String.join(",", mUnmeteredNetworkTypes));
         pw.println("Roaming unmetered network types="
                 + String.join(",", mRoamingUnmeteredNetworkTypes));
@@ -1368,7 +1354,8 @@
                 + shouldPersistIwlanDataNetworksWhenDataServiceRestarted());
         pw.println("Bandwidth estimation source=" + mResources.getString(
                 com.android.internal.R.string.config_bandwidthEstimateSource));
-        pw.println("isDelayTearDownImsEnabled=" + isImsDelayTearDownEnabled());
+        pw.println("isImsDelayTearDownUntilVoiceCallEndEnabled="
+                + isImsDelayTearDownUntilVoiceCallEndEnabled());
         pw.println("isEnhancedIwlanHandoverCheckEnabled=" + isEnhancedIwlanHandoverCheckEnabled());
         pw.println("isTetheringProfileDisabledForRoaming="
                 + isTetheringProfileDisabledForRoaming());
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index f13e66b..2ba3fe4 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -323,7 +323,9 @@
         /** 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);
+        DATA_SETTINGS_NOT_READY(true),
+        /** Handover max retry stopped but network is not on the preferred transport. */
+        HANDOVER_RETRY_STOPPED(true);
 
         private final boolean mIsHardReason;
 
@@ -362,6 +364,10 @@
          */
         NORMAL,
         /**
+         * Data is allowed because an ongoing VoPS call depends on this network
+         */
+        IN_VOICE_CALL,
+        /**
          * The network brought up by this network request is unmetered. Should allowed no matter
          * the user enables or disables data.
          */
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index c6b01ed..d533933 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.data;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -52,6 +54,7 @@
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.ValidationStatus;
 import android.telephony.AnomalyReporter;
+import android.telephony.CarrierConfigManager;
 import android.telephony.DataFailCause;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.LinkCapacityEstimate;
@@ -678,6 +681,9 @@
      */
     private @NonNull int[] mAdministratorUids = new int[0];
 
+    /** Carrier privileges callback to monitor administrator UID change. */
+    private @Nullable TelephonyManager.CarrierPrivilegesCallback mCarrierPrivilegesCallback;
+
     /**
      * Carrier service package uid. This UID will not change through the life cycle of data network.
      */
@@ -920,8 +926,9 @@
         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);
+        for (int transportType : mAccessNetworksManager.getAvailableTransports()) {
+            mCid.put(transportType, INVALID_CID);
+        }
         mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();
         mTcpBufferSizes = mDataConfigManager.getTcpConfigString(mTelephonyDisplayInfo);
 
@@ -1053,8 +1060,22 @@
                 mDataServiceManagers.get(transport)
                         .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);
             }
-            mPhone.getCarrierPrivilegesTracker().registerCarrierPrivilegesListener(getHandler(),
-                    EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
+
+            mCarrierPrivilegesCallback =
+                    (Set<String> privilegedPackageNames, Set<Integer> privilegedUids) -> {
+                        log("onCarrierPrivilegesChanged, Uids=" + privilegedUids.toString());
+                        Message message = obtainMessage(EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED);
+                        AsyncResult.forMessage(
+                                message,
+                                privilegedUids.stream().mapToInt(i -> i).toArray(),
+                                null /* ex */);
+                        sendMessage(message);
+                    };
+            TelephonyManager tm = mPhone.getContext().getSystemService(TelephonyManager.class);
+            if (tm != null) {
+                tm.registerCarrierPrivilegesCallback(
+                        mPhone.getPhoneId(), getHandler()::post, mCarrierPrivilegesCallback);
+            }
 
             mPhone.getServiceStateTracker().registerForCssIndicatorChanged(
                     getHandler(), EVENT_CSS_INDICATOR_CHANGED, null);
@@ -1088,7 +1109,10 @@
             mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
 
             mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
-            mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
+            TelephonyManager tm = mPhone.getContext().getSystemService(TelephonyManager.class);
+            if (tm != null && mCarrierPrivilegesCallback != null) {
+                tm.unregisterCarrierPrivilegesCallback(mCarrierPrivilegesCallback);
+            }
             for (int transport : mAccessNetworksManager.getAvailableTransports()) {
                 mDataServiceManagers.get(transport)
                         .unregisterForDataCallListChanged(getHandler());
@@ -1316,13 +1340,14 @@
                 }
             }
 
-            // If we've ever received PCO data before connected, now it's the time to
-            // process it.
+            // If we've ever received PCO data before connected, now it's the time to process it.
             mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap())
                     .forEach((pcoId, pcoData) -> {
                         onPcoDataChanged(pcoData);
                     });
 
+            mDataNetworkCallback.invokeFromExecutor(
+                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
             notifyPreciseDataConnectionState();
             updateSuspendState();
         }
@@ -1574,6 +1599,9 @@
             //************************************************************//
 
             if (mEverConnected) {
+                mLinkStatus = DataCallResponse.LINK_STATUS_INACTIVE;
+                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
+                        .onLinkStatusChanged(DataNetwork.this, mLinkStatus));
                 mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                         .onDisconnected(DataNetwork.this, mFailCause, mTearDownReason));
                 if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
@@ -2278,8 +2306,13 @@
         if (mLinkStatus != response.getLinkStatus()) {
             mLinkStatus = response.getLinkStatus();
             log("Link status updated to " + DataUtils.linkStatusToString(mLinkStatus));
-            mDataNetworkCallback.invokeFromExecutor(
-                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
+            if (isConnected()) {
+                // If the data network is in a transition state, the link status will be notified
+                // upon entering connected or disconnected state. If the data network is already
+                // connected, send the updated link status from the updated data call response.
+                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
+                        .onLinkStatusChanged(DataNetwork.this, mLinkStatus));
+            }
         }
 
         // Set link addresses
@@ -2552,9 +2585,9 @@
             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)) {
+        } else if (mPhone.getHalVersion(HAL_SERVICE_DATA).less(RIL.RADIO_HAL_VERSION_2_0)) {
             log("Remove network on deactivate data response on old HAL "
-                    + mPhone.getHalVersion());
+                    + mPhone.getHalVersion(HAL_SERVICE_DATA));
             mFailCause = DataFailCause.LOST_CONNECTION;
             transitionTo(mDisconnectedState);
         }
@@ -2589,16 +2622,17 @@
                 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);
+        mDataCallSessionStats.setDeactivateDataCallReason(reason);
         mInvokedDataDeactivation = true;
     }
 
     /**
-     * @return {@code true} if this is an IMS network and tear down should be delayed until call
-     * ends on this data network.
+     * @return {@code true} if we shall delay tear down this network because an active voice call is
+     * relying on it and
+     * {@link CarrierConfigManager#KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL} is enabled.
      */
     public boolean shouldDelayImsTearDownDueToInCall() {
-        return mDataConfigManager.isImsDelayTearDownEnabled()
+        return mDataConfigManager.isImsDelayTearDownUntilVoiceCallEndEnabled()
                 && mNetworkCapabilities != null
                 && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                 && mPhone.getImsPhone() != null
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 8ee4c64..079b398 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -561,10 +561,10 @@
         /**
          * 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.
+         * @param internetNetworks The connected internet data network. It should be only one in
+         *                         most of the cases.
          */
-        public void onInternetDataNetworkConnected(@NonNull List<DataProfile> dataProfiles) {}
+        public void onInternetDataNetworkConnected(@NonNull List<DataNetwork> internetNetworks) {}
 
         /**
          * Called when data network is connected.
@@ -801,13 +801,10 @@
         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));
+        for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+            mDataServiceManagers.put(transport, new DataServiceManager(mPhone, looper, transport));
         }
+
         mDataConfigManager = new DataConfigManager(mPhone, looper);
 
         // ========== Anomaly counters ==========
@@ -913,24 +910,7 @@
                     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.shouldDelayImsTearDownDueToInCall()) {
-                            log("onDataNetworkHandoverRetryStopped: Delay IMS tear down until call "
-                                    + "ends. " + dataNetwork);
-                            return;
-                        }
-
-                        tearDownGracefully(dataNetwork,
-                                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
+                        DataNetworkController.this.onDataNetworkHandoverRetryStopped(dataNetwork);
                     }
                 });
         mImsManager = mPhone.getContext().getSystemService(ImsManager.class);
@@ -1011,12 +991,10 @@
         mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                 .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED);
 
-        if (!mAccessNetworksManager.isInLegacyMode()) {
-            mPhone.getServiceStateTracker().registerForServiceStateChanged(this,
-                    EVENT_SERVICE_STATE_CHANGED, null);
-            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                    .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED);
-        }
+        mPhone.getServiceStateTracker().registerForServiceStateChanged(this,
+                EVENT_SERVICE_STATE_CHANGED, null);
+        mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+                .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED);
 
         mPhone.getContext().getSystemService(TelephonyRegistryManager.class)
                 .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() {
@@ -1640,13 +1618,11 @@
                         reason.isConditionBased());
         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.
+        } else if (// Check for new requests if we already self-scheduled(as opposed to modem
+            // demanded) retry for similar requests.
+                reason == DataEvaluationReason.NEW_REQUEST
+                        &&  mDataRetryManager.isSimilarNetworkRequestRetryScheduled(
+                        networkRequest, transport)) {
             evaluation.addDataDisallowedReason(DataDisallowedReason.RETRY_SCHEDULED);
         } else if (mDataRetryManager.isDataProfileThrottled(dataProfile, transport)) {
             evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
@@ -1771,15 +1747,20 @@
             }
         }
 
-        boolean isMmtel = false;
-        // 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.
-            isMmtel = true;
-            if (!dataNetwork.shouldDelayImsTearDownDueToInCall()) {
+        boolean vopsIsRequired = dataNetwork.hasNetworkCapabilityInNetworkRequests(
+                NetworkCapabilities.NET_CAPABILITY_MMTEL);
+
+        // Check an active call relying on this network and config for "delay tear down due to vops
+        // call" is enabled.
+        if (dataNetwork.shouldDelayImsTearDownDueToInCall()) {
+            if (vopsIsRequired) {
+                log("Ignored VoPS check due to delay IMS tear down until call ends.");
+            }
+        } else {
+            // Reach here means we should ignore active calls even if there are any.
+
+            // Check if VoPS requirement is met.
+            if (vopsIsRequired) {
                 if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                     NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
                             NetworkRegistrationInfo.DOMAIN_PS,
@@ -1794,16 +1775,20 @@
                         }
                     }
                 }
-            } else {
-                log("Ignored VoPS check due to delay IMS tear down until call ends.");
+            }
+
+            // Check if handover retry stopped and preferred transport still not matched.
+            int preferredTransport = mAccessNetworksManager
+                    .getPreferredTransportByNetworkCapability(
+                            dataNetwork.getApnTypeNetworkCapability());
+            if (preferredTransport != dataNetwork.getTransport()
+                    && mDataRetryManager.isDataNetworkHandoverRetryStopped(dataNetwork)) {
+                evaluation.addDataDisallowedReason(DataDisallowedReason.HANDOVER_RETRY_STOPPED);
             }
         }
 
         // Check if data is disabled
-        boolean dataDisabled = false;
-        if (!mDataSettingsManager.isDataEnabled()) {
-            dataDisabled = true;
-        }
+        boolean dataDisabled = !mDataSettingsManager.isDataEnabled();
 
         // Check if data roaming is disabled
         if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) {
@@ -1818,17 +1803,14 @@
         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)));
+            dataDisabled = !mDataSettingsManager.isDataEnabled(
+                    DataUtils.networkCapabilityToApnType(
+                            dataNetwork.getApnTypeNetworkCapability()));
 
             // 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)
-                    // delay IMS tear down if SRVCC in progress
-                    && !(isMmtel && mIsSrvccHandoverInProcess)) {
+                    && !dataProfile.getApnSetting().canSupportLingeringNetworkType(networkType)) {
                 log("networkType=" + TelephonyManager.getNetworkTypeName(networkType)
                         + ", networkTypeBitmask="
                         + TelephonyManager.convertNetworkTypeBitmaskToString(
@@ -1855,7 +1837,8 @@
         // If users switch preferred profile in APN editor, we need to tear down network.
         if (dataNetwork.isInternetSupported()
                 && !mDataProfileManager.isDataProfilePreferred(dataProfile)
-                && mDataProfileManager.isAnyPreferredDataProfileExisting()) {
+                && mDataProfileManager.canPreferredDataProfileSatisfy(
+                        dataNetwork.getAttachedNetworkRequestList())) {
             evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_NOT_PREFERRED);
         }
 
@@ -1891,6 +1874,15 @@
             }
         }
 
+        // Check if we allow additional lingering for active VoPS call network if
+        // a. this network is SRVCC handover in progress
+        // or b. "delay tear down due to active VoPS call" is enabled
+        boolean isInSrvcc = vopsIsRequired && mIsSrvccHandoverInProcess;
+        if (evaluation.containsOnly(DataDisallowedReason.DATA_NETWORK_TYPE_NOT_ALLOWED)
+                && (dataNetwork.shouldDelayImsTearDownDueToInCall() || isInSrvcc)) {
+            evaluation.addDataAllowedReason(DataAllowedReason.IN_VOICE_CALL);
+        }
+
         log("Evaluated " + dataNetwork + ", " + evaluation);
         return evaluation;
     }
@@ -2083,6 +2075,8 @@
                     return DataNetwork.TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED;
                 case ONLY_ALLOWED_SINGLE_NETWORK:
                     return DataNetwork.TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK;
+                case HANDOVER_RETRY_STOPPED:
+                    return DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED;
             }
         }
         return DataNetwork.TEAR_DOWN_REASON_NONE;
@@ -2801,6 +2795,32 @@
     }
 
     /**
+     * Called when data network reached max handover retry count.
+     *
+     * @param dataNetwork The data network.
+     */
+    private void onDataNetworkHandoverRetryStopped(@NonNull DataNetwork 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.shouldDelayImsTearDownDueToInCall()) {
+            log("onDataNetworkHandoverRetryStopped: Delay IMS tear down until call "
+                    + "ends. " + dataNetwork);
+            return;
+        }
+
+        tearDownGracefully(dataNetwork,
+                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
+    }
+
+    /**
      * Called when data network validation status changed.
      *
      * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
@@ -3152,6 +3172,16 @@
             logl("Start handover " + dataNetwork + " to "
                     + AccessNetworkConstants.transportTypeToString(targetTransport));
             dataNetwork.startHandover(targetTransport, dataHandoverRetryEntry);
+        } else if (dataEvaluation.containsOnly(DataDisallowedReason.NOT_IN_SERVICE)
+                && dataNetwork.shouldDelayImsTearDownDueToInCall()) {
+            // We try to preserve voice call in the case of temporary preferred transport mismatch
+            if (dataHandoverRetryEntry != null) {
+                dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
+            }
+            mDataRetryManager.evaluateDataHandoverRetry(dataNetwork,
+                    DataFailCause.HANDOVER_FAILED,
+                    DataCallResponse.RETRY_DURATION_UNDEFINED /* retry mills */);
+            logl("tryHandoverDataNetwork: Scheduled retry due to in voice call and target OOS");
         } else if (dataEvaluation.containsAny(DataDisallowedReason.NOT_ALLOWED_BY_POLICY,
                 DataDisallowedReason.NOT_IN_SERVICE,
                 DataDisallowedReason.VOPS_NOT_SUPPORTED)) {
@@ -3456,9 +3486,7 @@
                     && mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) {
                 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                         () -> callback.onInternetDataNetworkConnected(
-                                allConnectedInternetDataNetworks.stream()
-                                        .map(DataNetwork::getDataProfile)
-                                        .collect(Collectors.toList()))));
+                                allConnectedInternetDataNetworks)));
             } else if (dataNetworkState == TelephonyManager.DATA_DISCONNECTED
                     && mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) {
                 mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index bcb9a36..893ec41 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -171,8 +171,8 @@
                 new DataNetworkControllerCallback(this::post) {
                     @Override
                     public void onInternetDataNetworkConnected(
-                            @NonNull List<DataProfile> dataProfiles) {
-                        DataProfileManager.this.onInternetDataNetworkConnected(dataProfiles);
+                            @NonNull List<DataNetwork> internetNetworks) {
+                        DataProfileManager.this.onInternetDataNetworkConnected(internetNetworks);
                     }
 
                     @Override
@@ -413,24 +413,37 @@
     /**
      * Called when internet data is connected.
      *
-     * @param dataProfiles The connected internet data networks' profiles.
+     * @param internetNetworks The connected internet data networks.
      */
-    private void onInternetDataNetworkConnected(@NonNull List<DataProfile> dataProfiles) {
-        // 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);
+    private void onInternetDataNetworkConnected(@NonNull List<DataNetwork> internetNetworks) {
+        DataProfile defaultProfile = null;
+        if (internetNetworks.size() == 1) {
+            // Most of the cases there should be only one.
+            defaultProfile = internetNetworks.get(0).getDataProfile();
+        } else if (internetNetworks.size() > 1) {
+            // but in case there are multiple, find the default internet network, and choose the
+            // one which has longest life cycle.
+            logv("onInternetDataNetworkConnected: mPreferredDataProfile=" + mPreferredDataProfile
+                    + " internetNetworks=" + internetNetworks);
+            defaultProfile = internetNetworks.stream()
+                    .filter(network -> mPreferredDataProfile == null
+                            || canPreferredDataProfileSatisfy(
+                            network.getAttachedNetworkRequestList()))
+                    .map(DataNetwork::getDataProfile)
+                    .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp))
+                    .orElse(null);
+        }
 
         // Update a working internet data profile as a future candidate for preferred data profile
         // after APNs are reset to default
-        mLastInternetDataProfile = dataProfile;
+        mLastInternetDataProfile = defaultProfile;
 
-        // 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.
-        if (mPreferredDataProfile != null) return;
+        // If the live default internet network is not using the preferred data profile, since
+        // brought up a network means it passed sophisticated checks, update the preferred data
+        // profile so that this network won't be torn down in future network evaluations.
+        if (defaultProfile == null || defaultProfile.equals(mPreferredDataProfile)) return;
         // Save the preferred data profile into database.
-        setPreferredDataProfile(dataProfile);
+        setPreferredDataProfile(defaultProfile);
         updateDataProfiles(ONLY_UPDATE_IA_IF_CHANGED);
     }
 
@@ -484,7 +497,7 @@
      * the preferred data profile from database.
      */
     private void setPreferredDataProfile(@Nullable DataProfile dataProfile) {
-        log("setPreferredDataProfile: " + dataProfile);
+        logl("setPreferredDataProfile: " + dataProfile);
 
         String subId = Long.toString(mPhone.getSubId());
         Uri uri = Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_URI, subId);
@@ -783,6 +796,18 @@
     }
 
     /**
+     * @param networkRequests The required network requests
+     * @return {@code true} if we currently have a preferred data profile that's capable of
+     * satisfying the required network requests; {@code false} if we have no preferred, or the
+     * preferred cannot satisfy the required requests.
+     */
+    public boolean canPreferredDataProfileSatisfy(
+            @NonNull DataNetworkController.NetworkRequestList networkRequests) {
+        return mPreferredDataProfile != null && networkRequests.stream()
+                .allMatch(request -> request.canBeSatisfiedBy(mPreferredDataProfile));
+    }
+
+    /**
      * Check if there is tethering data profile for certain network type.
      *
      * @param networkType The network type
@@ -803,18 +828,6 @@
         return getDataProfileForNetworkRequest(networkRequest, networkType, true) != 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.
      */
@@ -1130,6 +1143,7 @@
         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("Last internet data profile=" + mLastInternetDataProfile);
         pw.println("Initial attach data profile=" + mInitialAttachDataProfile);
         pw.println("isTetheringDataProfileExisting=" + isTetheringDataProfileExisting(
                 TelephonyManager.NETWORK_TYPE_LTE));
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index ab653fe..b6ad101 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -21,6 +21,12 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.NetworkCapabilities;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -72,6 +78,11 @@
 public class DataRetryManager extends Handler {
     private static final boolean VDBG = false;
 
+    /** Intent of Alarm Manager for long retry timer. */
+    private static final String ACTION_RETRY = "com.android.internal.telephony.data.ACTION_RETRY";
+    /** The extra key for the hashcode of the retry entry for Alarm Manager. */
+    private static final String ACTION_RETRY_EXTRA_HASHCODE = "extra_retry_hashcode";
+
     /** Event for data setup retry. */
     private static final int EVENT_DATA_SETUP_RETRY = 3;
 
@@ -98,6 +109,12 @@
 
     /** The maximum entries to preserve. */
     private static final int MAXIMUM_HISTORICAL_ENTRIES = 100;
+    /**
+     * The threshold of retry timer, longer than or equal to which we use alarm manager to schedule
+     * instead of handler.
+     */
+    private static final long RETRY_LONG_DELAY_TIMER_THRESHOLD_MILLIS = TimeUnit
+            .MINUTES.toMillis(1);
 
     @IntDef(prefix = {"RESET_REASON_"},
             value = {
@@ -143,6 +160,9 @@
     /** Local log. */
     private final @NonNull LocalLog mLocalLog = new LocalLog(128);
 
+    /** Alarm Manager used to schedule long set up or handover retries. */
+    private final @NonNull AlarmManager mAlarmManager;
+
     /**
      * The data retry callback. This is only used to notify {@link DataNetworkController} to retry
      * setup data network.
@@ -952,16 +972,17 @@
         mDataServiceManagers = dataServiceManagers;
         mDataConfigManager = dataNetworkController.getDataConfigManager();
         mDataProfileManager = dataNetworkController.getDataProfileManager();
+        mAlarmManager = mPhone.getContext().getSystemService(AlarmManager.class);
+
         mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) {
             @Override
             public void onCarrierConfigChanged() {
                 DataRetryManager.this.onCarrierConfigUpdated();
             }
         });
-        mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .registerForApnUnthrottled(this, EVENT_DATA_PROFILE_UNTHROTTLED);
-        if (!mPhone.getAccessNetworksManager().isInLegacyMode()) {
-            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+
+        for (int transport : mPhone.getAccessNetworksManager().getAvailableTransports()) {
+            mDataServiceManagers.get(transport)
                     .registerForApnUnthrottled(this, EVENT_DATA_PROFILE_UNTHROTTLED);
         }
         mDataProfileManager.registerCallback(new DataProfileManagerCallback(this::post) {
@@ -997,6 +1018,19 @@
         mRil.registerForOn(this, EVENT_RADIO_ON, null);
         mRil.registerForModemReset(this, EVENT_MODEM_RESET, null);
 
+        // Register intent of alarm manager for long retry timer
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_RETRY);
+        mPhone.getContext().registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (ACTION_RETRY.equals(intent.getAction())) {
+                    DataRetryManager.this.onAlarmIntentRetry(
+                            intent.getIntExtra(ACTION_RETRY_EXTRA_HASHCODE, -1 /*Bad hashcode*/));
+                }
+            }
+        }, intentFilter);
+
         if (mDataConfigManager.shouldResetDataThrottlingWhenTacChanges()) {
             mPhone.getServiceStateTracker().registerForAreaCodeChanged(this, EVENT_TAC_CHANGED,
                     null);
@@ -1190,13 +1224,14 @@
                         return;
                     }
 
-                    int failedCount = getRetryFailedCount(capability, retryRule);
+                    int failedCount = getRetryFailedCount(capability, retryRule, transport);
                     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 "
+                        log("Data retry failed for " + failedCount + " times on "
+                                + AccessNetworkConstants.transportTypeToString(transport)
+                                + ". Stopped timer-based data retry for "
                                 + DataUtils.networkCapabilityToString(capability)
                                 + ". Condition-based retry will still happen when condition "
                                 + "changes.");
@@ -1299,6 +1334,24 @@
         }
     }
 
+    /**
+     * @param dataNetwork The data network to check.
+     * @return {@code true} if the data network had failed the maximum number of attempts for
+     * handover according to any retry rules.
+     */
+    public boolean isDataNetworkHandoverRetryStopped(@NonNull DataNetwork dataNetwork) {
+        // Matching the rule in configured order.
+        for (DataHandoverRetryRule retryRule : mDataHandoverRetryRuleList) {
+            int failedCount = getRetryFailedCount(dataNetwork, retryRule);
+            if (failedCount == retryRule.getMaxRetries()) {
+                log("Data handover retry failed for " + failedCount + " times. Stopped "
+                        + "handover retry.");
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** Cancel all retries and throttling entries. */
     private void onReset(@RetryResetReason int reason) {
         logl("Remove all retry and throttling entries, reason=" + resetReasonToString(reason));
@@ -1354,16 +1407,18 @@
      *
      * @param networkCapability The network capability to check.
      * @param dataRetryRule The data retry rule.
+     * @param transport The transport on which setup failure has occurred.
      * @return The failed count since last successful data setup.
      */
     private int getRetryFailedCount(@NetCapability int networkCapability,
-            @NonNull DataSetupRetryRule dataRetryRule) {
+            @NonNull DataSetupRetryRule dataRetryRule, @TransportType int transport) {
         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.setupRetryType == DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS
+                        && entry.transport == transport) {
                     if (entry.networkRequestList.isEmpty()) {
                         String msg = "Invalid data retry entry detected";
                         logl(msg);
@@ -1395,20 +1450,50 @@
      * @param dataRetryEntry The data retry entry.
      */
     private void schedule(@NonNull DataRetryEntry dataRetryEntry) {
-        logl("Scheduled data retry: " + dataRetryEntry);
+        logl("Scheduled data retry " + dataRetryEntry
+                + " hashcode=" + dataRetryEntry.hashCode());
         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);
+        // When the device is in doze mode, the handler message might be extremely delayed because
+        // handler uses relative system time(not counting sleep) which is inaccurate even when we
+        // enter the maintenance window.
+        // Therefore, we use alarm manager when we need to schedule long timers.
+        if (dataRetryEntry.retryDelayMillis <= RETRY_LONG_DELAY_TIMER_THRESHOLD_MILLIS) {
+            sendMessageDelayed(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
+                            ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY, dataRetryEntry),
+                    dataRetryEntry.retryDelayMillis);
+        } else {
+            Intent intent = new Intent(ACTION_RETRY);
+            intent.putExtra(ACTION_RETRY_EXTRA_HASHCODE, dataRetryEntry.hashCode());
+            // No need to wake up the device at the exact time, the retry can wait util next time
+            // the device wake up to save power.
+            mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME,
+                    dataRetryEntry.retryElapsedTime,
+                    PendingIntent.getBroadcast(mPhone.getContext(),
+                            dataRetryEntry.hashCode() /*Unique identifier of this retry attempt*/,
+                            intent,
+                            PendingIntent.FLAG_IMMUTABLE));
+        }
+    }
+
+    /**
+     * Called when it's time to retry scheduled by Alarm Manager.
+     * @param retryHashcode The hashcode is the unique identifier of which retry entry to retry.
+     */
+    private void onAlarmIntentRetry(int retryHashcode) {
+        DataRetryEntry dataRetryEntry = mDataRetryEntries.stream()
+                .filter(entry -> entry.hashCode() == retryHashcode)
+                .findAny()
+                .orElse(null);
+        logl("onAlarmIntentRetry: found " + dataRetryEntry + " with hashcode " + retryHashcode);
+        if (dataRetryEntry != null) {
+            sendMessage(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
+                    ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY, dataRetryEntry));
+        }
     }
 
     /**
@@ -1431,15 +1516,20 @@
             @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.
+        // Remove previous entry that contains the same data profile. Therefore it should always
+        // contain at maximum all the distinct data profiles of the current subscription.
         mDataThrottlingEntries.removeIf(
                 throttlingEntry -> dataProfile.equals(throttlingEntry.dataProfile));
 
-
+        if (mDataThrottlingEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
+            // If we don't see the anomaly report after U release, we should remove this check for
+            // the commented reason above.
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString("24fd4d46-1d0f-4b13-b7d6-7bad70b8289b"),
+                    "DataRetryManager throttling more than 100 data profiles",
+                    mPhone.getCarrierId());
+            mDataThrottlingEntries.remove(0);
+        }
         logl("Add throttling entry " + entry);
         mDataThrottlingEntries.add(entry);
 
@@ -1474,11 +1564,11 @@
      * 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.
-     * @param retry Whether schedule data setup retry after unthrottling.
+     * @param retry Whether schedule retry after unthrottling.
      */
     private void onDataProfileUnthrottled(@Nullable DataProfile dataProfile, @Nullable String apn,
             @TransportType int transport, boolean remove, boolean retry) {
-        log("onDataProfileUnthrottled: data profile=" + dataProfile + ", apn=" + apn
+        log("onDataProfileUnthrottled: dataProfile=" + dataProfile + ", apn=" + apn
                 + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)
                 + ", remove=" + remove);
 
@@ -1490,11 +1580,9 @@
             // 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.
-            log("onDataProfileUnthrottled: dataProfile=" + dataProfile);
             Stream<DataThrottlingEntry> stream = mDataThrottlingEntries.stream();
             stream = stream.filter(entry -> entry.expirationTimeMillis > now);
             if (dataProfile.getApnSetting() != null) {
-                dataProfile.getApnSetting().setPermanentFailed(false);
                 stream = stream
                         .filter(entry -> entry.dataProfile.getApnSetting() != null)
                         .filter(entry -> entry.dataProfile.getApnSetting().getApnName()
@@ -1535,6 +1623,7 @@
         final int dataRetryType = retryType;
 
         if (unthrottledProfile != null && unthrottledProfile.getApnSetting() != null) {
+            unthrottledProfile.getApnSetting().setPermanentFailed(false);
             throttleStatusList.addAll(unthrottledProfile.getApnSetting().getApnTypes().stream()
                     .map(apnType -> new ThrottleStatus.Builder()
                             .setApnType(apnType)
@@ -1618,12 +1707,14 @@
      */
     public boolean isSimilarNetworkRequestRetryScheduled(
             @NonNull TelephonyNetworkRequest networkRequest, @TransportType int transport) {
+        long now = SystemClock.elapsedRealtime();
         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) {
+                        == DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS
+                        && entry.retryElapsedTime > now) {
                     if (entry.networkRequestList.isEmpty()) {
                         String msg = "Invalid data retry entry detected";
                         logl(msg);
@@ -1646,23 +1737,6 @@
     }
 
     /**
-     * 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.
@@ -1697,13 +1771,11 @@
                         && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork
                         && entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
                 .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
-        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.
      */
diff --git a/src/java/com/android/internal/telephony/data/DataServiceManager.java b/src/java/com/android/internal/telephony/data/DataServiceManager.java
index 957b703..2733aff 100644
--- a/src/java/com/android/internal/telephony/data/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/data/DataServiceManager.java
@@ -571,7 +571,9 @@
         // Read package name from resource overlay
         packageName = mPhone.getContext().getResources().getString(resourceId);
 
-        PersistableBundle b = getCarrierConfigSubset(carrierConfig);
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(), mPhone.getSubId(), carrierConfig);
         if (!b.isEmpty() && !TextUtils.isEmpty(b.getString(carrierConfig))) {
             // If carrier config overrides it, use the one from carrier config
             packageName = b.getString(carrierConfig, packageName);
@@ -619,7 +621,9 @@
         // Read package name from resource overlay
         className = mPhone.getContext().getResources().getString(resourceId);
 
-        PersistableBundle b = getCarrierConfigSubset(carrierConfig);
+        PersistableBundle b =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(), mPhone.getSubId(), carrierConfig);
         if (!b.isEmpty() && !TextUtils.isEmpty(b.getString(carrierConfig))) {
             // If carrier config overrides it, use the one from carrier config
             className = b.getString(carrierConfig, className);
@@ -628,17 +632,6 @@
         return className;
     }
 
-    @NonNull
-    private PersistableBundle getCarrierConfigSubset(String key) {
-        PersistableBundle configs = new PersistableBundle();
-        try {
-            configs = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(), key);
-        } catch (RuntimeException e) {
-            loge("CarrierConfigLoader is not available.");
-        }
-        return configs;
-    }
-
     private void sendCompleteMessage(Message msg, @DataServiceCallback.ResultCode int code) {
         if (msg != null) {
             msg.arg1 = code;
diff --git a/src/java/com/android/internal/telephony/data/DataSettingsManager.java b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
index f6b33ad..5178ae4 100644
--- a/src/java/com/android/internal/telephony/data/DataSettingsManager.java
+++ b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
@@ -28,7 +28,6 @@
 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.TelephonyManager.MobileDataPolicy;
@@ -46,8 +45,8 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SettingsObserver;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback;
+import com.android.internal.telephony.metrics.DeviceTelephonyPropertiesStats;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.util.TelephonyUtils;
@@ -396,16 +395,10 @@
     }
 
     private boolean isStandAloneOpportunistic(int subId) {
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(subId);
-            return subInfo != null && subInfo.isOpportunistic()
-                    && TextUtils.isEmpty(subInfo.getGroupUuid());
-        }
-        SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
-                subId, mPhone.getContext().getOpPackageName(),
-                mPhone.getContext().getAttributionTag());
-        return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null;
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(subId);
+        return subInfo != null && subInfo.isOpportunistic()
+                && TextUtils.isEmpty(subInfo.getGroupUuid());
     }
 
     /**
@@ -584,16 +577,11 @@
 
     /** Refresh the enabled mobile data policies from Telephony database */
     private void refreshEnabledMobileDataPolicy() {
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(mSubId);
-            if (subInfo != null) {
-                mEnabledMobileDataPolicy = getMobileDataPolicyEnabled(
-                        subInfo.getEnabledMobileDataPolicies());
-            }
-        } else {
-            mEnabledMobileDataPolicy = getMobileDataPolicyEnabled(SubscriptionController
-                    .getInstance().getEnabledMobileDataPolicies(mSubId));
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(mSubId);
+        if (subInfo != null) {
+            mEnabledMobileDataPolicy = getMobileDataPolicyEnabled(
+                    subInfo.getEnabledMobileDataPolicies());
         }
     }
 
@@ -624,6 +612,8 @@
         if (enable == isMobileDataPolicyEnabled(mobileDataPolicy)) {
             return;
         }
+        metricsRecordSetMobileDataPolicy(mobileDataPolicy);
+
         if (enable) {
             mEnabledMobileDataPolicy.add(mobileDataPolicy);
         } else {
@@ -632,23 +622,21 @@
 
         String enabledMobileDataPolicies = mEnabledMobileDataPolicy.stream().map(String::valueOf)
                 .collect(Collectors.joining(","));
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionManagerService.getInstance().setEnabledMobileDataPolicies(mSubId,
-                    enabledMobileDataPolicies);
-            logl(TelephonyUtils.mobileDataPolicyToString(mobileDataPolicy) + " changed to "
-                    + enable);
-            updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
-            notifyDataEnabledOverrideChanged(enable, mobileDataPolicy);
-        } else {
-            if (SubscriptionController.getInstance().setEnabledMobileDataPolicies(
-                    mSubId, enabledMobileDataPolicies)) {
-                logl(TelephonyUtils.mobileDataPolicyToString(mobileDataPolicy) + " changed to "
-                        + enable);
-                updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
-                notifyDataEnabledOverrideChanged(enable, mobileDataPolicy);
-            } else {
-                loge("onSetMobileDataPolicy: failed to set " + enabledMobileDataPolicies);
-            }
+        SubscriptionManagerService.getInstance().setEnabledMobileDataPolicies(mSubId,
+                enabledMobileDataPolicies);
+        logl(TelephonyUtils.mobileDataPolicyToString(mobileDataPolicy) + " changed to "
+                + enable);
+        updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
+        notifyDataEnabledOverrideChanged(enable, mobileDataPolicy);
+    }
+
+    /**
+     * Record the number of times a mobile data policy is toggled to metrics.
+     * @param mobileDataPolicy The mobile data policy that's toggled
+     */
+    private void metricsRecordSetMobileDataPolicy(@MobileDataPolicy int mobileDataPolicy) {
+        if (mobileDataPolicy == TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH) {
+            DeviceTelephonyPropertiesStats.recordAutoDataSwitchFeatureToggle();
         }
     }
 
@@ -732,38 +720,25 @@
             overridden = apnType == ApnSetting.TYPE_MMS;
         }
 
-        boolean isNonDds;
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            isNonDds = mPhone.getSubId() != SubscriptionManagerService.getInstance()
-                    .getDefaultDataSubId();
-        } else {
-            isNonDds = mPhone.getSubId() != SubscriptionController.getInstance()
-                    .getDefaultDataSubId();
-        }
+        boolean isNonDds = mPhone.getSubId() != SubscriptionManagerService.getInstance()
+                .getDefaultDataSubId();
 
         // mobile data policy : data during call
         if (isMobileDataPolicyEnabled(TelephonyManager
                 .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL)) {
-            overridden = isNonDds && mPhone.getState() != PhoneConstants.State.IDLE;
+            overridden = overridden || isNonDds && mPhone.getState() != PhoneConstants.State.IDLE;
         }
 
         // mobile data policy : auto data switch
         if (isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH)) {
-            Phone defaultDataPhone;
-            if (mPhone.isSubscriptionManagerServiceEnabled()) {
-                // check user enabled data on the default data phone
-                defaultDataPhone = PhoneFactory.getPhone(SubscriptionManagerService.getInstance()
-                        .getPhoneId(SubscriptionManagerService.getInstance()
-                                .getDefaultDataSubId()));
-            } else {
-                // check user enabled data on the default data phone
-                defaultDataPhone = PhoneFactory.getPhone(SubscriptionController.getInstance()
-                        .getPhoneId(SubscriptionController.getInstance().getDefaultDataSubId()));
-            }
+            // check user enabled data on the default data phone
+            Phone defaultDataPhone = PhoneFactory.getPhone(SubscriptionManagerService.getInstance()
+                    .getPhoneId(SubscriptionManagerService.getInstance()
+                            .getDefaultDataSubId()));
             if (defaultDataPhone == null) {
                 loge("isDataEnabledOverriddenForApn: unexpected defaultDataPhone is null");
             } else {
-                overridden = isNonDds && defaultDataPhone.isUserDataEnabled();
+                overridden = overridden || isNonDds && defaultDataPhone.isUserDataEnabled();
             }
         }
         return overridden;
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
index 7b4e5af..6c6f064 100644
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.data;
 
+import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.IntDef;
@@ -32,7 +34,6 @@
 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;
 
@@ -146,7 +147,7 @@
     private final @NonNull DataServiceManager mWwanDataServiceManager;
 
     /** The data stall recovery action. */
-    private @RecoveryAction int mRecovryAction;
+    private @RecoveryAction int mRecoveryAction;
     /** The elapsed real time of last recovery attempted */
     private @ElapsedRealtimeLong long mTimeLastRecoveryStartMs;
     /** Whether current network is good or not */
@@ -267,7 +268,7 @@
 
                     @Override
                     public void onInternetDataNetworkConnected(
-                            @NonNull List<DataProfile> dataProfiles) {
+                            @NonNull List<DataNetwork> internetNetworks) {
                         mIsInternetNetworkConnected = true;
                         logl("onInternetDataNetworkConnected");
                     }
@@ -365,7 +366,7 @@
         cancelNetworkCheckTimer();
         mTimeLastRecoveryStartMs = 0;
         mLastAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
-        mRecovryAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
+        mRecoveryAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
     }
 
     /**
@@ -405,8 +406,8 @@
     @VisibleForTesting
     @RecoveryAction
     public int getRecoveryAction() {
-        log("getRecoveryAction: " + recoveryActionToString(mRecovryAction));
-        return mRecovryAction;
+        log("getRecoveryAction: " + recoveryActionToString(mRecoveryAction));
+        return mRecoveryAction;
     }
 
     /**
@@ -416,24 +417,24 @@
      */
     @VisibleForTesting
     public void setRecoveryAction(@RecoveryAction int action) {
-        mRecovryAction = action;
+        mRecoveryAction = 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;
+                && mRecoveryAction < RECOVERY_ACTION_RADIO_RESTART) {
+            mRecoveryAction = 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;
+            mRecoveryAction = RECOVERY_ACTION_RESET_MODEM;
         }
         // To check the flag from DataConfigManager if we need to skip the step.
-        if (shouldSkipRecoveryAction(mRecovryAction)) {
-            switch (mRecovryAction) {
+        if (shouldSkipRecoveryAction(mRecoveryAction)) {
+            switch (mRecoveryAction) {
                 case RECOVERY_ACTION_GET_DATA_CALL_LIST:
                     setRecoveryAction(RECOVERY_ACTION_CLEANUP);
                     break;
@@ -449,7 +450,7 @@
             }
         }
 
-        log("setRecoveryAction: " + recoveryActionToString(mRecovryAction));
+        log("setRecoveryAction: " + recoveryActionToString(mRecoveryAction));
     }
 
     /**
@@ -489,7 +490,7 @@
         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);
+        mPhone.getContext().sendBroadcast(intent, READ_PRIVILEGED_PHONE_STATE);
     }
 
     /** Recovery Action: RECOVERY_ACTION_GET_DATA_CALL_LIST */
@@ -640,7 +641,10 @@
 
         if (isLogNeeded) {
             timeDurationOfCurrentAction =
-                (isFirstDataStall == true ? 0 : (int) getDurationOfCurrentRecoveryMs());
+                ((getRecoveryAction() > RECOVERY_ACTION_GET_DATA_CALL_LIST
+                   && !mIsAttemptedAllSteps)
+                 || mLastAction == RECOVERY_ACTION_RESET_MODEM)
+                 ? (int) getDurationOfCurrentRecoveryMs() : 0;
             DataStallRecoveryStats.onDataStallEvent(
                     mLastAction, mPhone, isValid, timeDuration, reason,
                     isFirstValidationAfterDoRecovery, timeDurationOfCurrentAction);
diff --git a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
index 5ceb5e4..5ed12aa 100644
--- a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
@@ -458,6 +458,23 @@
         long txBytesDelta = mobileTxBytes - mLastMobileTxBytes;
         long rxBytesDelta = mobileRxBytes - mLastMobileRxBytes;
 
+        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)));
+        }
+
         // Schedule the next traffic stats poll
         sendEmptyMessageDelayed(MSG_TRAFFIC_STATS_POLL, TRAFFIC_STATS_POLL_INTERVAL_MS);
 
@@ -506,23 +523,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) {
@@ -678,7 +678,7 @@
                 return;
             }
             int linkBandwidthKbps = (int) linkBandwidthLongKbps;
-            mBwSampleValid = true;
+            mBwSampleValid = linkBandwidthKbps > 0;
             mBwSampleKbps = linkBandwidthKbps;
 
             String dataRatName = getDataRatName(mDataRat);
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 1ff7fde..5e13f6b 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -86,8 +86,6 @@
 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;
@@ -97,6 +95,7 @@
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.WatchedInt;
 import com.android.internal.telephony.util.NotificationChannelController;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
@@ -206,7 +205,6 @@
 
     private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
     protected final RegistrantList mActivePhoneRegistrants;
-    protected final SubscriptionController mSubscriptionController;
     private final SubscriptionManagerService mSubscriptionManagerService;
     protected final Context mContext;
     private final LocalLog mLocalLog;
@@ -276,14 +274,8 @@
     protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
 
     // Subscription ID corresponds to mPreferredDataPhoneId.
-    protected WatchedInt mPreferredDataSubId =
-            new WatchedInt(SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-        @Override
-        public void set(int newValue) {
-            super.set(newValue);
-            SubscriptionManager.invalidateActiveDataSubIdCaches();
-        }
-    };
+    protected WatchedInt mPreferredDataSubId = new WatchedInt(
+            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
     // If non-null, An emergency call is about to be started, is ongoing, or has just ended and we
     // are overriding the DDS.
@@ -292,18 +284,8 @@
 
     private ISetOpportunisticDataCallback mSetOpptSubCallback;
 
-    /** Data config manager callback for updating device config. **/
-    private final DataConfigManager.DataConfigManagerCallback mDataConfigManagerCallback =
-            new DataConfigManager.DataConfigManagerCallback(this::post) {
-        @Override
-        public void onDeviceConfigChanged() {
-            log("onDeviceConfigChanged");
-            PhoneSwitcher.this.updateConfig();
-        }
-    };
-
     private static final int EVENT_PRIMARY_DATA_SUB_CHANGED       = 101;
-    protected static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
+    protected static final int EVENT_SUBSCRIPTION_CHANGED         = 102;
     private static final int EVENT_REQUEST_NETWORK                = 103;
     private static final int EVENT_RELEASE_NETWORK                = 104;
     // ECBM has started/ended. If we just ended an emergency call and mEmergencyOverride is not
@@ -362,6 +344,12 @@
     private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
 
     /**
+     * {@code true} if requires ping test before switching preferred data modem; otherwise, switch
+     * even if ping test fails.
+     */
+    private boolean mRequirePingTestBeforeDataSwitch = true;
+
+    /**
      * Time threshold in ms to define a internet connection status to be stable(e.g. out of service,
      * in service, wifi is the default active network.etc), while -1 indicates auto switch
      * feature disabled.
@@ -371,8 +359,7 @@
     /**
      * The maximum number of retries when a validation for switching failed.
      */
-    private int mAutoDataSwitchValidationMaxRetry =
-            DataConfigManager.DEFAULT_AUTO_DATA_SWITCH_MAX_RETRY;
+    private int mAutoDataSwitchValidationMaxRetry;
 
     /** Data settings manager callback. Key is the phone id. */
     private final @NonNull Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
@@ -464,7 +451,6 @@
     public static PhoneSwitcher make(int maxDataAttachModemCount, Context context, Looper looper) {
         if (sPhoneSwitcher == null) {
             sPhoneSwitcher = new PhoneSwitcher(maxDataAttachModemCount, context, looper);
-            SubscriptionManager.invalidateActiveDataSubIdCaches();
         }
 
         return sPhoneSwitcher;
@@ -531,13 +517,7 @@
         mMaxDataAttachModemCount = maxActivePhones;
         mLocalLog = new LocalLog(MAX_LOCAL_LOG_LINES);
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService = SubscriptionManagerService.getInstance();
-            mSubscriptionController = null;
-        } else {
-            mSubscriptionController = SubscriptionController.getInstance();
-            mSubscriptionManagerService = null;
-        }
+        mSubscriptionManagerService = SubscriptionManagerService.getInstance();
 
         mRadioConfig = RadioConfig.getInstance();
         mValidator = CellularNetworkValidator.getInstance();
@@ -583,6 +563,8 @@
             PhoneFactory.getPhone(0).mCi.registerForOn(this, EVENT_RADIO_ON, null);
         }
 
+        readDeviceResourceConfig();
+
         TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
                 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
         telephonyRegistryManager.addOnSubscriptionsChangedListener(
@@ -663,16 +645,9 @@
             return false;
         }
 
-        SubscriptionInfo info;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            info = mSubscriptionManagerService
-                    .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
-                            mContext.getOpPackageName(), mContext.getAttributionTag());
-        } else {
-            info = mSubscriptionController
-                    .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
-                            mContext.getOpPackageName(), null);
-        }
+        SubscriptionInfo info = mSubscriptionManagerService
+                .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
+                        mContext.getOpPackageName(), mContext.getAttributionTag());
         boolean uiccAppsEnabled = info != null && info.areUiccApplicationsEnabled();
 
         IccCard iccCard = PhoneFactory.getPhone(slotIndex).getIccCard();
@@ -840,6 +815,9 @@
             }
             case EVENT_MODEM_COMMAND_RETRY: {
                 int phoneId = (int) msg.obj;
+                if (mActiveModemCount <= phoneId) {
+                    break;
+                }
                 if (isPhoneIdValidForRetry(phoneId)) {
                     logl("EVENT_MODEM_COMMAND_RETRY: resend modem command on phone " + phoneId);
                     sendRilCommands(phoneId);
@@ -905,50 +883,40 @@
                 break;
             }
             case EVENT_PROCESS_SIM_STATE_CHANGE: {
-                int slotIndex = (int) msg.arg1;
-                int simState = (int) msg.arg2;
+                int slotIndex = msg.arg1;
+                int simState = msg.arg2;
 
                 if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
                     logl("EVENT_PROCESS_SIM_STATE_CHANGE: skip processing due to invalid slotId: "
                             + slotIndex);
-                } else if (mCurrentDdsSwitchFailure.get(slotIndex).contains(
+                } else if (TelephonyManager.SIM_STATE_LOADED == simState) {
+                    if (mCurrentDdsSwitchFailure.get(slotIndex).contains(
                         CommandException.Error.INVALID_SIM_STATE)
                         && (TelephonyManager.SIM_STATE_LOADED == simState)
                         && isSimApplicationReady(slotIndex)) {
-                    sendRilCommands(slotIndex);
+                        sendRilCommands(slotIndex);
+                    }
+                    // SIM loaded after subscriptions slot mapping are done. Evaluate for auto
+                    // data switch.
+                    sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
                 }
-
-                registerConfigChange();
                 break;
             }
         }
     }
 
     /**
-     * Register for device config change on the primary data phone.
+     * Read the default device config from any default phone because the resource config are per
+     * device. No need to register callback for the same reason.
      */
-    private void registerConfigChange() {
-        Phone phone = getPhoneBySubId(mPrimaryDataSubId);
-        if (phone != null) {
-            DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
-            dataConfig.registerCallback(mDataConfigManagerCallback);
-            updateConfig();
-            sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
-        }
-    }
-
-    /**
-     * Update data config.
-     */
-    private void updateConfig() {
-        Phone phone = getPhoneBySubId(mPrimaryDataSubId);
-        if (phone != null) {
-            DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
-            mAutoDataSwitchAvailabilityStabilityTimeThreshold =
-                    dataConfig.getAutoDataSwitchAvailabilityStabilityTimeThreshold();
-            mAutoDataSwitchValidationMaxRetry =
-                    dataConfig.getAutoDataSwitchValidationMaxRetry();
-        }
+    private void readDeviceResourceConfig() {
+        Phone phone = PhoneFactory.getDefaultPhone();
+        DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
+        mRequirePingTestBeforeDataSwitch = dataConfig.isPingTestBeforeAutoDataSwitchRequired();
+        mAutoDataSwitchAvailabilityStabilityTimeThreshold =
+                dataConfig.getAutoDataSwitchAvailabilityStabilityTimeThreshold();
+        mAutoDataSwitchValidationMaxRetry =
+                dataConfig.getAutoDataSwitchValidationMaxRetry();
     }
 
     private synchronized void onMultiSimConfigChanged(int activeModemCount) {
@@ -1129,16 +1097,9 @@
         // auto data switch feature is disabled from server
         if (mAutoDataSwitchAvailabilityStabilityTimeThreshold < 0) return;
         // check is valid DSDS
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            if (!isActiveSubId(mPrimaryDataSubId) || mSubscriptionManagerService
-                    .getActiveSubIdList(true).length <= 1) {
-                return;
-            }
-        } else {
-            if (!isActiveSubId(mPrimaryDataSubId)
-                    || mSubscriptionController.getActiveSubIdList(true).length <= 1) {
-                return;
-            }
+        if (!isActiveSubId(mPrimaryDataSubId) || mSubscriptionManagerService
+                .getActiveSubIdList(true).length <= 1) {
+            return;
         }
 
         Phone primaryDataPhone = getPhoneBySubId(mPrimaryDataSubId);
@@ -1158,7 +1119,7 @@
 
             int candidateSubId = getAutoSwitchTargetSubIdIfExists();
             if (candidateSubId != INVALID_SUBSCRIPTION_ID) {
-                startAutoDataSwitchStabilityCheck(candidateSubId, true);
+                startAutoDataSwitchStabilityCheck(candidateSubId, mRequirePingTestBeforeDataSwitch);
             } else {
                 cancelPendingAutoDataSwitch();
             }
@@ -1193,7 +1154,8 @@
 
             if (isInService(mPhoneStates[primaryPhoneId])) {
                 // primary becomes available
-                startAutoDataSwitchStabilityCheck(DEFAULT_SUBSCRIPTION_ID, true);
+                startAutoDataSwitchStabilityCheck(DEFAULT_SUBSCRIPTION_ID,
+                        mRequirePingTestBeforeDataSwitch);
                 return;
             }
 
@@ -1317,12 +1279,7 @@
         boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged;
 
         // Check if user setting of default non-opportunistic data sub is changed.
-        int primaryDataSubId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            primaryDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
-        } else {
-            primaryDataSubId = mSubscriptionController.getDefaultDataSubId();
-        }
+        int primaryDataSubId = mSubscriptionManagerService.getDefaultDataSubId();
         if (primaryDataSubId != mPrimaryDataSubId) {
             sb.append(" mPrimaryDataSubId ").append(mPrimaryDataSubId).append("->")
                 .append(primaryDataSubId);
@@ -1425,7 +1382,7 @@
                     }
 
                     if (newActivePhones.size() < mMaxDataAttachModemCount
-                            && newActivePhones.contains(mPreferredDataPhoneId)
+                            && !newActivePhones.contains(mPreferredDataPhoneId)
                             && SubscriptionManager.isUsableSubIdValue(mPreferredDataPhoneId)) {
                         newActivePhones.add(mPreferredDataPhoneId);
                     }
@@ -1597,13 +1554,9 @@
     }
 
     private boolean isActiveSubId(int subId) {
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(subId);
-            return subInfo != null && subInfo.isActive();
-        } else {
-            return mSubscriptionController.isActiveSubId(subId);
-        }
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(subId);
+        return subInfo != null && subInfo.isActive();
     }
 
     // This updates mPreferredDataPhoneId which decides which phone should handle default network
@@ -1686,11 +1639,7 @@
     }
 
     private Phone getPhoneBySubId(int subId) {
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            return findPhoneById(mSubscriptionManagerService.getPhoneId(subId));
-        } else {
-            return findPhoneById(mSubscriptionController.getPhoneId(subId));
-        }
+        return findPhoneById(mSubscriptionManagerService.getPhoneId(subId));
     }
 
     private Phone findPhoneById(final int phoneId) {
@@ -2067,8 +2016,8 @@
      * @param reason The switching reason.
      */
     private void logDataSwitchEvent(int subId, int state, int reason) {
-        logl("Data switch event. subId=" + subId + ", state=" + switchStateToString(state)
-                + ", reason=" + switchReasonToString(reason));
+        logl("Data switch state=" + switchStateToString(state) + " due to reason="
+                + switchReasonToString(reason) + " on subId " + subId);
         DataSwitch dataSwitch = new DataSwitch();
         dataSwitch.state = state;
         dataSwitch.reason = reason;
@@ -2121,15 +2070,9 @@
         }
         pw.println("mPreferredDataPhoneId=" + mPreferredDataPhoneId);
         pw.println("mPreferredDataSubId=" + mPreferredDataSubId.get());
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            pw.println("DefaultDataSubId=" + mSubscriptionManagerService.getDefaultDataSubId());
-            pw.println("DefaultDataPhoneId=" + mSubscriptionManagerService.getPhoneId(
-                    mSubscriptionManagerService.getDefaultDataSubId()));
-        } else {
-            pw.println("DefaultDataSubId=" + mSubscriptionController.getDefaultDataSubId());
-            pw.println("DefaultDataPhoneId=" + mSubscriptionController.getPhoneId(
-                    mSubscriptionController.getDefaultDataSubId()));
-        }
+        pw.println("DefaultDataSubId=" + mSubscriptionManagerService.getDefaultDataSubId());
+        pw.println("DefaultDataPhoneId=" + mSubscriptionManagerService.getPhoneId(
+                mSubscriptionManagerService.getDefaultDataSubId()));
         pw.println("mPrimaryDataSubId=" + mPrimaryDataSubId);
         pw.println("mAutoSelectedDataSubId=" + mAutoSelectedDataSubId);
         pw.println("mIsRegisteredForImsRadioTechChange=" + mIsRegisteredForImsRadioTechChange);
@@ -2141,6 +2084,7 @@
         pw.println("mAutoDataSwitchAvailabilityStabilityTimeThreshold="
                 + mAutoDataSwitchAvailabilityStabilityTimeThreshold);
         pw.println("mAutoDataSwitchValidationMaxRetry=" + mAutoDataSwitchValidationMaxRetry);
+        pw.println("mRequirePingTestBeforeDataSwitch=" + mRequirePingTestBeforeDataSwitch);
         pw.println("mLastSwitchPreferredDataReason="
                 + switchReasonToString(mLastSwitchPreferredDataReason));
         pw.println("mDisplayedAutoSwitchNotification=" + mDisplayedAutoSwitchNotification);
@@ -2215,12 +2159,8 @@
                     + switchReasonToString(mLastSwitchPreferredDataReason));
             return;
         }
-        SubscriptionInfo subInfo;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            subInfo = mSubscriptionManagerService.getSubscriptionInfo(mAutoSelectedDataSubId);
-        } else {
-            subInfo = mSubscriptionController.getSubscriptionInfo(mAutoSelectedDataSubId);
-        }
+        SubscriptionInfo subInfo = mSubscriptionManagerService
+                .getSubscriptionInfo(mAutoSelectedDataSubId);
         if (subInfo == null || subInfo.isOpportunistic()) {
             loge("displayAutoDataSwitchNotification: mAutoSelectedDataSubId="
                     + mAutoSelectedDataSubId + " unexpected subInfo " + subInfo);
@@ -2259,14 +2199,8 @@
     }
 
     private boolean isPhoneIdValidForRetry(int phoneId) {
-        int ddsPhoneId;
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            ddsPhoneId = mSubscriptionManagerService.getPhoneId(
-                    mSubscriptionManagerService.getDefaultDataSubId());
-        } else {
-            ddsPhoneId = mSubscriptionController.getPhoneId(
-                    mSubscriptionController.getDefaultDataSubId());
-        }
+        int ddsPhoneId = mSubscriptionManagerService.getPhoneId(
+                mSubscriptionManagerService.getDefaultDataSubId());
         if (ddsPhoneId != INVALID_PHONE_INDEX && ddsPhoneId == phoneId) {
             return true;
         } else {
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
new file mode 100644
index 0000000..9a75b43
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
@@ -0,0 +1,467 @@
+/*
+ * 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.domainselection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.AsyncResult;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.EmergencyScanType;
+import android.telephony.DomainSelector;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.util.TelephonyUtils;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+
+
+/**
+ * Manages the information of request and the callback binder.
+ */
+public class DomainSelectionConnection {
+
+    private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE;
+
+    protected static final int EVENT_EMERGENCY_NETWORK_SCAN_RESULT = 1;
+    protected static final int EVENT_QUALIFIED_NETWORKS_CHANGED = 2;
+
+    /** Callback to receive responses from DomainSelectionConnection. */
+    public interface DomainSelectionConnectionCallback {
+        /**
+         * Notifies that selection has terminated because there is no decision that can be made
+         * or a timeout has occurred. The call should be terminated when this method is called.
+         *
+         * @param cause Indicates the reason.
+         */
+        void onSelectionTerminated(@DisconnectCauses int cause);
+    }
+
+    /** An internal class implementing {@link TransportSelectorCallback} interface. */
+    private final class TransportSelectorCallbackWrapper implements TransportSelectorCallback {
+        @Override
+        public void onCreated(@NonNull DomainSelector selector) {
+            mDomainSelector = selector;
+            DomainSelectionConnection.this.onCreated();
+        }
+
+        @Override
+        public void onWlanSelected(boolean useEmergencyPdn) {
+            DomainSelectionConnection.this.onWlanSelected(useEmergencyPdn);
+        }
+
+        @Override
+        public @NonNull WwanSelectorCallback onWwanSelected() {
+            if (mWwanSelectorCallback == null) {
+                mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+            }
+            DomainSelectionConnection.this.onWwanSelected();
+            return mWwanSelectorCallback;
+        }
+
+        @Override
+        public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
+            if (mWwanSelectorCallback == null) {
+                mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+            }
+            if (mWwanSelectedExecutor == null) {
+                mWwanSelectedExecutor = Executors.newSingleThreadExecutor();
+            }
+            mWwanSelectedExecutor.execute(() -> {
+                DomainSelectionConnection.this.onWwanSelected();
+                consumer.accept(mWwanSelectorCallback);
+            });
+        }
+
+        @Override
+        public void onSelectionTerminated(int cause) {
+            DomainSelectionConnection.this.onSelectionTerminated(cause);
+            dispose();
+        }
+    }
+
+    /** An internal class implementing {@link WwanSelectorCallback} interface. */
+    private final class WwanSelectorCallbackWrapper
+            implements WwanSelectorCallback, CancellationSignal.OnCancelListener {
+        @Override
+        public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
+                @EmergencyScanType int scanType, @NonNull CancellationSignal signal,
+                @NonNull Consumer<EmergencyRegResult> consumer) {
+            if (signal != null) signal.setOnCancelListener(this);
+            mResultCallback = consumer;
+            initHandler();
+            DomainSelectionConnection.this.onRequestEmergencyNetworkScan(
+                    preferredNetworks.stream().mapToInt(Integer::intValue).toArray(), scanType);
+        }
+
+        @Override
+        public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+                boolean useEmergencyPdn) {
+            DomainSelectionConnection.this.onDomainSelected(domain, useEmergencyPdn);
+        }
+
+        @Override
+        public void onCancel() {
+            DomainSelectionConnection.this.onCancel();
+        }
+    }
+
+    protected final class DomainSelectionConnectionHandler extends Handler {
+        DomainSelectionConnectionHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_EMERGENCY_NETWORK_SCAN_RESULT:
+                    mIsWaitingForScanResult = false;
+                    if (mResultCallback == null) break;
+                    ar = (AsyncResult) msg.obj;
+                    EmergencyRegResult regResult = (EmergencyRegResult) ar.result;
+                    if (DBG) logd("EVENT_EMERGENCY_NETWORK_SCAN_RESULT result=" + regResult);
+                    CompletableFuture.runAsync(
+                            () -> mResultCallback.accept(regResult),
+                            mController.getDomainSelectionServiceExecutor()).join();
+                    break;
+                case EVENT_QUALIFIED_NETWORKS_CHANGED:
+                    onQualifiedNetworksChanged();
+                    break;
+                default:
+                    loge("handleMessage unexpected msg=" + msg.what);
+                    break;
+            }
+        }
+    }
+
+    protected String mTag = "DomainSelectionConnection";
+
+    private final LocalLog mLocalLog = new LocalLog(30);
+    private final @NonNull TransportSelectorCallback mTransportSelectorCallback;
+
+    /**
+     * Controls the communication between {@link DomainSelectionConnection} and
+     * {@link DomainSelectionService}.
+     */
+    private final @NonNull DomainSelectionController mController;
+    /** Indicates whether the requested service is for emergency services. */
+    private final boolean mIsEmergency;
+
+    /** Interface to receive the request to trigger emergency network scan and selected domain. */
+    private @Nullable WwanSelectorCallback mWwanSelectorCallback;
+    /** Interface to return the result of emergency network scan. */
+    private @Nullable Consumer<EmergencyRegResult> mResultCallback;
+    /** Interface to the {@link DomainSelector} created for this service. */
+    private @Nullable DomainSelector mDomainSelector;
+
+    /** The slot requested this connection. */
+    protected @NonNull Phone mPhone;
+    /** The requested domain selector type. */
+    private @DomainSelectionService.SelectorType int mSelectorType;
+
+    /** The attributes required to determine the domain. */
+    private @Nullable DomainSelectionService.SelectionAttributes mSelectionAttributes;
+
+    private @Nullable Looper mLooper;
+    protected @Nullable DomainSelectionConnectionHandler mHandler;
+    private boolean mRegisteredRegistrant;
+    private boolean mIsWaitingForScanResult;
+
+    private @NonNull AndroidFuture<Integer> mOnComplete;
+
+    private @Nullable Executor mWwanSelectedExecutor;
+
+    /**
+     * Creates an instance.
+     *
+     * @param phone For which this service is requested.
+     * @param selectorType Indicates the type of the requested service.
+     * @param isEmergency Indicates whether this request is for emergency service.
+     * @param controller The controller to communicate with the domain selection service.
+     */
+    public DomainSelectionConnection(@NonNull Phone phone,
+            @DomainSelectionService.SelectorType int selectorType, boolean isEmergency,
+            @NonNull DomainSelectionController controller) {
+        mController = controller;
+        mPhone = phone;
+        mSelectorType = selectorType;
+        mIsEmergency = isEmergency;
+
+        mTransportSelectorCallback = new TransportSelectorCallbackWrapper();
+        mOnComplete = new AndroidFuture<>();
+    }
+
+    /**
+     * Returns the attributes required to determine the domain for a telephony service.
+     *
+     * @return The attributes required to determine the domain.
+     */
+    public @Nullable DomainSelectionService.SelectionAttributes getSelectionAttributes() {
+        return mSelectionAttributes;
+    }
+
+    /**
+     * Returns the interface for the callbacks.
+     *
+     * @return The {@link TransportSelectorCallback} interface.
+     */
+    @VisibleForTesting
+    public @NonNull TransportSelectorCallback getTransportSelectorCallback() {
+        return mTransportSelectorCallback;
+    }
+
+    /**
+     * Returns the {@link CompletableFuture} to receive the selected domain.
+     *
+     * @return The callback to receive response.
+     */
+    public @NonNull CompletableFuture<Integer> getCompletableFuture() {
+        return mOnComplete;
+    }
+
+    /**
+     * Returs the {@link Phone} which requested this connection.
+     *
+     * @return The {@link Phone} instance.
+     */
+    public @NonNull Phone getPhone() {
+        return mPhone;
+    }
+
+    /**
+     * Requests the domain selection servic to select a domain.
+     *
+     * @param attr The attributes required to determine the domain.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
+    public void selectDomain(@NonNull DomainSelectionService.SelectionAttributes attr) {
+        mSelectionAttributes = attr;
+        mController.selectDomain(attr, getTransportSelectorCallback());
+    }
+
+    /**
+     * Notifies that {@link DomainSelector} instance has been created for the selection request.
+     */
+    public void onCreated() {
+        // Can be overridden if required
+    }
+
+    /**
+     * Notifies that WLAN transport has been selected.
+     */
+    public void onWlanSelected() {
+        // Can be overridden.
+    }
+
+    /**
+     * Notifies that WLAN transport has been selected.
+     *
+     * @param useEmergencyPdn Indicates whether Wi-Fi emergency services use emergency PDN or not.
+     */
+    public void onWlanSelected(boolean useEmergencyPdn) {
+        // Can be overridden.
+        onWlanSelected();
+    }
+
+    /**
+     * Notifies that WWAN transport has been selected.
+     */
+    public void onWwanSelected() {
+        // Can be overridden.
+    }
+
+    /**
+     * Notifies that selection has terminated because there is no decision that can be made
+     * or a timeout has occurred. The call should be terminated when this method is called.
+     *
+     * @param cause Indicates the reason.
+     */
+    public void onSelectionTerminated(@DisconnectCauses int cause) {
+        // Can be overridden.
+    }
+
+    /**
+     * Requests the emergency network scan.
+     *
+     * @param preferredNetworks The ordered list of preferred networks to scan.
+     * @param scanType Indicates the scan preference, such as full service or limited service.
+     */
+    public void onRequestEmergencyNetworkScan(
+            @NonNull @RadioAccessNetworkType int[] preferredNetworks,
+            @EmergencyScanType int scanType) {
+        // Can be overridden if required
+        if (!mRegisteredRegistrant) {
+            mPhone.registerForEmergencyNetworkScan(mHandler,
+                    EVENT_EMERGENCY_NETWORK_SCAN_RESULT, null);
+            mRegisteredRegistrant = true;
+        }
+        mIsWaitingForScanResult = true;
+        mPhone.triggerEmergencyNetworkScan(preferredNetworks, scanType, null);
+    }
+
+    /**
+     * Notifies the domain selected.
+     *
+     * @param domain The selected domain.
+     */
+    public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain) {
+        // Can be overridden if required
+        CompletableFuture<Integer> future = getCompletableFuture();
+        future.complete(domain);
+    }
+
+    /**
+     * Notifies the domain selected.
+     *
+     * @param domain The selected domain.
+     * @param useEmergencyPdn Indicates whether emergency services use emergency PDN or not.
+     */
+    public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+            boolean useEmergencyPdn) {
+        // Can be overridden if required
+        onDomainSelected(domain);
+    }
+
+    /**
+     * Notifies that the emergency network scan is canceled.
+     */
+    public void onCancel() {
+        // Can be overridden if required
+        onCancel(false);
+    }
+
+    private void onCancel(boolean resetScan) {
+        if (mIsWaitingForScanResult) {
+            mIsWaitingForScanResult = false;
+            mPhone.cancelEmergencyNetworkScan(resetScan, null);
+        }
+    }
+
+    /**
+     * Cancels an ongoing selection operation. It is up to the {@link DomainSelectionService}
+     * to clean up all ongoing operations with the framework.
+     */
+    public void cancelSelection() {
+        if (mDomainSelector == null) return;
+        mDomainSelector.cancelSelection();
+        dispose();
+    }
+
+    /**
+     * Requests the domain selection service to reselect a domain.
+     *
+     * @param attr The attributes required to determine the domain.
+     * @return The callback to receive the response.
+     */
+    public @NonNull CompletableFuture<Integer> reselectDomain(
+            @NonNull DomainSelectionService.SelectionAttributes attr) {
+        mSelectionAttributes = attr;
+        if (mDomainSelector == null) return null;
+        mOnComplete = new AndroidFuture<>();
+        mDomainSelector.reselectDomain(attr);
+        return mOnComplete;
+    }
+
+    /**
+     * Finishes the selection procedure and cleans everything up.
+     */
+    public void finishSelection() {
+        if (mDomainSelector == null) return;
+        mDomainSelector.finishSelection();
+        dispose();
+    }
+
+    /** Indicates that the service connection has been removed. */
+    public void onServiceDisconnected() {
+        // Can be overridden.
+        dispose();
+    }
+
+    private void dispose() {
+        if (mRegisteredRegistrant) {
+            mPhone.unregisterForEmergencyNetworkScan(mHandler);
+            mRegisteredRegistrant = false;
+        }
+        onCancel(true);
+        mController.removeConnection(this);
+        if (mLooper != null) mLooper.quitSafely();
+        mLooper = null;
+        mHandler = null;
+    }
+
+    protected void initHandler() {
+        if (mLooper == null) {
+            HandlerThread handlerThread = new HandlerThread(mTag);
+            handlerThread.start();
+            mLooper = handlerThread.getLooper();
+        }
+        if (mHandler == null) mHandler = new DomainSelectionConnectionHandler(mLooper);
+    }
+
+    /**
+     * Notifies the change of qualified networks.
+     */
+    protected void onQualifiedNetworksChanged() {
+        if (mIsEmergency
+                && (mSelectorType == DomainSelectionService.SELECTOR_TYPE_CALLING)) {
+            // DomainSelectionConnection for emergency calls shall override this.
+            throw new IllegalStateException("DomainSelectionConnection for emergency calls"
+                    + " should override onQualifiedNetworksChanged()");
+        }
+    }
+
+    /**
+     * Dumps local log.
+     */
+    public void dump(@NonNull PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    protected void logd(String msg) {
+        Log.d(mTag, msg);
+    }
+
+    protected void logi(String msg) {
+        Log.i(mTag, msg);
+        mLocalLog.log(msg);
+    }
+
+    protected void loge(String msg) {
+        Log.e(mTag, msg);
+        mLocalLog.log(msg);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionController.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionController.java
new file mode 100644
index 0000000..52c9960
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionController.java
@@ -0,0 +1,299 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.BarringInfo;
+import android.telephony.DomainSelectionService;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.TransportSelectorCallback;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.util.TelephonyUtils;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+
+/**
+ * Manages the connection to {@link DomainSelectionService}.
+ */
+public class DomainSelectionController {
+    private static final String TAG = "DomainSelectionController";
+    private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE;
+
+    private static final int EVENT_SERVICE_STATE_CHANGED = 1;
+    private static final int EVENT_BARRING_INFO_CHANGED = 2;
+
+    private final HandlerThread mHandlerThread =
+            new HandlerThread("DomainSelectionControllerHandler");
+
+    private final DomainSelectionService mDomainSelectionService;
+    private final Handler mHandler;
+    // Only added or removed, never accessed on purpose.
+    private final LocalLog mLocalLog = new LocalLog(30);
+
+    protected final Object mLock = new Object();
+    protected final Context mContext;
+
+    protected final int[] mConnectionCounts;
+    private final ArrayList<DomainSelectionConnection> mConnections = new ArrayList<>();
+
+    private final class DomainSelectionControllerHandler extends Handler {
+        DomainSelectionControllerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_SERVICE_STATE_CHANGED:
+                    ar = (AsyncResult) msg.obj;
+                    updateServiceState((Phone) ar.userObj, (ServiceState) ar.result);
+                    break;
+                case EVENT_BARRING_INFO_CHANGED:
+                    ar = (AsyncResult) msg.obj;
+                    updateBarringInfo((Phone) ar.userObj, (BarringInfo) ar.result);
+                    break;
+                default:
+                    loge("unexpected event=" + msg.what);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Creates an instance.
+     *
+     * @param context Context object from hosting application.
+     * @param service The {@link DomainSelectionService} instance.
+     */
+    public DomainSelectionController(@NonNull Context context,
+            @NonNull DomainSelectionService service) {
+        this(context, service, null);
+    }
+
+    /**
+     * Creates an instance.
+     *
+     * @param context Context object from hosting application.
+     * @param service The {@link DomainSelectionService} instance.
+     * @param looper Handles event messages.
+     */
+    @VisibleForTesting
+    public DomainSelectionController(@NonNull Context context,
+            @NonNull DomainSelectionService service, @Nullable Looper looper) {
+        mContext = context;
+        mDomainSelectionService = service;
+
+        if (looper == null) {
+            mHandlerThread.start();
+            looper = mHandlerThread.getLooper();
+        }
+        mHandler = new DomainSelectionControllerHandler(looper);
+
+        int numPhones = TelephonyManager.getDefault().getActiveModemCount();
+        mConnectionCounts = new int[numPhones];
+        for (int i = 0; i < numPhones; i++) {
+            mConnectionCounts[i] = 0;
+        }
+    }
+
+    /**
+     * Returns a {@link DomainSelectionConnection} instance.
+     *
+     * @param phone Indicates who requests the service.
+     * @param selectorType Indicates the selector type requested.
+     * @param isEmergency Indicates whether this is for emergency service.
+     * @return A {@link DomainSelectiionConnection} instance for the requested service.
+     *         Returns {@code null} if the requested service is not supported.
+     */
+    public @Nullable DomainSelectionConnection getDomainSelectionConnection(
+            @NonNull Phone phone,
+            @DomainSelectionService.SelectorType int selectorType,
+            boolean isEmergency) {
+        DomainSelectionConnection c = null;
+
+        if (selectorType == SELECTOR_TYPE_CALLING) {
+            if (isEmergency) {
+                c = new EmergencyCallDomainSelectionConnection(phone, this);
+            } else {
+                c = new NormalCallDomainSelectionConnection(phone, this);
+            }
+        } else if (selectorType == SELECTOR_TYPE_SMS) {
+            if (isEmergency) {
+                c = new EmergencySmsDomainSelectionConnection(phone, this);
+            } else {
+                c = new SmsDomainSelectionConnection(phone, this);
+            }
+        }
+
+        addConnection(c);
+        return c;
+    }
+
+    private void addConnection(@Nullable DomainSelectionConnection c) {
+        if (c == null) return;
+        mConnections.add(c);
+        registerForStateChange(c);
+    }
+
+    /**
+     * Releases resources for this connection.
+     */
+    public void removeConnection(@Nullable DomainSelectionConnection c) {
+        if (c == null) return;
+        mConnections.remove(c);
+        unregisterForStateChange(c);
+    }
+
+    /**
+     * Requests the domain selection.
+     *
+     * @param attr Attributetes required to determine the domain.
+     * @param callback A callback to receive the response.
+     */
+    public void selectDomain(@NonNull DomainSelectionService.SelectionAttributes attr,
+            @NonNull TransportSelectorCallback callback) {
+        if (attr == null || callback == null) return;
+        if (DBG) logd("selectDomain");
+
+        Executor e = mDomainSelectionService.getCachedExecutor();
+        e.execute(() -> mDomainSelectionService.onDomainSelection(attr, callback));
+    }
+
+    /**
+     * Notifies the change in {@link ServiceState} for a specific slot.
+     *
+     * @param phone {@link Phone} which the state changed.
+     * @param serviceState Updated {@link ServiceState}.
+     */
+    private void updateServiceState(Phone phone, ServiceState serviceState) {
+        if (phone == null || serviceState == null) return;
+        if (DBG) logd("updateServiceState phoneId=" + phone.getPhoneId());
+
+        Executor e = mDomainSelectionService.getCachedExecutor();
+        e.execute(() -> mDomainSelectionService.onServiceStateUpdated(
+                phone.getPhoneId(), phone.getSubId(), serviceState));
+    }
+
+    /**
+     * Notifies the change in {@link BarringInfo} for a specific slot.
+     *
+     * @param phone {@link Phone} which the state changed.
+     * @param info Updated {@link BarringInfo}.
+     */
+    private void updateBarringInfo(Phone phone, BarringInfo info) {
+        if (phone == null || info == null) return;
+        if (DBG) logd("updateBarringInfo phoneId=" + phone.getPhoneId());
+
+        Executor e = mDomainSelectionService.getCachedExecutor();
+        e.execute(() -> mDomainSelectionService.onBarringInfoUpdated(
+                phone.getPhoneId(), phone.getSubId(), info));
+    }
+
+    /**
+     * Registers for the notification of {@link ServiceState} and {@link BarringInfo}.
+     *
+     * @param c {@link DomainSelectionConnection} for which the registration is requested.
+     */
+    private void registerForStateChange(DomainSelectionConnection c) {
+        Phone phone = c.getPhone();
+        int count = mConnectionCounts[phone.getPhoneId()];
+        if (count < 0) count = 0;
+
+        mConnectionCounts[phone.getPhoneId()] = count + 1;
+        if (count > 0) return;
+
+        phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, phone);
+        phone.mCi.registerForBarringInfoChanged(mHandler, EVENT_BARRING_INFO_CHANGED, phone);
+
+        updateServiceState(phone, phone.getServiceStateTracker().getServiceState());
+        updateBarringInfo(phone, phone.mCi.getLastBarringInfo());
+    }
+
+    /**
+     * Unregisters for the notification of {@link ServiceState} and {@link BarringInfo}.
+     *
+     * @param c {@link DomainSelectionConnection} for which the unregistration is requested.
+     */
+    private void unregisterForStateChange(DomainSelectionConnection c) {
+        Phone phone = c.getPhone();
+        int count = mConnectionCounts[phone.getPhoneId()];
+        if (count < 1) count = 1;
+
+        mConnectionCounts[phone.getPhoneId()] = count - 1;
+        if (count > 1) return;
+
+        phone.unregisterForServiceStateChanged(mHandler);
+        phone.mCi.unregisterForBarringInfoChanged(mHandler);
+    }
+
+    /**
+     * Notifies the {@link DomainSelectionConnection} instances registered
+     * of the service disconnection.
+     */
+    private void notifyServiceDisconnected() {
+        for (DomainSelectionConnection c : mConnections) {
+            c.onServiceDisconnected();
+        }
+    }
+
+    /**
+     * Gets the {@link Executor} which executes methods of {@link DomainSelectionService.}
+     * @return {@link Executor} instance.
+     */
+    public @NonNull Executor getDomainSelectionServiceExecutor() {
+        return mDomainSelectionService.getCachedExecutor();
+    }
+
+    /**
+     * Dumps logcal log
+     */
+    public void dump(@NonNull PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    private void logd(String msg) {
+        Log.d(TAG, msg);
+    }
+
+    private void logi(String msg) {
+        Log.i(TAG, msg);
+        mLocalLog.log(msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(TAG, msg);
+        mLocalLog.log(msg);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionResolver.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionResolver.java
new file mode 100644
index 0000000..cbb74fa
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionResolver.java
@@ -0,0 +1,207 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+
+import static com.android.internal.telephony.RIL.RADIO_HAL_VERSION_2_1;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.telephony.DomainSelectionService;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * This class is an entry point to provide whether the AOSP domain selection is supported or not,
+ * and bind the {@link DomainSelectionController} with the given {@link DomainSelectionService} to
+ * provide a specific {@link DomainSelectionConnection} object for communicating with each domain
+ * selector.
+ */
+public class DomainSelectionResolver {
+    private static final String TAG = DomainSelectionResolver.class.getSimpleName();
+    private static DomainSelectionResolver sInstance = null;
+
+    /**
+     * Creates the DomainSelectionResolver singleton instance.
+     *
+     * @param context The context of the application.
+     * @param deviceConfigEnabled The flag to indicate whether or not the device supports
+     *                            the domain selection service or not.
+     */
+    public static void make(Context context, boolean deviceConfigEnabled) {
+        if (sInstance == null) {
+            sInstance = new DomainSelectionResolver(context, deviceConfigEnabled);
+        }
+    }
+
+    /**
+     * Returns the singleton instance of DomainSelectionResolver.
+     *
+     * @return A {@link DomainSelectionResolver} instance.
+     */
+    public static DomainSelectionResolver getInstance() {
+        if (sInstance == null) {
+            throw new IllegalStateException("DomainSelectionResolver is not ready!");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Sets a {@link DomainSelectionResolver} for injecting mock DomainSelectionResolver.
+     *
+     * @param resolver A {@link DomainSelectionResolver} instance to test.
+     */
+    @VisibleForTesting
+    public static void setDomainSelectionResolver(DomainSelectionResolver resolver) {
+        sInstance = resolver;
+    }
+
+    /**
+     * Testing interface for injecting mock DomainSelectionController.
+     */
+    @VisibleForTesting
+    public interface DomainSelectionControllerFactory {
+        /**
+         * Returns a {@link DomainSelectionController} created using the specified
+         * context and {@link DomainSelectionService} instance.
+         */
+        DomainSelectionController create(@NonNull Context context,
+                @NonNull DomainSelectionService service);
+    }
+
+    private DomainSelectionControllerFactory mDomainSelectionControllerFactory =
+            new DomainSelectionControllerFactory() {
+        @Override
+        public DomainSelectionController create(@NonNull Context context,
+                @NonNull DomainSelectionService service) {
+            return new DomainSelectionController(context, service);
+        }
+    };
+
+    // Persistent Logging
+    private final LocalLog mEventLog = new LocalLog(10);
+    private final Context mContext;
+    // The flag to indicate whether the device supports the domain selection service or not.
+    private final boolean mDeviceConfigEnabled;
+    // DomainSelectionController, which are bound to DomainSelectionService.
+    private DomainSelectionController mController;
+
+    public DomainSelectionResolver(Context context, boolean deviceConfigEnabled) {
+        mContext = context;
+        mDeviceConfigEnabled = deviceConfigEnabled;
+        logi("DomainSelectionResolver created: device-config=" + deviceConfigEnabled);
+    }
+
+    /**
+     * Checks if the device supports the domain selection service to route the call / SMS /
+     * supplementary services to the appropriate domain.
+     * This checks the device-config and Radio HAL version for supporting the domain selection.
+     * The domain selection requires the Radio HAL version greater than or equal to 2.1.
+     *
+     * @return {@code true} if the domain selection is supported on the device,
+     *         {@code false} otherwise.
+     */
+    public boolean isDomainSelectionSupported() {
+        return mDeviceConfigEnabled && PhoneFactory.getDefaultPhone()
+                .getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RADIO_HAL_VERSION_2_1);
+    }
+
+    /**
+     * Returns a {@link DomainSelectionConnection} instance.
+     *
+     * @param phone The Phone instance for witch this request is.
+     * @param selectorType Indicates the selector type requested.
+     * @param isEmergency Indicates whether this is for emergency service.
+     * @throws IllegalStateException If the {@link DomainSelectionController} is not created
+     *         because {@link #initialize} method is not called even if the domain selection is
+     *         supported.
+     * @return A {@link DomainSelectionConnection} instance if the device supports
+     *         AOSP domain selection and IMS is available or {@code null} otherwise.
+     */
+    public @Nullable DomainSelectionConnection getDomainSelectionConnection(Phone phone,
+            @DomainSelectionService.SelectorType int selectorType, boolean isEmergency) {
+        if (mController == null) {
+            // If the caller calls this method without checking whether the domain selection
+            // is supported or not, this exception will be thrown.
+            throw new IllegalStateException("DomainSelection is not supported!");
+        }
+
+        if (phone == null || !phone.isImsAvailable()) {
+            // If ImsPhone is null or the binder of ImsService is not available,
+            // CS domain is used for the telephony services.
+            return null;
+        }
+
+        return mController.getDomainSelectionConnection(phone, selectorType, isEmergency);
+    }
+
+    /** Sets a factory interface for creating {@link DomainSelectionController} instance. */
+    @VisibleForTesting
+    public void setDomainSelectionControllerFactory(DomainSelectionControllerFactory factory) {
+        mDomainSelectionControllerFactory = factory;
+    }
+
+    /**
+     * Needs to be called after the constructor to create a {@link DomainSelectionController} that
+     * is bound to the given {@link DomainSelectionService}.
+     *
+     * @param service A {@link DomainSelectionService} to be bound.
+     */
+    public void initialize(@NonNull DomainSelectionService service) {
+        logi("Initialize.");
+        mController = mDomainSelectionControllerFactory.create(mContext, service);
+    }
+
+    /**
+     * Dumps this instance into a readable format for dumpsys usage.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        ipw.println("Resolver:");
+        ipw.increaseIndent();
+        ipw.println("Event Log:");
+        ipw.increaseIndent();
+        mEventLog.dump(ipw);
+        ipw.decreaseIndent();
+        ipw.decreaseIndent();
+
+        ipw.println("Controller:");
+        ipw.increaseIndent();
+        DomainSelectionController controller = mController;
+        if (controller == null) {
+            ipw.println("no active controller");
+        } else {
+            controller.dump(ipw);
+        }
+        ipw.decreaseIndent();
+    }
+
+    private void logi(String s) {
+        Log.i(TAG, s);
+        mEventLog.log(s);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnection.java
new file mode 100644
index 0000000..5f3c3b6
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnection.java
@@ -0,0 +1,225 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+
+import static com.android.internal.telephony.PhoneConstants.DOMAIN_NON_3GPP_PS;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.Annotation.NetCapability;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.data.ApnSetting;
+import android.telephony.ims.ImsReasonInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.data.AccessNetworksManager;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Manages the information of request and the callback binder for emergency calling.
+ */
+public class EmergencyCallDomainSelectionConnection extends DomainSelectionConnection {
+
+    private static final boolean DBG = false;
+
+    private @NonNull EmergencyStateTracker mEmergencyStateTracker = null;
+    private @Nullable DomainSelectionConnectionCallback mCallback;
+    private @TransportType int mPreferredTransportType = TRANSPORT_TYPE_INVALID;
+
+    /**
+     * Create an instance.
+     *
+     * @param phone For which this service is requested.
+     * @param controller The controller to communicate with the domain selection service.
+     */
+    public EmergencyCallDomainSelectionConnection(@NonNull Phone phone,
+            @NonNull DomainSelectionController controller) {
+        this(phone, controller, EmergencyStateTracker.getInstance());
+    }
+
+    /**
+     * Create an instance.
+     *
+     * @param phone For which this service is requested.
+     * @param controller The controller to communicate with the domain selection service.
+     * @param tracker The {@link EmergencyStateTracker} instance.
+     */
+    @VisibleForTesting
+    public EmergencyCallDomainSelectionConnection(@NonNull Phone phone,
+            @NonNull DomainSelectionController controller, @NonNull EmergencyStateTracker tracker) {
+        super(phone, SELECTOR_TYPE_CALLING, true, controller);
+        mTag = "EmergencyCallDomainSelectionConnection";
+
+        mEmergencyStateTracker = tracker;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onWlanSelected(boolean useEmergencyPdn) {
+        mEmergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_CALL, MODE_EMERGENCY_WLAN);
+        if (useEmergencyPdn) {
+            AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+            int transportType = anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY);
+            logi("onWlanSelected curTransportType=" + transportType);
+            if (transportType != TRANSPORT_TYPE_WLAN) {
+                changePreferredTransport(TRANSPORT_TYPE_WLAN);
+                return;
+            }
+        }
+
+        CompletableFuture<Integer> future = getCompletableFuture();
+        if (future != null) future.complete(DOMAIN_NON_3GPP_PS);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onWwanSelected() {
+        mEmergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_CALL, MODE_EMERGENCY_WWAN);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onSelectionTerminated(@DisconnectCauses int cause) {
+        if (mCallback != null) mCallback.onSelectionTerminated(cause);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+            boolean useEmergencyPdn) {
+        if (domain == DOMAIN_PS && useEmergencyPdn) {
+            AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+            int transportType = anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY);
+            logi("onDomainSelected curTransportType=" + transportType);
+            if (transportType != TRANSPORT_TYPE_WWAN) {
+                changePreferredTransport(TRANSPORT_TYPE_WWAN);
+                return;
+            }
+        }
+        super.onDomainSelected(domain, useEmergencyPdn);
+    }
+
+    /**
+     * Request a domain for emergency call.
+     *
+     * @param attr The attributes required to determine the domain.
+     * @param callback A callback to receive the response.
+     * @return the callback to receive the response.
+     */
+    public @NonNull CompletableFuture<Integer> createEmergencyConnection(
+            @NonNull DomainSelectionService.SelectionAttributes attr,
+            @NonNull DomainSelectionConnectionCallback callback) {
+        mCallback = callback;
+        selectDomain(attr);
+        return getCompletableFuture();
+    }
+
+    private void changePreferredTransport(@TransportType int transportType) {
+        logi("changePreferredTransport " + transportType);
+        initHandler();
+        mPreferredTransportType = transportType;
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+        anm.registerForQualifiedNetworksChanged(mHandler, EVENT_QUALIFIED_NETWORKS_CHANGED);
+        mPhone.notifyEmergencyDomainSelected(transportType);
+    }
+
+    private AccessNetworksManager.AccessNetworksManagerCallback mPreferredTransportCallback =
+            new AccessNetworksManager.AccessNetworksManagerCallback(Runnable::run) {
+        @Override
+        public void onPreferredTransportChanged(@NetCapability int capability) {
+        }
+    };
+
+    /** {@inheritDoc} */
+    @Override
+    protected void onQualifiedNetworksChanged() {
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+        int preferredTransport = anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY);
+        logi("onQualifiedNetworksChanged preferred=" + mPreferredTransportType
+                + ", current=" + preferredTransport);
+        if (preferredTransport == mPreferredTransportType) {
+            CompletableFuture<Integer> future = getCompletableFuture();
+            if (future != null) {
+                if (preferredTransport == TRANSPORT_TYPE_WLAN) {
+                    future.complete(DOMAIN_NON_3GPP_PS);
+                } else {
+                    future.complete(DOMAIN_PS);
+                }
+            }
+            anm.unregisterForQualifiedNetworksChanged(mHandler);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void cancelSelection() {
+        logi("cancelSelection");
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+        anm.unregisterForQualifiedNetworksChanged(mHandler);
+        super.cancelSelection();
+    }
+
+    /**
+     * Returns the attributes required to determine the domain for a telephony service.
+     *
+     * @param slotId The slot identifier.
+     * @param subId The subscription identifier.
+     * @param exited {@code true} if the request caused the device to move out of airplane mode.
+     * @param callId The call identifier.
+     * @param number The dialed number.
+     * @param callFailCause The reason why the last CS attempt failed.
+     * @param imsReasonInfo The reason why the last PS attempt failed.
+     * @param emergencyRegResult The current registration result for emergency services.
+     * @return The attributes required to determine the domain.
+     */
+    public static @NonNull DomainSelectionService.SelectionAttributes getSelectionAttributes(
+            int slotId, int subId, boolean exited,
+            @NonNull String callId, @NonNull String number, int callFailCause,
+            @Nullable ImsReasonInfo imsReasonInfo,
+            @Nullable EmergencyRegResult emergencyRegResult) {
+        DomainSelectionService.SelectionAttributes.Builder builder =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        slotId, subId, SELECTOR_TYPE_CALLING)
+                .setEmergency(true)
+                .setExitedFromAirplaneMode(exited)
+                .setCallId(callId)
+                .setNumber(number)
+                .setCsDisconnectCause(callFailCause);
+
+        if (imsReasonInfo != null) builder.setPsDisconnectCause(imsReasonInfo);
+        if (emergencyRegResult != null) builder.setEmergencyRegResult(emergencyRegResult);
+
+        return builder.build();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnection.java
new file mode 100644
index 0000000..efcdf11
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnection.java
@@ -0,0 +1,163 @@
+/*
+ * 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.domainselection;
+
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import android.annotation.NonNull;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.data.ApnSetting;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.data.AccessNetworksManager;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
+
+/**
+ * Manages the information of request and the callback binder for an emergency SMS.
+ */
+public class EmergencySmsDomainSelectionConnection extends SmsDomainSelectionConnection {
+    private final Object mLock = new Object();
+    private @NonNull EmergencyStateTracker mEmergencyStateTracker;
+    private @TransportType int mPreferredTransportType =
+            AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+
+    public EmergencySmsDomainSelectionConnection(
+            Phone phone, DomainSelectionController controller) {
+        this(phone, controller, EmergencyStateTracker.getInstance());
+    }
+
+    @VisibleForTesting
+    public EmergencySmsDomainSelectionConnection(Phone phone,
+            DomainSelectionController controller, EmergencyStateTracker tracker) {
+        super(phone, controller, true);
+        mTag = "DomainSelectionConnection-EmergencySMS";
+        mEmergencyStateTracker = tracker;
+    }
+
+    /**
+     * Notifies that WLAN transport has been selected.
+     *
+     * @param useEmergencyPdn A flag specifying whether Wi-Fi emergency service uses emergency PDN
+     *                        or not.
+     */
+    @Override
+    public void onWlanSelected(boolean useEmergencyPdn) {
+        synchronized (mLock) {
+            if (mPreferredTransportType != AccessNetworkConstants.TRANSPORT_TYPE_INVALID) {
+                logi("Domain selection completion is in progress");
+                return;
+            }
+
+            mEmergencyStateTracker.onEmergencyTransportChanged(
+                    EmergencyStateTracker.EMERGENCY_TYPE_SMS, MODE_EMERGENCY_WLAN);
+
+            if (useEmergencyPdn) {
+                // Change the transport type if the current preferred transport type for
+                // an emergency is not {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}.
+                AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+                if (anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY)
+                        != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
+                    changePreferredTransport(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+                    // The {@link #onDomainSlected()} will be called after the preferred transport
+                    // is successfully changed and notified from the {@link AccessNetworksManager}.
+                    return;
+                }
+            }
+
+            super.onWlanSelected(useEmergencyPdn);
+        }
+    }
+
+    @Override
+    public void onWwanSelected() {
+        mEmergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_SMS, MODE_EMERGENCY_WWAN);
+    }
+
+    /**
+     * Notifies the domain selected.
+     *
+     * @param domain The selected domain.
+     * @param useEmergencyPdn A flag specifying whether emergency service uses emergency PDN or not.
+     */
+    @Override
+    public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+            boolean useEmergencyPdn) {
+        synchronized (mLock) {
+            if (mPreferredTransportType != AccessNetworkConstants.TRANSPORT_TYPE_INVALID) {
+                logi("Domain selection completion is in progress");
+                return;
+            }
+
+            if (useEmergencyPdn && domain == NetworkRegistrationInfo.DOMAIN_PS) {
+                // Change the transport type if the current preferred transport type for
+                // an emergency is not {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}.
+                AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+                if (anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY)
+                        != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
+                    changePreferredTransport(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+                    // The {@link #onDomainSlected()} will be called after the preferred transport
+                    // is successfully changed and notified from the {@link AccessNetworksManager}.
+                    return;
+                }
+            }
+
+            super.onDomainSelected(domain, useEmergencyPdn);
+        }
+    }
+
+    @Override
+    public void finishSelection() {
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+
+        synchronized (mLock) {
+            if (mPreferredTransportType != AccessNetworkConstants.TRANSPORT_TYPE_INVALID) {
+                mPreferredTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+                anm.unregisterForQualifiedNetworksChanged(mHandler);
+            }
+        }
+
+        super.finishSelection();
+    }
+
+    @Override
+    protected void onQualifiedNetworksChanged() {
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+        int preferredTransportType = anm.getPreferredTransport(ApnSetting.TYPE_EMERGENCY);
+
+        synchronized (mLock) {
+            if (preferredTransportType == mPreferredTransportType) {
+                mPreferredTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+                super.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+                anm.unregisterForQualifiedNetworksChanged(mHandler);
+            }
+        }
+    }
+
+    private void changePreferredTransport(@TransportType int transportType) {
+        logi("Change preferred transport: " + transportType);
+        initHandler();
+        mPreferredTransportType = transportType;
+        AccessNetworksManager anm = mPhone.getAccessNetworksManager();
+        anm.registerForQualifiedNetworksChanged(mHandler, EVENT_QUALIFIED_NETWORKS_CHANGED);
+        mPhone.notifyEmergencyDomainSelected(transportType);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnection.java
new file mode 100644
index 0000000..e157d24
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnection.java
@@ -0,0 +1,146 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.EmergencyScanType;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ims.ImsReasonInfo;
+
+import com.android.internal.telephony.Phone;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Manages the information of request and the callback binder for normal calling.
+ */
+public class NormalCallDomainSelectionConnection extends DomainSelectionConnection {
+
+    private static final boolean DBG = false;
+
+    private static final String PREFIX_WPS = "*272";
+
+    // WPS prefix when CLIR is being activated for the call.
+    private static final String PREFIX_WPS_CLIR_ACTIVATE = "*31#*272";
+
+    // WPS prefix when CLIR is being deactivated for the call.
+    private static final String PREFIX_WPS_CLIR_DEACTIVATE = "#31#*272";
+
+
+    private @Nullable DomainSelectionConnectionCallback mCallback;
+
+    /**
+     * Create an instance.
+     *
+     * @param phone For which this service is requested.
+     * @param controller The controller to communicate with the domain selection service.
+     */
+    public NormalCallDomainSelectionConnection(@NonNull Phone phone,
+            @NonNull DomainSelectionController controller) {
+        super(phone, SELECTOR_TYPE_CALLING, false, controller);
+        mTag = "NormalCallDomainSelectionConnection";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onWlanSelected() {
+        CompletableFuture<Integer> future = getCompletableFuture();
+        future.complete(NetworkRegistrationInfo.DOMAIN_PS);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onWwanSelected() {
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onSelectionTerminated(@DisconnectCauses int cause) {
+        if (mCallback != null) mCallback.onSelectionTerminated(cause);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onRequestEmergencyNetworkScan(@RadioAccessNetworkType int[] preferredNetworks,
+            @EmergencyScanType int scanType) {
+        // Not expected with normal calling.
+        // Override to prevent abnormal behavior.
+    }
+
+    /**
+     * Request a domain for normal call.
+     *
+     * @param attr The attributes required to determine the domain.
+     * @param callback A callback to receive the response.
+     * @return A {@link CompletableFuture} callback to receive the result.
+     */
+    public CompletableFuture<Integer> createNormalConnection(
+            @NonNull DomainSelectionService.SelectionAttributes attr,
+            @NonNull DomainSelectionConnectionCallback callback) {
+        mCallback = callback;
+        selectDomain(attr);
+        return getCompletableFuture();
+    }
+
+    /**
+     * Returns the attributes required to determine the domain for a normal call.
+     *
+     * @param slotId The slot identifier.
+     * @param subId The subscription identifier.
+     * @param callId The call identifier.
+     * @param number The dialed number.
+     * @param isVideoCall flag for video call.
+     * @param callFailCause The reason why the last CS attempt failed.
+     * @param imsReasonInfo The reason why the last PS attempt failed.
+     * @return The attributes required to determine the domain.
+     */
+    public static @NonNull DomainSelectionService.SelectionAttributes getSelectionAttributes(
+            int slotId, int subId, @NonNull String callId, @NonNull String number,
+            boolean isVideoCall, int callFailCause, @Nullable ImsReasonInfo imsReasonInfo) {
+
+        DomainSelectionService.SelectionAttributes.Builder builder =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        slotId, subId, SELECTOR_TYPE_CALLING)
+                        .setEmergency(false)
+                        .setCallId(callId)
+                        .setNumber(number)
+                        .setCsDisconnectCause(callFailCause)
+                        .setVideoCall(isVideoCall);
+
+        if (imsReasonInfo != null) {
+            builder.setPsDisconnectCause(imsReasonInfo);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Check if the call is Wireless Priority Service call
+     * @param dialString  The number being dialed.
+     * @return {@code true} if dialString matches WPS pattern and {@code false} otherwise.
+     */
+    public static boolean isWpsCall(String dialString) {
+        return (dialString != null) && (dialString.startsWith(PREFIX_WPS)
+                || dialString.startsWith(PREFIX_WPS_CLIR_ACTIVATE)
+                || dialString.startsWith(PREFIX_WPS_CLIR_DEACTIVATE));
+    }
+}
diff --git a/src/java/com/android/internal/telephony/domainselection/SmsDomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/SmsDomainSelectionConnection.java
new file mode 100644
index 0000000..36a7b17
--- /dev/null
+++ b/src/java/com/android/internal/telephony/domainselection/SmsDomainSelectionConnection.java
@@ -0,0 +1,83 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;
+
+import android.annotation.NonNull;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.DomainSelectionService;
+import android.telephony.NetworkRegistrationInfo;
+
+import com.android.internal.telephony.Phone;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Manages the information of request and the callback binder for SMS.
+ */
+public class SmsDomainSelectionConnection extends DomainSelectionConnection {
+    private DomainSelectionConnectionCallback mCallback;
+
+    public SmsDomainSelectionConnection(Phone phone, DomainSelectionController controller) {
+        this(phone, controller, false);
+        mTag = "DomainSelectionConnection-SMS";
+    }
+
+    protected SmsDomainSelectionConnection(Phone phone, DomainSelectionController controller,
+            boolean isEmergency) {
+        super(phone, SELECTOR_TYPE_SMS, isEmergency, controller);
+    }
+
+    @Override
+    public void onWlanSelected() {
+        super.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS);
+    }
+
+    @Override
+    public void onSelectionTerminated(@DisconnectCauses int cause) {
+        if (mCallback != null) mCallback.onSelectionTerminated(cause);
+    }
+
+    @Override
+    public void finishSelection() {
+        CompletableFuture<Integer> future = getCompletableFuture();
+
+        if (future != null && !future.isDone()) {
+            cancelSelection();
+        } else {
+            super.finishSelection();
+        }
+    }
+
+    /**
+     * Requests a domain selection for SMS.
+     *
+     * @param attr The attributes required to determine the domain.
+     * @param callback A callback to notify an error of the domain selection.
+     * @return A {@link CompletableFuture} to get the selected domain
+     *         {@link NetworkRegistrationInfo#DOMAIN_PS} or
+     *         {@link NetworkRegistrationInfo#DOMAIN_CS}.
+     */
+    public @NonNull CompletableFuture<Integer> requestDomainSelection(
+            @NonNull DomainSelectionService.SelectionAttributes attr,
+            @NonNull DomainSelectionConnectionCallback callback) {
+        mCallback = callback;
+        selectDomain(attr);
+        return getCompletableFuture();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyConstants.java b/src/java/com/android/internal/telephony/emergency/EmergencyConstants.java
new file mode 100644
index 0000000..6caf5ab
--- /dev/null
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyConstants.java
@@ -0,0 +1,69 @@
+/*
+ * 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.emergency;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the constants for emergency call domain selection.
+ */
+public class EmergencyConstants {
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"MODE_EMERGENCY_"},
+            value = {
+                    MODE_EMERGENCY_NONE,
+                    MODE_EMERGENCY_WWAN,
+                    MODE_EMERGENCY_WLAN,
+                    MODE_EMERGENCY_CALLBACK,
+            })
+    public @interface EmergencyMode {}
+
+    /**
+     * Default value.
+     */
+    public static final int MODE_EMERGENCY_NONE = 0;
+    /**
+     * Mode Type Emergency WWAN, indicates that the current domain selected for the Emergency call
+     * is cellular.
+     */
+    public static final int MODE_EMERGENCY_WWAN = 1;
+    /**
+     * Mode Type Emergency WLAN, indicates that the current domain selected for the Emergency call
+     * is WLAN/WIFI.
+     */
+    public static final int MODE_EMERGENCY_WLAN = 2;
+    /**
+     * Mode Type Emergency Callback, indicates that the current mode set request is for Emergency
+     * callback.
+     */
+    public static final int MODE_EMERGENCY_CALLBACK = 3;
+
+    /** Converts the {@link EmergencyMode} to String */
+    public static String emergencyModeToString(int emcMode) {
+        switch (emcMode) {
+            case MODE_EMERGENCY_NONE: return "NONE";
+            case MODE_EMERGENCY_WWAN: return "WWAN";
+            case MODE_EMERGENCY_WLAN: return "WLAN";
+            case MODE_EMERGENCY_CALLBACK: return "CALLBACK";
+            default: return "UNKNOWN(" + emcMode + ")";
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index bddd0e2..9b44001 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -20,14 +20,15 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.os.AsyncResult;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
-import android.os.SystemProperties;
 import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentity;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -36,18 +37,20 @@
 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.LocalLog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.HalVersion;
 import com.android.internal.telephony.LocaleTracker;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.metrics.EmergencyNumberStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.PersistAtomsProto;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.ecc.nano.ProtobufEccData;
@@ -68,6 +71,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import java.util.zip.GZIPInputStream;
 
 /**
@@ -96,9 +102,18 @@
 
     private final CommandsInterface mCi;
     private final Phone mPhone;
+    private int mPhoneId;
     private String mCountryIso;
     private String mLastKnownEmergencyCountryIso = "";
     private int mCurrentDatabaseVersion = INVALID_DATABASE_VERSION;
+    private int mCurrentOtaDatabaseVersion = INVALID_DATABASE_VERSION;
+    private Resources mResources = null;
+    /**
+     * Used for storing all specific mnc's along with the list of emergency numbers
+     * for which normal routing should be supported.
+     */
+    private Map<String, Set<String>> mNormalRoutedNumbers = new ArrayMap<>();
+
     /**
      * Indicates if the country iso is set by another subscription.
      * @hide
@@ -142,10 +157,6 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(
-                    CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                onCarrierConfigChanged();
-                return;
-            } else if (intent.getAction().equals(
                     TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
                 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1);
                 if (phoneId == mPhone.getPhoneId()) {
@@ -165,27 +176,35 @@
     public EmergencyNumberTracker(Phone phone, CommandsInterface ci) {
         mPhone = phone;
         mCi = ci;
+        mResources = mPhone.getContext().getResources();
 
         if (mPhone != null) {
+            mPhoneId = phone.getPhoneId();
             CarrierConfigManager configMgr = (CarrierConfigManager)
                     mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
             if (configMgr != null) {
-                PersistableBundle b = configMgr.getConfigForSubId(mPhone.getSubId());
-                if (b != null) {
+                PersistableBundle b = CarrierConfigManager.getCarrierConfigSubset(
+                        mPhone.getContext(),
+                        mPhone.getSubId(),
+                        CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
+                if (!b.isEmpty()) {
                     mEmergencyNumberPrefix = b.getStringArray(
                             CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
                 }
+
+                // Callback which directly handle config change should be executed on handler thread
+                configMgr.registerCarrierConfigChangeListener(this::post,
+                        (slotIndex, subId, carrierId, specificCarrierId) ->
+                                onCarrierConfigUpdated(slotIndex));
+
+                //register country change listener
+                IntentFilter filter = new IntentFilter(
+                    TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
+                mPhone.getContext().registerReceiver(mIntentReceiver, filter);
+
             } else {
                 loge("CarrierConfigManager is null.");
             }
-
-            // Receive Carrier Config Changes
-            IntentFilter filter = new IntentFilter(
-                    CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-            // Receive Telephony Network Country Changes
-            filter.addAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
-
-            mPhone.getContext().registerReceiver(mIntentReceiver, filter);
         } else {
             loge("mPhone is null.");
         }
@@ -270,12 +289,7 @@
     @VisibleForTesting
     public boolean isSimAbsent() {
         for (Phone phone: PhoneFactory.getPhones()) {
-            int slotId;
-            if (phone.isSubscriptionManagerServiceEnabled()) {
-                slotId = SubscriptionManagerService.getInstance().getSlotIndex(phone.getSubId());
-            } else {
-                slotId = SubscriptionController.getInstance().getSlotIndex(phone.getSubId());
-            }
+            int slotId = SubscriptionManagerService.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
@@ -290,7 +304,7 @@
         // If country iso has been cached when listener is set, don't need to cache the initial
         // country iso and initial database.
         if (mCountryIso == null) {
-            String countryForDatabaseCache = getInitialCountryIso().toLowerCase();
+            String countryForDatabaseCache = getInitialCountryIso().toLowerCase(Locale.ROOT);
             updateEmergencyCountryIso(countryForDatabaseCache);
             // Use the last known country to cache the database in APM
             if (TextUtils.isEmpty(countryForDatabaseCache)
@@ -333,23 +347,26 @@
         }
     }
 
-    private void onCarrierConfigChanged() {
+    private void onCarrierConfigUpdated(int slotIndex) {
         if (mPhone != null) {
-            CarrierConfigManager configMgr = (CarrierConfigManager)
-                    mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            if (configMgr != null) {
-                PersistableBundle b = configMgr.getConfigForSubId(mPhone.getSubId());
-                if (b != null) {
-                    String[] emergencyNumberPrefix = b.getStringArray(
+            if (slotIndex != mPhone.getPhoneId()) return;
+
+            PersistableBundle b =
+                    CarrierConfigManager.getCarrierConfigSubset(
+                            mPhone.getContext(),
+                            mPhone.getSubId(),
                             CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
-                    if (!Arrays.equals(mEmergencyNumberPrefix, emergencyNumberPrefix)) {
-                        this.obtainMessage(EVENT_UPDATE_EMERGENCY_NUMBER_PREFIX,
-                                emergencyNumberPrefix).sendToTarget();
-                    }
+            if (!b.isEmpty()) {
+                String[] emergencyNumberPrefix =
+                        b.getStringArray(
+                                CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
+                if (!Arrays.equals(mEmergencyNumberPrefix, emergencyNumberPrefix)) {
+                    this.obtainMessage(EVENT_UPDATE_EMERGENCY_NUMBER_PREFIX, emergencyNumberPrefix)
+                            .sendToTarget();
                 }
             }
         } else {
-            loge("onCarrierConfigChanged mPhone is null.");
+            loge("onCarrierConfigurationChanged mPhone is null.");
         }
     }
 
@@ -410,7 +427,8 @@
                 EVENT_OVERRIDE_OTA_EMERGENCY_NUMBER_DB_FILE_PATH, null).sendToTarget();
     }
 
-    private EmergencyNumber convertEmergencyNumberFromEccInfo(EccInfo eccInfo, String countryIso) {
+    private EmergencyNumber convertEmergencyNumberFromEccInfo(EccInfo eccInfo, String countryIso,
+            int emergencyCallRouting) {
         String phoneNumber = eccInfo.phoneNumber.trim();
         if (phoneNumber.isEmpty()) {
             loge("EccInfo has empty phone number.");
@@ -451,13 +469,65 @@
                     // Ignores unknown types.
             }
         }
-        return new EmergencyNumber(phoneNumber, countryIso, "", emergencyServiceCategoryBitmask,
-                new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
-                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        return new EmergencyNumber(phoneNumber, countryIso, "",
+                emergencyServiceCategoryBitmask, new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE, emergencyCallRouting);
+    }
+
+    /**
+     * Get routing type of emergency numbers from DB. Update mnc's list with numbers that are
+     * to supported as normal routing type in the respective mnc's.
+     */
+    private int getRoutingInfoFromDB(EccInfo eccInfo,
+            Map<String, Set<String>> normalRoutedNumbers) {
+        int emergencyCallRouting;
+        switch(eccInfo.routing)
+        {
+            case EccInfo.Routing.NORMAL :
+                emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
+                break;
+            case EccInfo.Routing.EMERGENCY :
+                emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
+                break;
+            default:
+                emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+        }
+        String phoneNumber = eccInfo.phoneNumber.trim();
+        if (phoneNumber.isEmpty()) {
+            loge("EccInfo has empty phone number.");
+            return emergencyCallRouting;
+        }
+
+        if (eccInfo.routing == EccInfo.Routing.NORMAL) {
+            emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
+
+            if (((eccInfo.normalRoutingMncs).length != 0)
+                    && (eccInfo.normalRoutingMncs[0].length() > 0)) {
+                emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+
+                for (String routingMnc : eccInfo.normalRoutingMncs) {
+                    boolean mncExist = normalRoutedNumbers.containsKey(routingMnc);
+                    Set phoneNumberList;
+                    if (!mncExist) {
+                        phoneNumberList = new ArraySet<String>();
+                        phoneNumberList.add(phoneNumber);
+                        normalRoutedNumbers.put(routingMnc, phoneNumberList);
+                    } else {
+                        phoneNumberList = normalRoutedNumbers.get(routingMnc);
+                        if (!phoneNumberList.contains(phoneNumber)) {
+                            phoneNumberList.add(phoneNumber);
+                        }
+                    }
+                }
+                logd("Normal routed mncs with phoneNumbers:" + normalRoutedNumbers);
+            }
+        }
+        return emergencyCallRouting;
     }
 
     private void cacheEmergencyDatabaseByCountry(String countryIso) {
         int assetsDatabaseVersion;
+        Map<String, Set<String>> assetNormalRoutedNumbers = new ArrayMap<>();
 
         // Read the Asset emergency number database
         List<EmergencyNumber> updatedAssetEmergencyNumberList = new ArrayList<>();
@@ -469,12 +539,17 @@
                     readInputStreamToByteArray(gzipInputStream));
             assetsDatabaseVersion = allEccMessages.revision;
             logd(countryIso + " asset emergency database is loaded. Ver: " + assetsDatabaseVersion
-                    + " Phone Id: " + mPhone.getPhoneId());
+                    + " Phone Id: " + mPhone.getPhoneId() + " countryIso: " + countryIso);
             for (ProtobufEccData.CountryInfo countryEccInfo : allEccMessages.countries) {
-                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase())) {
+                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase(Locale.ROOT))) {
                     for (ProtobufEccData.EccInfo eccInfo : countryEccInfo.eccs) {
+                        int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+                        if (!shouldEmergencyNumberRoutingFromDbBeIgnored()) {
+                            emergencyCallRouting = getRoutingInfoFromDB(eccInfo,
+                                    assetNormalRoutedNumbers);
+                        }
                         updatedAssetEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
-                                eccInfo, countryIso));
+                                eccInfo, countryIso, emergencyCallRouting));
                     }
                 }
             }
@@ -485,24 +560,27 @@
         }
 
         // Cache OTA emergency number database
-        int otaDatabaseVersion = cacheOtaEmergencyNumberDatabase();
+        mCurrentOtaDatabaseVersion = cacheOtaEmergencyNumberDatabase();
 
         // Use a valid database that has higher version.
-        if (otaDatabaseVersion == INVALID_DATABASE_VERSION
+        if (mCurrentOtaDatabaseVersion == INVALID_DATABASE_VERSION
                 && assetsDatabaseVersion == INVALID_DATABASE_VERSION) {
             loge("No database available. Phone Id: " + mPhone.getPhoneId());
-        } else if (assetsDatabaseVersion > otaDatabaseVersion) {
+        } else if (assetsDatabaseVersion > mCurrentOtaDatabaseVersion) {
             logd("Using Asset Emergency database. Version: " + assetsDatabaseVersion);
             mCurrentDatabaseVersion = assetsDatabaseVersion;
             mEmergencyNumberListFromDatabase = updatedAssetEmergencyNumberList;
+            mNormalRoutedNumbers.clear();
+            mNormalRoutedNumbers = assetNormalRoutedNumbers;
         } else {
-            logd("Using Ota Emergency database. Version: " + otaDatabaseVersion);
+            logd("Using Ota Emergency database. Version: " + mCurrentOtaDatabaseVersion);
         }
     }
 
     private int cacheOtaEmergencyNumberDatabase() {
         ProtobufEccData.AllInfo allEccMessages = null;
         int otaDatabaseVersion = INVALID_DATABASE_VERSION;
+        Map<String, Set<String>> otaNormalRoutedNumbers = new ArrayMap<>();
 
         // Read the OTA emergency number database
         List<EmergencyNumber> updatedOtaEmergencyNumberList = new ArrayList<>();
@@ -531,10 +609,15 @@
             logd(countryIso + " ota emergency database is loaded. Ver: " + otaDatabaseVersion);
             otaDatabaseVersion = allEccMessages.revision;
             for (ProtobufEccData.CountryInfo countryEccInfo : allEccMessages.countries) {
-                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase())) {
+                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase(Locale.ROOT))) {
                     for (ProtobufEccData.EccInfo eccInfo : countryEccInfo.eccs) {
+                        int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
+                        if (!shouldEmergencyNumberRoutingFromDbBeIgnored()) {
+                            emergencyCallRouting = getRoutingInfoFromDB(eccInfo,
+                                    otaNormalRoutedNumbers);
+                        }
                         updatedOtaEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
-                                eccInfo, countryIso));
+                                eccInfo, countryIso, emergencyCallRouting));
                     }
                 }
             }
@@ -549,6 +632,8 @@
                 && mCurrentDatabaseVersion < otaDatabaseVersion) {
             mCurrentDatabaseVersion = otaDatabaseVersion;
             mEmergencyNumberListFromDatabase = updatedOtaEmergencyNumberList;
+            mNormalRoutedNumbers.clear();
+            mNormalRoutedNumbers = otaNormalRoutedNumbers;
         }
         return otaDatabaseVersion;
     }
@@ -597,9 +682,9 @@
     private void updateEmergencyNumberListDatabaseAndNotify(String countryIso) {
         logd("updateEmergencyNumberListDatabaseAndNotify(): receiving countryIso: "
                 + countryIso);
-        updateEmergencyCountryIso(countryIso.toLowerCase());
+        updateEmergencyCountryIso(countryIso.toLowerCase(Locale.ROOT));
         // Use cached country iso in APM to load emergency number database.
-        if (TextUtils.isEmpty(countryIso) && isAirplaneModeEnabled()) {
+        if (TextUtils.isEmpty(countryIso)) {
             countryIso = getCountryIsoForCachingDatabase();
             logd("updateEmergencyNumberListDatabaseAndNotify(): using cached APM country "
                     + countryIso);
@@ -628,7 +713,8 @@
     private void updateOtaEmergencyNumberListDatabaseAndNotify() {
         logd("updateOtaEmergencyNumberListDatabaseAndNotify():"
                 + " receiving Emegency Number database OTA update");
-        if (cacheOtaEmergencyNumberDatabase() != INVALID_DATABASE_VERSION) {
+        mCurrentOtaDatabaseVersion = cacheOtaEmergencyNumberDatabase();
+        if (mCurrentOtaDatabaseVersion != INVALID_DATABASE_VERSION) {
             writeUpdatedEmergencyNumberListMetrics(mEmergencyNumberListFromDatabase);
             if (!DBG) {
                 mEmergencyNumberListDatabaseLocalLog.log(
@@ -693,7 +779,11 @@
         }
         mergedEmergencyNumberList.addAll(mEmergencyNumberListWithPrefix);
         mergedEmergencyNumberList.addAll(mEmergencyNumberListFromTestMode);
-        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        if (shouldDeterminingOfUrnsAndCategoriesWhileMergingIgnored()) {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        } else {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList, true);
+        }
         mEmergencyNumberList = mergedEmergencyNumberList;
     }
 
@@ -704,11 +794,90 @@
      *         indication not support from the HAL.
      */
     public List<EmergencyNumber> getEmergencyNumberList() {
+        List<EmergencyNumber> completeEmergencyNumberList;
         if (!mEmergencyNumberListFromRadio.isEmpty()) {
-            return Collections.unmodifiableList(mEmergencyNumberList);
+            completeEmergencyNumberList = Collections.unmodifiableList(mEmergencyNumberList);
         } else {
-            return getEmergencyNumberListFromEccListDatabaseAndTest();
+            completeEmergencyNumberList = getEmergencyNumberListFromEccListDatabaseAndTest();
         }
+        if (shouldAdjustForRouting()) {
+            return adjustRoutingForEmergencyNumbers(completeEmergencyNumberList);
+        } else {
+            return completeEmergencyNumberList;
+        }
+    }
+
+    /**
+     * Util function to check whether routing type and mnc value in emergency number needs
+     * to be adjusted for the current network mnc.
+     */
+    private boolean shouldAdjustForRouting() {
+        if (!shouldEmergencyNumberRoutingFromDbBeIgnored() && !mNormalRoutedNumbers.isEmpty()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Adjust emergency numbers with mnc and routing type based on the current network mnc.
+     */
+    private List<EmergencyNumber> adjustRoutingForEmergencyNumbers(
+            List<EmergencyNumber> emergencyNumbers) {
+        CellIdentity cellIdentity = mPhone.getCurrentCellIdentity();
+        if (cellIdentity != null) {
+            String networkMnc = cellIdentity.getMncString();
+            Set<String> normalRoutedPhoneNumbers = mNormalRoutedNumbers.get(networkMnc);
+            Set<String> normalRoutedPhoneNumbersWithPrefix = new ArraySet<String>();
+
+            if (normalRoutedPhoneNumbers != null && !normalRoutedPhoneNumbers.isEmpty()) {
+                for (String num : normalRoutedPhoneNumbers) {
+                    Set<String> phoneNumbersWithPrefix = addPrefixToEmergencyNumber(num);
+                    if (phoneNumbersWithPrefix != null && !phoneNumbersWithPrefix.isEmpty()) {
+                        normalRoutedPhoneNumbersWithPrefix.addAll(phoneNumbersWithPrefix);
+                    }
+                }
+            }
+            List<EmergencyNumber> adjustedEmergencyNumberList = new ArrayList<>();
+            int routing;
+            String mnc;
+            for (EmergencyNumber num : emergencyNumbers) {
+                routing = num.getEmergencyCallRouting();
+                mnc = num.getMnc();
+                if (num.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE)) {
+                    if ((normalRoutedPhoneNumbers != null
+                            && normalRoutedPhoneNumbers.contains(num.getNumber()))
+                            || normalRoutedPhoneNumbersWithPrefix.contains(num.getNumber())) {
+                        routing = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
+                        mnc = networkMnc;
+                        logd("adjustRoutingForEmergencyNumbers for number" + num.getNumber());
+                    } else if (routing == EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN) {
+                        routing = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
+                    }
+                }
+                adjustedEmergencyNumberList.add(new EmergencyNumber(num.getNumber(),
+                        num.getCountryIso(), mnc,
+                        num.getEmergencyServiceCategoryBitmask(),
+                        num.getEmergencyUrns(), num.getEmergencyNumberSourceBitmask(),
+                        routing));
+            }
+            return adjustedEmergencyNumberList;
+        } else {
+            return emergencyNumbers;
+        }
+    }
+
+
+    /**
+     * Util function to add prefix to the given emergency number.
+     */
+    private Set<String> addPrefixToEmergencyNumber(String number) {
+        Set<String> phoneNumbersWithPrefix = new ArraySet<String>();
+        for (String prefix : mEmergencyNumberPrefix) {
+            if (!number.startsWith(prefix)) {
+                phoneNumbersWithPrefix.add(prefix + number);
+            }
+        }
+        return phoneNumbersWithPrefix;
     }
 
     /**
@@ -716,7 +885,7 @@
      *
      * @return {@code true} if it is; {@code false} otherwise.
      */
-    public boolean isEmergencyNumber(String number, boolean exactMatch) {
+    public boolean isEmergencyNumber(String number) {
         if (number == null) {
             return false;
         }
@@ -732,31 +901,14 @@
 
         if (!mEmergencyNumberListFromRadio.isEmpty()) {
             for (EmergencyNumber num : mEmergencyNumberList) {
-                // 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.
-                String countryIso = getLastKnownEmergencyCountryIso();
-                if (countryIso.equals("br") || countryIso.equals("cl")
-                        || countryIso.equals("ni")) {
-                    exactMatch = true;
-                } else {
-                    exactMatch = false || exactMatch;
-                }
-                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;
-                    }
+                if (num.getNumber().equals(number)) {
+                    logd("Found in mEmergencyNumberList");
+                    return true;
                 }
             }
             return false;
         } else {
-            boolean inEccList = isEmergencyNumberFromEccList(number, exactMatch);
+            boolean inEccList = isEmergencyNumberFromEccList(number);
             boolean inEmergencyNumberDb = isEmergencyNumberFromDatabase(number);
             boolean inEmergencyNumberTestList = isEmergencyNumberForTest(number);
             logd("Search results - inRilEccList:" + inEccList
@@ -846,6 +998,10 @@
         return mCurrentDatabaseVersion;
     }
 
+    public int getEmergencyNumberOtaDbVersion() {
+        return mCurrentOtaDatabaseVersion;
+    }
+
     private synchronized void updateEmergencyCountryIso(String countryIso) {
         mCountryIso = countryIso;
         if (!TextUtils.isEmpty(mCountryIso)) {
@@ -861,22 +1017,8 @@
      */
     private List<EmergencyNumber> getEmergencyNumberListFromEccList() {
         List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
-        int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
 
-        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
-        String 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");
-        }
-        if (!TextUtils.isEmpty(emergencyNumbers)) {
-            // searches through the comma-separated list for a match,
-            // return true if one is found.
-            for (String emergencyNum : emergencyNumbers.split(",")) {
-                emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
-            }
-        }
-        emergencyNumbers = ((isSimAbsent()) ? "112,911,000,08,110,118,119,999" : "112,911");
+        String emergencyNumbers = ((isSimAbsent()) ? "112,911,000,08,110,118,119,999" : "112,911");
         for (String emergencyNum : emergencyNumbers.split(",")) {
             emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
         }
@@ -892,15 +1034,14 @@
         List<EmergencyNumber> emergencyNumberListWithPrefix = new ArrayList<>();
         if (emergencyNumberList != null) {
             for (EmergencyNumber num : emergencyNumberList) {
-                for (String prefix : mEmergencyNumberPrefix) {
-                    // If an emergency number has started with the prefix,
-                    // no need to apply the prefix.
-                    if (!num.getNumber().startsWith(prefix)) {
+                Set<String> phoneNumbersWithPrefix = addPrefixToEmergencyNumber(num.getNumber());
+                if (phoneNumbersWithPrefix != null && !phoneNumbersWithPrefix.isEmpty()) {
+                    for (String numberWithPrefix : phoneNumbersWithPrefix) {
                         emergencyNumberListWithPrefix.add(new EmergencyNumber(
-                            prefix + num.getNumber(), num.getCountryIso(),
-                            num.getMnc(), num.getEmergencyServiceCategoryBitmask(),
-                            num.getEmergencyUrns(), num.getEmergencyNumberSourceBitmask(),
-                            num.getEmergencyCallRouting()));
+                                numberWithPrefix, num.getCountryIso(),
+                                num.getMnc(), num.getEmergencyServiceCategoryBitmask(),
+                                num.getEmergencyUrns(), num.getEmergencyNumberSourceBitmask(),
+                                num.getEmergencyCallRouting()));
                     }
                 }
             }
@@ -919,7 +1060,7 @@
     }
 
     private boolean isEmergencyNumberFromDatabase(String number) {
-        if (!mPhone.getHalVersion().greaterOrEqual(new HalVersion(1, 4))) {
+        if (mEmergencyNumberListFromDatabase.isEmpty()) {
             return false;
         }
         number = PhoneNumberUtils.stripSeparators(number);
@@ -942,10 +1083,10 @@
         number = PhoneNumberUtils.stripSeparators(number);
         for (EmergencyNumber num : mEmergencyNumberListFromDatabase) {
             if (num.getNumber().equals(number)) {
-                return new EmergencyNumber(number, getLastKnownEmergencyCountryIso().toLowerCase(),
-                        "", num.getEmergencyServiceCategoryBitmask(),
+                return new EmergencyNumber(number, getLastKnownEmergencyCountryIso()
+                        .toLowerCase(Locale.ROOT), "", num.getEmergencyServiceCategoryBitmask(),
                         new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
-                        EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+                        num.getEmergencyCallRouting());
             }
         }
         return new EmergencyNumber(number, "", "",
@@ -958,7 +1099,7 @@
      * Back-up old logics for {@link PhoneNumberUtils#isEmergencyNumberInternal} for legacy
      * and deprecate purpose.
      */
-    private boolean isEmergencyNumberFromEccList(String number, boolean useExactMatch) {
+    private boolean isEmergencyNumberFromEccList(String number) {
         // If the number passed in is null, just return false:
         if (number == null) return false;
 
@@ -982,59 +1123,8 @@
         /// @}
 
         String emergencyNumbers = "";
-        int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
-
-        String ecclist = null;
         String countryIso = getLastKnownEmergencyCountryIso();
-
-        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, "");
-
-            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")
-                        || countryIso.equals("ni")) {
-                        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 {
-                            for (String prefix : mEmergencyNumberPrefix) {
-                                if (number.startsWith(prefix + emergencyNum)) {
-                                    return true;
-                                }
-                            }
-                        }
-                    }
-                }
-                // no matches found against the list!
-                return false;
-            }
-        }
+        logd("country:" + countryIso);
 
         logd("System property doesn't provide any emergency numbers."
                 + " Use embedded logic for determining ones.");
@@ -1044,57 +1134,32 @@
         emergencyNumbers = ((isSimAbsent()) ? "112,911,000,08,110,118,119,999" : "112,911");
 
         for (String emergencyNum : emergencyNumbers.split(",")) {
-            if (useExactMatch) {
-                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 {
-                if (number.startsWith(emergencyNum)) {
-                    return true;
-                } else {
-                    for (String prefix : mEmergencyNumberPrefix) {
-                        if (number.equals(prefix + emergencyNum)) {
-                            return true;
-                        }
+                for (String prefix : mEmergencyNumberPrefix) {
+                    if (number.equals(prefix + emergencyNum)) {
+                        return true;
                     }
                 }
             }
         }
 
-        if(isSimAbsent()) {
+        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;
+                if (info.isEmergencyNumber(number, countryIso.toUpperCase(Locale.ROOT))) {
+                    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(Locale.ROOT))) {
+                            return true;
                         }
                     }
-                    return false;
                 }
+                return false;
             }
         }
 
@@ -1113,7 +1178,7 @@
      */
     private void updateEmergencyNumberListTestModeAndNotify(int action, EmergencyNumber num) {
         if (action == ADD_EMERGENCY_NUMBER_TEST_MODE) {
-            if (!isEmergencyNumber(num.getNumber(), true)) {
+            if (!isEmergencyNumber(num.getNumber())) {
                 mEmergencyNumberListFromTestMode.add(num);
             }
         } else if (action == RESET_EMERGENCY_NUMBER_TEST_MODE) {
@@ -1140,7 +1205,7 @@
 
     private List<EmergencyNumber> getEmergencyNumberListFromEccListDatabaseAndTest() {
         List<EmergencyNumber> mergedEmergencyNumberList = getEmergencyNumberListFromEccList();
-        if (mPhone.getHalVersion().greaterOrEqual(new HalVersion(1, 4))) {
+        if (!mEmergencyNumberListFromDatabase.isEmpty()) {
             loge("getEmergencyNumberListFromEccListDatabaseAndTest: radio indication is"
                     + " unavailable in 1.4 HAL.");
             mergedEmergencyNumberList.addAll(mEmergencyNumberListFromDatabase);
@@ -1148,7 +1213,12 @@
                     mEmergencyNumberListFromDatabase));
         }
         mergedEmergencyNumberList.addAll(getEmergencyNumberListTestMode());
-        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+
+        if (shouldDeterminingOfUrnsAndCategoriesWhileMergingIgnored()) {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        } else {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList, true);
+        }
         return mergedEmergencyNumberList;
     }
 
@@ -1164,16 +1234,16 @@
         return new ArrayList<>(mEmergencyNumberListFromRadio);
     }
 
-    private static void logd(String str) {
-        Rlog.d(TAG, str);
+    private void logd(String str) {
+        Rlog.d(TAG, "[" + mPhoneId + "]" + str);
     }
 
-    private static void logw(String str) {
-        Rlog.w(TAG, str);
+    private void logw(String str) {
+        Rlog.w(TAG, "[" + mPhoneId + "]" + str);
     }
 
-    private static void loge(String str) {
-        Rlog.e(TAG, str);
+    private void loge(String str) {
+        Rlog.e(TAG, "[" + mPhoneId + "]" +  str);
     }
 
     private void writeUpdatedEmergencyNumberListMetrics(
@@ -1188,6 +1258,56 @@
     }
 
     /**
+     * @return {@code true} if emergency numbers sourced from modem/config should be ignored.
+     * {@code false} if emergency numbers sourced from modem/config should not be ignored.
+     */
+    @VisibleForTesting
+    public boolean shouldModemConfigEmergencyNumbersBeIgnored() {
+        return mResources.getBoolean(com.android.internal.R.bool
+                .ignore_modem_config_emergency_numbers);
+    }
+
+    /**
+     * @return {@code true} if emergency number routing from the android emergency number
+     * database should be ignored.
+     * {@code false} if emergency number routing from the android emergency number database
+     * should not be ignored.
+     */
+    @VisibleForTesting
+    public boolean shouldEmergencyNumberRoutingFromDbBeIgnored() {
+        return mResources.getBoolean(com.android.internal.R.bool
+                .ignore_emergency_number_routing_from_db);
+    }
+
+
+    /**
+     * @return {@code true} if determining of Urns & Service Categories while merging duplicate
+     * numbers should be ignored.
+     * {@code false} if determining of Urns & Service Categories while merging duplicate
+     * numbers should not be ignored.
+     */
+    @VisibleForTesting
+    public boolean shouldDeterminingOfUrnsAndCategoriesWhileMergingIgnored() {
+        // TODO: Device config
+        return false;
+    }
+
+    /**
+     * Captures the consolidated emergency numbers list and returns the array of
+     * {@link PersistAtomsProto.EmergencyNumber}.
+     */
+    public PersistAtomsProto.EmergencyNumbersInfo[] getEmergencyNumbersProtoArray() {
+        int otaVersion = Math.max(0, getEmergencyNumberOtaDbVersion());
+        int assetVersion = Math.max(0, getEmergencyNumberDbVersion());
+        boolean isDbRoutingIgnored = shouldEmergencyNumberRoutingFromDbBeIgnored();
+        List<EmergencyNumber> emergencyNumberList = getEmergencyNumberList();
+        logd("log emergency number list=" + emergencyNumberList + " for otaVersion=" + otaVersion
+                + ", assetVersion=" + assetVersion + ", isDbRoutingIgnored=" + isDbRoutingIgnored);
+        return EmergencyNumberStats.getInstance().convertEmergencyNumbersListToProto(
+                emergencyNumberList, assetVersion, otaVersion, isDbRoutingIgnored);
+    }
+
+    /**
      * Dump Emergency Number List info in the tracking
      *
      * @param fd FileDescriptor
@@ -1196,9 +1316,6 @@
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        ipw.println(" Hal Version:" + mPhone.getHalVersion());
-        ipw.println(" ========================================= ");
-
         ipw.println(" Country Iso:" + getEmergencyCountryIso());
         ipw.println(" ========================================= ");
 
@@ -1235,11 +1352,6 @@
         ipw.decreaseIndent();
         ipw.println(" ========================================= ");
 
-        int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
-        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
-        ipw.println(" ril.ecclist: " + SystemProperties.get(ecclist, ""));
-        ipw.println(" ========================================= ");
-
         ipw.println("Emergency Number List for Phone" + "(" + mPhone.getPhoneId() + ")");
         ipw.increaseIndent();
         ipw.println(getEmergencyNumberList());
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
new file mode 100644
index 0000000..96cd880
--- /dev/null
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
@@ -0,0 +1,1208 @@
+/*
+ * 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.emergency;
+
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_NONE;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+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.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.sysprop.TelephonyProperties;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.CarrierConfigManager;
+import android.telephony.DisconnectCause;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.telephony.Rlog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+
+/**
+ * Tracks the emergency call state and notifies listeners of changes to the emergency mode.
+ */
+public class EmergencyStateTracker {
+
+    private static final String TAG = "EmergencyStateTracker";
+
+    /**
+     * Timeout before we continue with the emergency call without waiting for DDS switch response
+     * from the modem.
+     */
+    private static final int DEFAULT_DATA_SWITCH_TIMEOUT_MS = 1000;
+    /** Default value for if Emergency Callback Mode is supported. */
+    private static final boolean DEFAULT_EMERGENCY_CALLBACK_MODE_SUPPORTED = true;
+    /** Default Emergency Callback Mode exit timeout value. */
+    private static final long DEFAULT_ECM_EXIT_TIMEOUT_MS = 300000;
+
+    /** The emergency types used when setting the emergency mode on modem. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "EMERGENCY_TYPE_",
+            value = {
+                    EMERGENCY_TYPE_CALL,
+                    EMERGENCY_TYPE_SMS})
+    public @interface EmergencyType {}
+
+    /** Indicates the emergency type is call. */
+    public static final int EMERGENCY_TYPE_CALL = 1;
+    /** Indicates the emergency type is SMS. */
+    public static final int EMERGENCY_TYPE_SMS = 2;
+
+    private static EmergencyStateTracker INSTANCE = null;
+
+    private final Context mContext;
+    private final CarrierConfigManager mConfigManager;
+    private final Handler mHandler;
+    private final boolean mIsSuplDdsSwitchRequiredForEmergencyCall;
+    private final PowerManager.WakeLock mWakeLock;
+    private RadioOnHelper mRadioOnHelper;
+    @EmergencyConstants.EmergencyMode
+    private int mEmergencyMode = MODE_EMERGENCY_NONE;
+    private boolean mWasEmergencyModeSetOnModem;
+    private EmergencyRegResult mLastEmergencyRegResult;
+    private boolean mIsEmergencyModeInProgress;
+    private boolean mIsEmergencyCallStartedDuringEmergencySms;
+
+    /** For emergency calls */
+    private final long mEcmExitTimeoutMs;
+    // A runnable which is used to automatically exit from Ecm after a period of time.
+    private final Runnable mExitEcmRunnable = this::exitEmergencyCallbackMode;
+    // Tracks emergency calls by callId that have reached {@link Call.State#ACTIVE}.
+    private final Set<String> mActiveEmergencyCalls = new ArraySet<>();
+    private Phone mPhone;
+    // Tracks ongoing emergency callId to handle a second emergency call
+    private String mOngoingCallId;
+    // Domain of the active emergency call. Assuming here that there will only be one domain active.
+    private int mEmergencyCallDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN;
+    private CompletableFuture<Integer> mCallEmergencyModeFuture;
+    private boolean mIsInEmergencyCall;
+    private boolean mIsInEcm;
+    private boolean mIsTestEmergencyNumber;
+    private Runnable mOnEcmExitCompleteRunnable;
+
+    /** For emergency SMS */
+    private final Set<String> mOngoingEmergencySmsIds = new ArraySet<>();
+    private Phone mSmsPhone;
+    private CompletableFuture<Integer> mSmsEmergencyModeFuture;
+    private boolean mIsTestEmergencyNumberForSms;
+
+    /**
+     * Listens for Emergency Callback Mode state change intents
+     */
+    private final BroadcastReceiver mEcmExitReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(
+                    TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+
+                boolean isInEcm = intent.getBooleanExtra(
+                        TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false);
+                Rlog.d(TAG, "Received ACTION_EMERGENCY_CALLBACK_MODE_CHANGED isInEcm = " + isInEcm);
+
+                // If we exit ECM mode, notify all connections.
+                if (!isInEcm) {
+                    exitEmergencyCallbackMode();
+                }
+            }
+        }
+    };
+
+    /** PhoneFactory Dependencies for testing. */
+    @VisibleForTesting
+    public interface PhoneFactoryProxy {
+        Phone[] getPhones();
+    }
+
+    private PhoneFactoryProxy mPhoneFactoryProxy = PhoneFactory::getPhones;
+
+    /** PhoneSwitcher dependencies for testing. */
+    @VisibleForTesting
+    public interface PhoneSwitcherProxy {
+
+        PhoneSwitcher getPhoneSwitcher();
+    }
+
+    private PhoneSwitcherProxy mPhoneSwitcherProxy = PhoneSwitcher::getInstance;
+
+    /**
+     * TelephonyManager dependencies for testing.
+     */
+    @VisibleForTesting
+    public interface TelephonyManagerProxy {
+        int getPhoneCount();
+    }
+
+    private final TelephonyManagerProxy mTelephonyManagerProxy;
+
+    private static class TelephonyManagerProxyImpl implements TelephonyManagerProxy {
+        private final TelephonyManager mTelephonyManager;
+
+
+        TelephonyManagerProxyImpl(Context context) {
+            mTelephonyManager = new TelephonyManager(context);
+        }
+
+        @Override
+        public int getPhoneCount() {
+            return mTelephonyManager.getActiveModemCount();
+        }
+    }
+
+    /**
+     * Return the handler for testing.
+     */
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    @VisibleForTesting
+    public static final int MSG_SET_EMERGENCY_MODE_DONE = 1;
+    @VisibleForTesting
+    public static final int MSG_EXIT_EMERGENCY_MODE_DONE = 2;
+    @VisibleForTesting
+    public static final int MSG_SET_EMERGENCY_CALLBACK_MODE_DONE = 3;
+
+    private class MyHandler extends Handler {
+
+        MyHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_SET_EMERGENCY_MODE_DONE: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Integer emergencyType = (Integer) ar.userObj;
+                    Rlog.v(TAG, "MSG_SET_EMERGENCY_MODE_DONE for "
+                            + emergencyTypeToString(emergencyType));
+                    if (ar.exception == null) {
+                        mLastEmergencyRegResult = (EmergencyRegResult) ar.result;
+                    } else {
+                        mLastEmergencyRegResult = null;
+                        Rlog.w(TAG, "LastEmergencyRegResult not set. AsyncResult.exception: "
+                                + ar.exception);
+                    }
+                    setEmergencyModeInProgress(false);
+
+                    if (emergencyType == EMERGENCY_TYPE_CALL) {
+                        setIsInEmergencyCall(true);
+                        completeEmergencyMode(emergencyType);
+
+                        // Case 1) When the emergency call is setting the emergency mode and
+                        // the emergency SMS is being sent, completes the SMS future also.
+                        // Case 2) When the emergency SMS is setting the emergency mode and
+                        // the emergency call is beint started, the SMS request is cancelled and
+                        // the call request will be handled.
+                        if (mSmsPhone != null) {
+                            completeEmergencyMode(EMERGENCY_TYPE_SMS);
+                        }
+                    } else if (emergencyType == EMERGENCY_TYPE_SMS) {
+                        if (mPhone != null && mSmsPhone != null) {
+                            // Clear call phone temporarily to exit the emergency mode
+                            // if the emergency call is started.
+                            if (mIsEmergencyCallStartedDuringEmergencySms) {
+                                Phone phone = mPhone;
+                                mPhone = null;
+                                exitEmergencyMode(mSmsPhone, emergencyType);
+                                // Restore call phone for further use.
+                                mPhone = phone;
+
+                                if (!isSamePhone(mPhone, mSmsPhone)) {
+                                    completeEmergencyMode(emergencyType,
+                                            DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED);
+                                }
+                            } else {
+                                completeEmergencyMode(emergencyType);
+                            }
+                            break;
+                        } else {
+                            completeEmergencyMode(emergencyType);
+                        }
+
+                        if (mIsEmergencyCallStartedDuringEmergencySms) {
+                            mIsEmergencyCallStartedDuringEmergencySms = false;
+                            turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL,
+                                    mIsTestEmergencyNumber);
+                        }
+                    }
+                    break;
+                }
+                case MSG_EXIT_EMERGENCY_MODE_DONE: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Integer emergencyType = (Integer) ar.userObj;
+                    Rlog.v(TAG, "MSG_EXIT_EMERGENCY_MODE_DONE for "
+                            + emergencyTypeToString(emergencyType));
+                    setEmergencyModeInProgress(false);
+
+                    if (emergencyType == EMERGENCY_TYPE_CALL) {
+                        setIsInEmergencyCall(false);
+                        if (mOnEcmExitCompleteRunnable != null) {
+                            mOnEcmExitCompleteRunnable.run();
+                            mOnEcmExitCompleteRunnable = null;
+                        }
+                    } else if (emergencyType == EMERGENCY_TYPE_SMS) {
+                        if (mIsEmergencyCallStartedDuringEmergencySms) {
+                            mIsEmergencyCallStartedDuringEmergencySms = false;
+                            turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL,
+                                    mIsTestEmergencyNumber);
+                        }
+                    }
+                    break;
+                }
+                case MSG_SET_EMERGENCY_CALLBACK_MODE_DONE: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Integer emergencyType = (Integer) ar.userObj;
+                    Rlog.v(TAG, "MSG_SET_EMERGENCY_CALLBACK_MODE_DONE for "
+                            + emergencyTypeToString(emergencyType));
+                    setEmergencyModeInProgress(false);
+                    // When the emergency callback mode is in progress and the emergency SMS is
+                    // started, it needs to be completed here for the emergency SMS.
+                    if (mSmsPhone != null) {
+                        completeEmergencyMode(EMERGENCY_TYPE_SMS);
+                    }
+                    break;
+                }
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Creates the EmergencyStateTracker singleton instance.
+     *
+     * @param context                                 The context of the application.
+     * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for
+     *                                                emergency call.
+     */
+    public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall) {
+        if (INSTANCE == null) {
+            INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(),
+                    isSuplDdsSwitchRequiredForEmergencyCall);
+        }
+    }
+
+    /**
+     * Returns the singleton instance of EmergencyStateTracker.
+     *
+     * @return {@link EmergencyStateTracker} instance.
+     */
+    public static EmergencyStateTracker getInstance() {
+        if (INSTANCE == null) {
+            throw new IllegalStateException("EmergencyStateTracker is not ready!");
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * Initializes EmergencyStateTracker.
+     */
+    private EmergencyStateTracker(Context context, Looper looper,
+            boolean isSuplDdsSwitchRequiredForEmergencyCall) {
+        mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS;
+        mContext = context;
+        mHandler = new MyHandler(looper);
+        mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall;
+
+        PowerManager pm = context.getSystemService(PowerManager.class);
+        mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                "telephony:" + TAG) : null;
+        mConfigManager = context.getSystemService(CarrierConfigManager.class);
+
+        // Register receiver for ECM exit.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        context.registerReceiver(mEcmExitReceiver, filter, null, mHandler);
+        mTelephonyManagerProxy = new TelephonyManagerProxyImpl(context);
+    }
+
+    /**
+     * Initializes EmergencyStateTracker with injections for testing.
+     *
+     * @param context                                 The context of the application.
+     * @param looper                                  The {@link Looper} of the application.
+     * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for
+     *                                                emergency call.
+     * @param phoneFactoryProxy                       The {@link PhoneFactoryProxy} to be injected.
+     * @param phoneSwitcherProxy                      The {@link PhoneSwitcherProxy} to be injected.
+     * @param telephonyManagerProxy                   The {@link TelephonyManagerProxy} to be
+     *                                                injected.
+     * @param radioOnHelper                           The {@link RadioOnHelper} to be injected.
+     */
+    @VisibleForTesting
+    public EmergencyStateTracker(Context context, Looper looper,
+            boolean isSuplDdsSwitchRequiredForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy,
+            PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy,
+            RadioOnHelper radioOnHelper, long ecmExitTimeoutMs) {
+        mContext = context;
+        mHandler = new MyHandler(looper);
+        mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall;
+        mPhoneFactoryProxy = phoneFactoryProxy;
+        mPhoneSwitcherProxy = phoneSwitcherProxy;
+        mTelephonyManagerProxy = telephonyManagerProxy;
+        mRadioOnHelper = radioOnHelper;
+        mEcmExitTimeoutMs = ecmExitTimeoutMs;
+        mWakeLock = null; // Don't declare a wakelock in tests
+        mConfigManager = context.getSystemService(CarrierConfigManager.class);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        context.registerReceiver(mEcmExitReceiver, filter, null, mHandler);
+    }
+
+    /**
+     * Starts the process of an emergency call.
+     *
+     * <p>
+     * Handles turning on radio and switching DDS.
+     *
+     * @param phone                 the {@code Phone} on which to process the emergency call.
+     * @param callId                the call id on which to process the emergency call.
+     * @param isTestEmergencyNumber whether this is a test emergency number.
+     * @return a {@code CompletableFuture} that results in {@code DisconnectCause.NOT_DISCONNECTED}
+     *         if emergency call successfully started.
+     */
+    public CompletableFuture<Integer> startEmergencyCall(@NonNull Phone phone,
+            @NonNull String callId, boolean isTestEmergencyNumber) {
+        Rlog.i(TAG, "startEmergencyCall: phoneId=" + phone.getPhoneId() + ", callId=" + callId);
+
+        if (mPhone != null) {
+            // Create new future to return as to not interfere with any uncompleted futures.
+            // Case1) When 2nd emergency call is initiated during an active call on the same phone.
+            // Case2) While the device is in ECBM, an emergency call is initiated on the same phone.
+            if (isSamePhone(mPhone, phone) && (!mActiveEmergencyCalls.isEmpty() || isInEcm())) {
+                mOngoingCallId = callId;
+                mIsTestEmergencyNumber = isTestEmergencyNumber;
+                return CompletableFuture.completedFuture(DisconnectCause.NOT_DISCONNECTED);
+            }
+
+            Rlog.e(TAG, "startEmergencyCall failed. Existing emergency call in progress.");
+            return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED);
+        }
+
+        mCallEmergencyModeFuture = new CompletableFuture<>();
+
+        if (mSmsPhone != null) {
+            mIsEmergencyCallStartedDuringEmergencySms = true;
+            // Case1) While exiting the emergency mode on the other phone,
+            // the emergency mode for this call will be restarted after the exit complete.
+            // Case2) While entering the emergency mode on the other phone,
+            // exit the emergency mode when receiving the result of setting the emergency mode and
+            // the emergency mode for this call will be restarted after the exit complete.
+            if (isInEmergencyMode() && !isEmergencyModeInProgress()) {
+                exitEmergencyMode(mSmsPhone, EMERGENCY_TYPE_SMS);
+            }
+
+            mPhone = phone;
+            mOngoingCallId = callId;
+            mIsTestEmergencyNumber = isTestEmergencyNumber;
+            return mCallEmergencyModeFuture;
+        }
+
+        mPhone = phone;
+        mOngoingCallId = callId;
+        mIsTestEmergencyNumber = isTestEmergencyNumber;
+        turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber);
+        return mCallEmergencyModeFuture;
+    }
+
+    /**
+     * Ends emergency call.
+     *
+     * <p>
+     * Enter ECM only once all active emergency calls have ended. If a call never reached
+     * {@link Call.State#ACTIVE}, then no need to enter ECM.
+     *
+     * @param callId the call id on which to end the emergency call.
+     */
+    public void endCall(@NonNull String callId) {
+        boolean wasActive = mActiveEmergencyCalls.remove(callId);
+
+        if (Objects.equals(mOngoingCallId, callId)) {
+            mOngoingCallId = null;
+        }
+
+        if (wasActive && mActiveEmergencyCalls.isEmpty()
+                && isEmergencyCallbackModeSupported()) {
+            enterEmergencyCallbackMode();
+
+            if (mOngoingCallId == null) {
+                mIsEmergencyCallStartedDuringEmergencySms = false;
+                mCallEmergencyModeFuture = null;
+            }
+        } else if (mOngoingCallId == null) {
+            if (isInEcm()) {
+                mIsEmergencyCallStartedDuringEmergencySms = false;
+                mCallEmergencyModeFuture = null;
+                // If the emergency call was initiated during the emergency callback mode,
+                // the emergency callback mode should be restored when the emergency call is ended.
+                if (mActiveEmergencyCalls.isEmpty()) {
+                    setEmergencyMode(mPhone, EMERGENCY_TYPE_CALL, MODE_EMERGENCY_CALLBACK,
+                            MSG_SET_EMERGENCY_CALLBACK_MODE_DONE);
+                }
+            } else {
+                exitEmergencyMode(mPhone, EMERGENCY_TYPE_CALL);
+                clearEmergencyCallInfo();
+            }
+        }
+    }
+
+    private void clearEmergencyCallInfo() {
+        mEmergencyCallDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN;
+        mIsTestEmergencyNumber = false;
+        mIsEmergencyCallStartedDuringEmergencySms = false;
+        mCallEmergencyModeFuture = null;
+        mOngoingCallId = null;
+        mPhone = null;
+    }
+
+    private void switchDdsAndSetEmergencyMode(Phone phone, @EmergencyType int emergencyType) {
+        switchDdsDelayed(phone, result -> {
+            Rlog.i(TAG, "switchDdsDelayed: result = " + result);
+            if (!result) {
+                // DDS Switch timed out/failed, but continue with call as it may still succeed.
+                Rlog.e(TAG, "DDS Switch failed.");
+            }
+            // Once radio is on and DDS switched, must call setEmergencyMode() before selecting
+            // emergency domain. EmergencyRegResult is required to determine domain and this is the
+            // only API that can receive it before starting domain selection. Once domain selection
+            // is finished, the actual emergency mode will be set when onEmergencyTransportChanged()
+            // is called.
+            setEmergencyMode(phone, emergencyType, MODE_EMERGENCY_WWAN,
+                    MSG_SET_EMERGENCY_MODE_DONE);
+        });
+    }
+
+    /**
+     * Triggers modem to set new emergency mode.
+     *
+     * @param phone the {@code Phone} to set the emergency mode on modem.
+     * @param emergencyType the emergency type to identify an emergency call or SMS.
+     * @param mode the new emergency mode.
+     * @param msg the message to be sent once mode has been set.
+     */
+    private void setEmergencyMode(Phone phone, @EmergencyType int emergencyType,
+            @EmergencyConstants.EmergencyMode int mode, int msg) {
+        Rlog.i(TAG, "setEmergencyMode from " + mEmergencyMode + " to " + mode + " for "
+                + emergencyTypeToString(emergencyType));
+
+        if (mEmergencyMode == mode) {
+            return;
+        }
+        mEmergencyMode = mode;
+        setEmergencyModeInProgress(true);
+
+        Message m = mHandler.obtainMessage(msg, Integer.valueOf(emergencyType));
+        if ((mIsTestEmergencyNumber && emergencyType == EMERGENCY_TYPE_CALL)
+                || (mIsTestEmergencyNumberForSms && emergencyType == EMERGENCY_TYPE_SMS)) {
+            Rlog.d(TAG, "TestEmergencyNumber for " + emergencyTypeToString(emergencyType)
+                    + ": Skipping setting emergency mode on modem.");
+            // Send back a response for the command, but with null information
+            AsyncResult.forMessage(m, null, null);
+            // Ensure that we do not accidentally block indefinitely when trying to validate test
+            // emergency numbers
+            m.sendToTarget();
+            return;
+        }
+
+        mWasEmergencyModeSetOnModem = true;
+        phone.setEmergencyMode(mode, m);
+    }
+
+    private void completeEmergencyMode(@EmergencyType int emergencyType) {
+        completeEmergencyMode(emergencyType, DisconnectCause.NOT_DISCONNECTED);
+    }
+
+    private void completeEmergencyMode(@EmergencyType int emergencyType,
+            @DisconnectCauses int result) {
+        if (emergencyType == EMERGENCY_TYPE_CALL) {
+            if (mCallEmergencyModeFuture != null && !mCallEmergencyModeFuture.isDone()) {
+                mCallEmergencyModeFuture.complete(result);
+            }
+
+            if (result != DisconnectCause.NOT_DISCONNECTED) {
+                clearEmergencyCallInfo();
+            }
+        } else if (emergencyType == EMERGENCY_TYPE_SMS) {
+            if (mSmsEmergencyModeFuture != null && !mSmsEmergencyModeFuture.isDone()) {
+                mSmsEmergencyModeFuture.complete(result);
+            }
+
+            if (result != DisconnectCause.NOT_DISCONNECTED) {
+                clearEmergencySmsInfo();
+            }
+        }
+    }
+
+    /**
+     * Checks if the device is currently in the emergency mode or not.
+     */
+    @VisibleForTesting
+    public boolean isInEmergencyMode() {
+        return mEmergencyMode != MODE_EMERGENCY_NONE;
+    }
+
+    /**
+     * Sets the flag to inidicate whether setting the emergency mode on modem is in progress or not.
+     */
+    private void setEmergencyModeInProgress(boolean isEmergencyModeInProgress) {
+        mIsEmergencyModeInProgress = isEmergencyModeInProgress;
+    }
+
+    /**
+     * Checks whether setting the emergency mode on modem is in progress or not.
+     */
+    private boolean isEmergencyModeInProgress() {
+        return mIsEmergencyModeInProgress;
+    }
+
+    /**
+     * Notifies external app listeners of emergency mode changes.
+     *
+     * @param isInEmergencyCall a flag to indicate whether there is an active emergency call.
+     */
+    private void setIsInEmergencyCall(boolean isInEmergencyCall) {
+        mIsInEmergencyCall = isInEmergencyCall;
+    }
+
+    /**
+     * Checks if there is an ongoing emergency call.
+     *
+     * @return true if in emergency call
+     */
+    public boolean isInEmergencyCall() {
+        return mIsInEmergencyCall;
+    }
+
+    /**
+     * Triggers modem to exit emergency mode.
+     *
+     * @param phone the {@code Phone} to exit the emergency mode.
+     * @param emergencyType the emergency type to identify an emergency call or SMS.
+     */
+    private void exitEmergencyMode(Phone phone, @EmergencyType int emergencyType) {
+        Rlog.i(TAG, "exitEmergencyMode for " + emergencyTypeToString(emergencyType));
+
+        if (emergencyType == EMERGENCY_TYPE_CALL) {
+            if (mSmsPhone != null && isSamePhone(phone, mSmsPhone)) {
+                // Waits for exiting the emergency mode until the emergency SMS is ended.
+                Rlog.i(TAG, "exitEmergencyMode: waits for emergency SMS end.");
+                setIsInEmergencyCall(false);
+                return;
+            }
+        } else if (emergencyType == EMERGENCY_TYPE_SMS) {
+            if (mPhone != null && isSamePhone(phone, mPhone)) {
+                // Waits for exiting the emergency mode until the emergency call is ended.
+                Rlog.i(TAG, "exitEmergencyMode: waits for emergency call end.");
+                return;
+            }
+        }
+
+        if (mEmergencyMode == MODE_EMERGENCY_NONE) {
+            return;
+        }
+        mEmergencyMode = MODE_EMERGENCY_NONE;
+        setEmergencyModeInProgress(true);
+
+        Message m = mHandler.obtainMessage(
+                MSG_EXIT_EMERGENCY_MODE_DONE, Integer.valueOf(emergencyType));
+        if (!mWasEmergencyModeSetOnModem) {
+            Rlog.d(TAG, "Emergency mode was not set on modem: Skipping exiting emergency mode.");
+            // Send back a response for the command, but with null information
+            AsyncResult.forMessage(m, null, null);
+            // Ensure that we do not accidentally block indefinitely when trying to validate
+            // the exit condition.
+            m.sendToTarget();
+            return;
+        }
+
+        mWasEmergencyModeSetOnModem = false;
+        phone.exitEmergencyMode(m);
+    }
+
+    /** Returns last {@link EmergencyRegResult} as set by {@code setEmergencyMode()}. */
+    public EmergencyRegResult getEmergencyRegResult() {
+        return mLastEmergencyRegResult;
+    }
+
+    /**
+     * Handles emergency transport change by setting new emergency mode.
+     *
+     * @param emergencyType the emergency type to identify an emergency call or SMS
+     * @param mode the new emergency mode
+     */
+    public void onEmergencyTransportChanged(@EmergencyType int emergencyType,
+            @EmergencyConstants.EmergencyMode int mode) {
+        if (mHandler.getLooper().isCurrentThread()) {
+            Phone phone = null;
+            if (emergencyType == EMERGENCY_TYPE_CALL) {
+                phone = mPhone;
+            } else if (emergencyType == EMERGENCY_TYPE_SMS) {
+                phone = mSmsPhone;
+            }
+
+            if (phone != null) {
+                setEmergencyMode(phone, emergencyType, mode, MSG_SET_EMERGENCY_MODE_DONE);
+            }
+        } else {
+            mHandler.post(() -> {
+                onEmergencyTransportChanged(emergencyType, mode);
+            });
+        }
+    }
+
+    /**
+     * Notify the tracker that the emergency call domain has been updated.
+     * @param phoneType The new PHONE_TYPE_* of the call.
+     * @param callId The ID of the call
+     */
+    public void onEmergencyCallDomainUpdated(int phoneType, String callId) {
+        Rlog.d(TAG, "domain update for callId: " + callId);
+        int domain = -1;
+        switch(phoneType) {
+            case (PhoneConstants.PHONE_TYPE_CDMA_LTE):
+                //fallthrough
+            case (PhoneConstants.PHONE_TYPE_GSM):
+                //fallthrough
+            case (PhoneConstants.PHONE_TYPE_CDMA): {
+                domain = NetworkRegistrationInfo.DOMAIN_CS;
+                break;
+            }
+            case (PhoneConstants.PHONE_TYPE_IMS): {
+                domain = NetworkRegistrationInfo.DOMAIN_PS;
+                break;
+            }
+            default: {
+                Rlog.w(TAG, "domain updated: Unexpected phoneType:" + phoneType);
+            }
+        }
+        if (mEmergencyCallDomain == domain) return;
+        Rlog.i(TAG, "domain updated: from " + mEmergencyCallDomain + " to " + domain);
+        mEmergencyCallDomain = domain;
+    }
+
+    /**
+     * Handles emergency call state change.
+     *
+     * @param state the new call state
+     * @param callId the callId whose state has changed
+     */
+    public void onEmergencyCallStateChanged(Call.State state, String callId) {
+        if (state == Call.State.ACTIVE) {
+            mActiveEmergencyCalls.add(callId);
+        }
+    }
+
+    /**
+     * Returns {@code true} if device and carrier support emergency callback mode.
+     */
+    private boolean isEmergencyCallbackModeSupported() {
+        return getConfig(mPhone.getSubId(),
+                CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL,
+                DEFAULT_EMERGENCY_CALLBACK_MODE_SUPPORTED);
+    }
+
+    /**
+     * Trigger entry into emergency callback mode.
+     */
+    private void enterEmergencyCallbackMode() {
+        Rlog.d(TAG, "enter ECBM");
+        setIsInEmergencyCall(false);
+        // Check if not in ECM already.
+        if (!isInEcm()) {
+            setIsInEcm(true);
+            if (!mPhone.getUnitTestMode()) {
+                TelephonyProperties.in_ecm_mode(true);
+            }
+
+            // Notify listeners of the entrance to ECM.
+            sendEmergencyCallbackModeChange();
+            if (isInImsEcm()) {
+                // emergency call registrants are not notified of new emergency call until entering
+                // ECBM (see ImsPhone#handleEnterEmergencyCallbackMode)
+                ((GsmCdmaPhone) mPhone).notifyEmergencyCallRegistrants(true);
+            }
+
+            // Set emergency mode on modem.
+            setEmergencyMode(mPhone, EMERGENCY_TYPE_CALL, MODE_EMERGENCY_CALLBACK,
+                    MSG_SET_EMERGENCY_CALLBACK_MODE_DONE);
+
+            // Post this runnable so we will automatically exit if no one invokes
+            // exitEmergencyCallbackMode() directly.
+            long delayInMillis = TelephonyProperties.ecm_exit_timer()
+                    .orElse(mEcmExitTimeoutMs);
+            mHandler.postDelayed(mExitEcmRunnable, delayInMillis);
+
+            // We don't want to go to sleep while in ECM.
+            if (mWakeLock != null) mWakeLock.acquire(delayInMillis);
+        }
+    }
+
+    /**
+     * Exits emergency callback mode and notifies relevant listeners.
+     */
+    public void exitEmergencyCallbackMode() {
+        Rlog.d(TAG, "exit ECBM");
+        // Remove pending exit ECM runnable, if any.
+        mHandler.removeCallbacks(mExitEcmRunnable);
+
+        if (isInEcm()) {
+            setIsInEcm(false);
+            if (!mPhone.getUnitTestMode()) {
+                TelephonyProperties.in_ecm_mode(false);
+            }
+
+            // Release wakeLock.
+            if (mWakeLock != null && mWakeLock.isHeld()) {
+                try {
+                    mWakeLock.release();
+                } catch (Exception e) {
+                    // Ignore the exception if the system has already released this WakeLock.
+                    Rlog.d(TAG, "WakeLock already released: " + e.toString());
+                }
+            }
+
+            GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) mPhone;
+            // Send intents that ECM has changed.
+            sendEmergencyCallbackModeChange();
+            gsmCdmaPhone.notifyEmergencyCallRegistrants(false);
+
+            // Exit emergency mode on modem.
+            exitEmergencyMode(gsmCdmaPhone, EMERGENCY_TYPE_CALL);
+        }
+
+        mEmergencyCallDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN;
+        mIsTestEmergencyNumber = false;
+        mPhone = null;
+    }
+
+    /**
+     * Exits emergency callback mode and triggers runnable after exit response is received.
+     */
+    public void exitEmergencyCallbackMode(Runnable onComplete) {
+        mOnEcmExitCompleteRunnable = onComplete;
+        exitEmergencyCallbackMode();
+    }
+
+    /**
+     * Sends intents that emergency callback mode changed.
+     */
+    private void sendEmergencyCallbackModeChange() {
+        Rlog.d(TAG, "sendEmergencyCallbackModeChange: isInEcm=" + isInEcm());
+
+        Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, isInEcm());
+        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
+        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    /**
+     * Returns {@code true} if currently in emergency callback mode.
+     *
+     * <p>
+     * This is a period where the phone should be using as little power as possible and be ready to
+     * receive an incoming call from the emergency operator.
+     */
+    public boolean isInEcm() {
+        return mIsInEcm;
+    }
+
+    /**
+     * Sets the emergency callback mode state.
+     *
+     * @param isInEcm {@code true} if currently in emergency callback mode, {@code false} otherwise.
+     */
+    private void setIsInEcm(boolean isInEcm) {
+        mIsInEcm = isInEcm;
+    }
+
+    /**
+     * Returns {@code true} if currently in emergency callback mode over PS
+     */
+    public boolean isInImsEcm() {
+        return mEmergencyCallDomain == NetworkRegistrationInfo.DOMAIN_PS && isInEcm();
+    }
+
+    /**
+     * Returns {@code true} if currently in emergency callback mode over CS
+     */
+    public boolean isInCdmaEcm() {
+        // Phone can be null in the case where we are not actively tracking an emergency call.
+        if (mPhone == null) return false;
+        // Ensure that this method doesn't return true when we are attached to GSM.
+        return mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                && mEmergencyCallDomain == NetworkRegistrationInfo.DOMAIN_CS && isInEcm();
+    }
+
+    /**
+     * Starts the process of an emergency SMS.
+     *
+     * @param phone the {@code Phone} on which to process the emergency SMS.
+     * @param smsId the SMS id on which to process the emergency SMS.
+     * @param isTestEmergencyNumber whether this is a test emergency number.
+     * @return A {@code CompletableFuture} that results in {@code DisconnectCause.NOT_DISCONNECTED}
+     *         if the emergency SMS is successfully started.
+     */
+    public CompletableFuture<Integer> startEmergencySms(@NonNull Phone phone, @NonNull String smsId,
+            boolean isTestEmergencyNumber) {
+        Rlog.i(TAG, "startEmergencySms: phoneId=" + phone.getPhoneId() + ", smsId=" + smsId);
+
+        // When an emergency call is in progress, it checks whether an emergency call is already in
+        // progress on the different phone.
+        if (mPhone != null && !isSamePhone(mPhone, phone)) {
+            Rlog.e(TAG, "Emergency call is in progress on the other slot.");
+            return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED);
+        }
+
+        // When an emergency SMS is in progress, it checks whether an emergency SMS is already in
+        // progress on the different phone.
+        if (mSmsPhone != null && !isSamePhone(mSmsPhone, phone)) {
+            Rlog.e(TAG, "Emergency SMS is in progress on the other slot.");
+            return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED);
+        }
+
+        // When the previous emergency SMS is not completed yet,
+        // this new request will not be allowed.
+        if (mSmsPhone != null && isInEmergencyMode() && isEmergencyModeInProgress()) {
+            Rlog.e(TAG, "Existing emergency SMS is in progress.");
+            return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED);
+        }
+
+        mSmsPhone = phone;
+        mIsTestEmergencyNumberForSms = isTestEmergencyNumber;
+        mOngoingEmergencySmsIds.add(smsId);
+
+        // When the emergency mode is already set by the previous emergency call or SMS,
+        // completes the future immediately.
+        if (isInEmergencyMode() && !isEmergencyModeInProgress()) {
+            return CompletableFuture.completedFuture(DisconnectCause.NOT_DISCONNECTED);
+        }
+
+        mSmsEmergencyModeFuture = new CompletableFuture<>();
+        if (!isInEmergencyMode()) {
+            setEmergencyMode(mSmsPhone, EMERGENCY_TYPE_SMS, MODE_EMERGENCY_WWAN,
+                    MSG_SET_EMERGENCY_MODE_DONE);
+        }
+        return mSmsEmergencyModeFuture;
+    }
+
+    /**
+     * Ends an emergency SMS.
+     * This should be called once an emergency SMS is sent.
+     *
+     * @param smsId the SMS id on which to end the emergency SMS.
+     * @param emergencyNumber the emergency number which was used for the emergency SMS.
+     */
+    public void endSms(@NonNull String smsId, EmergencyNumber emergencyNumber) {
+        mOngoingEmergencySmsIds.remove(smsId);
+
+        // If the outgoing emergency SMSs are empty, we can try to exit the emergency mode.
+        if (mOngoingEmergencySmsIds.isEmpty()) {
+            if (isInEcm()) {
+                // When the emergency mode is not in MODE_EMERGENCY_CALLBACK,
+                // it needs to notify the emergency callback mode to modem.
+                if (mActiveEmergencyCalls.isEmpty() && mOngoingCallId == null) {
+                    setEmergencyMode(mPhone, EMERGENCY_TYPE_CALL, MODE_EMERGENCY_CALLBACK,
+                            MSG_SET_EMERGENCY_CALLBACK_MODE_DONE);
+                }
+            } else {
+                exitEmergencyMode(mSmsPhone, EMERGENCY_TYPE_SMS);
+            }
+
+            clearEmergencySmsInfo();
+        }
+    }
+
+    private void clearEmergencySmsInfo() {
+        mOngoingEmergencySmsIds.clear();
+        mIsTestEmergencyNumberForSms = false;
+        mSmsEmergencyModeFuture = null;
+        mSmsPhone = null;
+    }
+
+    /**
+     * Returns {@code true} if any phones from PhoneFactory have radio on.
+     */
+    private boolean isRadioOn() {
+        boolean result = false;
+        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
+            result |= phone.isRadioOn();
+        }
+        return result;
+    }
+
+    /**
+     * Returns {@code true} if airplane mode is on.
+     */
+    private boolean isAirplaneModeOn(Context context) {
+        return Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0) > 0;
+    }
+
+    /**
+     * Ensures that the radio is switched on and that DDS is switched for emergency call/SMS.
+     *
+     * <p>
+     * Once radio is on and DDS switched, must call setEmergencyMode() before completing the future
+     * and selecting emergency domain. EmergencyRegResult is required to determine domain and
+     * setEmergencyMode() is the only API that can receive it before starting domain selection.
+     * Once domain selection is finished, the actual emergency mode will be set when
+     * onEmergencyTransportChanged() is called.
+     *
+     * @param phone the {@code Phone} for the emergency call/SMS.
+     * @param emergencyType the emergency type to identify an emergency call or SMS.
+     * @param isTestEmergencyNumber a flag to inidicate whether the emergency call/SMS uses the test
+     *                              emergency number.
+     */
+    private void turnOnRadioAndSwitchDds(Phone phone, @EmergencyType int emergencyType,
+            boolean isTestEmergencyNumber) {
+        final boolean isAirplaneModeOn = isAirplaneModeOn(mContext);
+        boolean needToTurnOnRadio = !isRadioOn() || isAirplaneModeOn;
+
+        if (needToTurnOnRadio) {
+            Rlog.i(TAG, "turnOnRadioAndSwitchDds: phoneId=" + phone.getPhoneId() + " for "
+                    + emergencyTypeToString(emergencyType));
+            if (mRadioOnHelper == null) {
+                mRadioOnHelper = new RadioOnHelper(mContext);
+            }
+
+            mRadioOnHelper.triggerRadioOnAndListen(new RadioOnStateListener.Callback() {
+                @Override
+                public void onComplete(RadioOnStateListener listener, boolean isRadioReady) {
+                    if (!isRadioReady) {
+                        // Could not turn radio on
+                        Rlog.e(TAG, "Failed to turn on radio.");
+                        completeEmergencyMode(emergencyType, DisconnectCause.POWER_OFF);
+                    } else {
+                        switchDdsAndSetEmergencyMode(phone, emergencyType);
+                    }
+                }
+
+                @Override
+                public boolean isOkToCall(Phone phone, int serviceState, boolean imsVoiceCapable) {
+                    // We currently only look to make sure that the radio is on before dialing. We
+                    // should be able to make emergency calls at any time after the radio has been
+                    // powered on and isn't in the UNAVAILABLE state, even if it is reporting the
+                    // OUT_OF_SERVICE state.
+                    return phone.getServiceStateTracker().isRadioOn();
+                }
+
+                @Override
+                public boolean onTimeout(Phone phone, int serviceState, boolean imsVoiceCapable) {
+                    return true;
+                }
+            }, !isTestEmergencyNumber, phone, isTestEmergencyNumber, 0);
+        } else {
+            switchDdsAndSetEmergencyMode(phone, emergencyType);
+        }
+    }
+
+    /**
+     * If needed, block until the default data is switched for outgoing emergency call, or
+     * timeout expires.
+     *
+     * @param phone            The Phone to switch the DDS on.
+     * @param completeConsumer The consumer to call once the default data subscription has been
+     *                         switched, provides {@code true} result if the switch happened
+     *                         successfully or {@code false} if the operation timed out/failed.
+     */
+    @VisibleForTesting
+    public void switchDdsDelayed(Phone phone, Consumer<Boolean> completeConsumer) {
+        if (phone == null) {
+            // Do not block indefinitely.
+            completeConsumer.accept(false);
+        }
+        try {
+            // Waiting for PhoneSwitcher to complete the operation.
+            CompletableFuture<Boolean> future = possiblyOverrideDefaultDataForEmergencyCall(phone);
+            // In the case that there is an issue or bug in PhoneSwitcher logic, do not wait
+            // indefinitely for the future to complete. Instead, set a timeout that will complete
+            // the future as to not block the outgoing call indefinitely.
+            CompletableFuture<Boolean> timeout = new CompletableFuture<>();
+            mHandler.postDelayed(() -> timeout.complete(false), DEFAULT_DATA_SWITCH_TIMEOUT_MS);
+            // Also ensure that the Consumer is completed on the main thread.
+            CompletableFuture<Void> unused = future.acceptEitherAsync(timeout, completeConsumer,
+                    mHandler::post);
+        } catch (Exception e) {
+            Rlog.w(TAG, "switchDdsDelayed - exception= " + e.getMessage());
+        }
+    }
+
+    /**
+     * If needed, block until Default Data subscription is switched for outgoing emergency call.
+     *
+     * <p>
+     * In some cases, we need to try to switch the Default Data subscription before placing the
+     * emergency call on DSDS devices. This includes the following situation: - The modem does not
+     * support processing GNSS SUPL requests on the non-default data subscription. For some carriers
+     * that do not provide a control plane fallback mechanism, the SUPL request will be dropped and
+     * we will not be able to get the user's location for the emergency call. In this case, we need
+     * to swap default data temporarily.
+     *
+     * @param phone Evaluates whether or not the default data should be moved to the phone
+     *              specified. Should not be null.
+     */
+    private CompletableFuture<Boolean> possiblyOverrideDefaultDataForEmergencyCall(
+            @NonNull Phone phone) {
+        int phoneCount = mTelephonyManagerProxy.getPhoneCount();
+        // Do not override DDS if this is a single SIM device.
+        if (phoneCount <= PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM) {
+            return CompletableFuture.completedFuture(Boolean.TRUE);
+        }
+
+        // Do not switch Default data if this device supports emergency SUPL on non-DDS.
+        if (!mIsSuplDdsSwitchRequiredForEmergencyCall) {
+            Rlog.d(TAG, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, does not "
+                    + "require DDS switch.");
+            return CompletableFuture.completedFuture(Boolean.TRUE);
+        }
+
+        // Only override default data if we are IN_SERVICE already.
+        if (!isAvailableForEmergencyCalls(phone)) {
+            Rlog.d(TAG, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS");
+            return CompletableFuture.completedFuture(Boolean.TRUE);
+        }
+
+        // Only override default data if we are not roaming, we do not want to switch onto a network
+        // that only supports data plane only (if we do not know).
+        boolean isRoaming = phone.getServiceState().getVoiceRoaming();
+        // In some roaming conditions, we know the roaming network doesn't support control plane
+        // fallback even though the home operator does. For these operators we will need to do a DDS
+        // switch anyway to make sure the SUPL request doesn't fail.
+        boolean roamingNetworkSupportsControlPlaneFallback = true;
+        String[] dataPlaneRoamPlmns = getConfig(phone.getSubId(),
+                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY);
+        if (dataPlaneRoamPlmns != null && Arrays.asList(dataPlaneRoamPlmns)
+                .contains(phone.getServiceState().getOperatorNumeric())) {
+            roamingNetworkSupportsControlPlaneFallback = false;
+        }
+        if (isRoaming && roamingNetworkSupportsControlPlaneFallback) {
+            Rlog.d(TAG, "possiblyOverrideDefaultDataForEmergencyCall: roaming network is assumed "
+                    + "to support CP fallback, not switching DDS.");
+            return CompletableFuture.completedFuture(Boolean.TRUE);
+        }
+        // Do not try to swap default data if we support CS fallback or it is assumed that the
+        // roaming network supports control plane fallback, we do not want to introduce a lag in
+        // emergency call setup time if possible.
+        final boolean supportsCpFallback = getConfig(phone.getSubId(),
+                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_ONLY)
+                != CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY;
+        if (supportsCpFallback && roamingNetworkSupportsControlPlaneFallback) {
+            Rlog.d(TAG, "possiblyOverrideDefaultDataForEmergencyCall: not switching DDS, carrier "
+                    + "supports CP fallback.");
+            return CompletableFuture.completedFuture(Boolean.TRUE);
+        }
+
+        // Get extension time, may be 0 for some carriers that support ECBM as well. Use
+        // CarrierConfig default if format fails.
+        int extensionTime = 0;
+        try {
+            extensionTime = Integer.parseInt(getConfig(phone.getSubId(),
+                    CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0"));
+        } catch (NumberFormatException e) {
+            // Just use default.
+        }
+        CompletableFuture<Boolean> modemResultFuture = new CompletableFuture<>();
+        try {
+            Rlog.d(TAG, "possiblyOverrideDefaultDataForEmergencyCall: overriding DDS for "
+                    + extensionTime + "seconds");
+            mPhoneSwitcherProxy.getPhoneSwitcher().overrideDefaultDataForEmergency(
+                    phone.getPhoneId(), extensionTime, modemResultFuture);
+            // Catch all exceptions, we want to continue with emergency call if possible.
+        } catch (Exception e) {
+            Rlog.w(TAG,
+                    "possiblyOverrideDefaultDataForEmergencyCall: exception = " + e.getMessage());
+            modemResultFuture = CompletableFuture.completedFuture(Boolean.FALSE);
+        }
+        return modemResultFuture;
+    }
+
+    // Helper functions for easy CarrierConfigManager access
+    private String getConfig(int subId, String key, String defVal) {
+        return getConfigBundle(subId, key).getString(key, defVal);
+    }
+    private int getConfig(int subId, String key, int defVal) {
+        return getConfigBundle(subId, key).getInt(key, defVal);
+    }
+    private String[] getConfig(int subId, String key) {
+        return getConfigBundle(subId, key).getStringArray(key);
+    }
+    private boolean getConfig(int subId, String key, boolean defVal) {
+        return getConfigBundle(subId, key).getBoolean(key, defVal);
+    }
+    private PersistableBundle getConfigBundle(int subId, String key) {
+        if (mConfigManager == null) return new PersistableBundle();
+        return mConfigManager.getConfigForSubId(subId, key);
+    }
+
+    /**
+     * Returns true if the state of the Phone is IN_SERVICE or available for emergency calling only.
+     */
+    private boolean isAvailableForEmergencyCalls(Phone phone) {
+        return ServiceState.STATE_IN_SERVICE == phone.getServiceState().getState()
+                || phone.getServiceState().isEmergencyOnly();
+    }
+
+    /**
+     * Checks whether both {@code Phone}s are same or not.
+     */
+    private static boolean isSamePhone(Phone p1, Phone p2) {
+        return p1 != null && p2 != null && (p1.getPhoneId() == p2.getPhoneId());
+    }
+
+    private static String emergencyTypeToString(@EmergencyType int emergencyType) {
+        switch (emergencyType) {
+            case EMERGENCY_TYPE_CALL: return "CALL";
+            case EMERGENCY_TYPE_SMS: return "SMS";
+            default: return "UNKNOWN";
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java b/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java
new file mode 100644
index 0000000..9c4ebfa
--- /dev/null
+++ b/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java
@@ -0,0 +1,189 @@
+/*
+ * 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.emergency;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.telephony.Rlog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class that implements special behavior related to emergency calls or making phone calls
+ * when the radio is in the POWER_OFF STATE. Specifically, this class handles the case of the user
+ * trying to dial an emergency number while the radio is off (i.e. the device is in airplane mode)
+ * or a normal number while the radio is off (because of the device is on Bluetooth), by turning the
+ * radio back on, waiting for it to come up, and then retrying the call.
+ */
+public class RadioOnHelper implements RadioOnStateListener.Callback {
+
+    private static final String TAG = "RadioOnStateListener";
+
+    private final Context mContext;
+    private RadioOnStateListener.Callback mCallback;
+    private List<RadioOnStateListener> mListeners;
+    private List<RadioOnStateListener> mInProgressListeners;
+    private boolean mIsRadioReady;
+
+    public RadioOnHelper(Context context) {
+        mContext = context;
+        mInProgressListeners = new ArrayList<>(2);
+    }
+
+    private void setupListeners() {
+        if (mListeners == null) {
+            mListeners = new ArrayList<>(2);
+        }
+        int activeModems = TelephonyManager.from(mContext).getActiveModemCount();
+        // Add new listeners if active modem count increased.
+        while (mListeners.size() < activeModems) {
+            mListeners.add(new RadioOnStateListener());
+        }
+        // Clean up listeners if active modem count decreased.
+        while (mListeners.size() > activeModems) {
+            mListeners.get(mListeners.size() - 1).cleanup();
+            mListeners.remove(mListeners.size() - 1);
+        }
+    }
+
+    /**
+     * Starts the "turn on radio" sequence. This is the (single) external API of the RadioOnHelper
+     * class.
+     *
+     * This method kicks off the following sequence:
+     * - Power on the radio for each Phone and disable the satellite modem
+     * - Listen for events telling us the radio has come up or the satellite modem is disabled.
+     * - Retry if we've gone a significant amount of time without any response.
+     * - Finally, clean up any leftover state.
+     *
+     * This method is safe to call from any thread, since it simply posts a message to the
+     * RadioOnHelper's handler (thus ensuring that the rest of the sequence is entirely serialized,
+     * and runs on the main looper.)
+     */
+    public void triggerRadioOnAndListen(RadioOnStateListener.Callback callback,
+            boolean forEmergencyCall, Phone phoneForEmergencyCall, boolean isTestEmergencyNumber,
+            int emergencyTimeoutIntervalMillis) {
+        setupListeners();
+        mCallback = callback;
+        mInProgressListeners.clear();
+        mIsRadioReady = false;
+        for (int i = 0; i < TelephonyManager.from(mContext).getActiveModemCount(); i++) {
+            Phone phone = PhoneFactory.getPhone(i);
+            if (phone == null) {
+                continue;
+            }
+
+            int timeoutCallbackInterval = (forEmergencyCall && phone == phoneForEmergencyCall)
+                    ? emergencyTimeoutIntervalMillis : 0;
+            mInProgressListeners.add(mListeners.get(i));
+            mListeners.get(i).waitForRadioOn(phone, this, forEmergencyCall, forEmergencyCall
+                    && phone == phoneForEmergencyCall, timeoutCallbackInterval);
+        }
+        powerOnRadio(forEmergencyCall, phoneForEmergencyCall, isTestEmergencyNumber);
+        if (SatelliteController.getInstance().isSatelliteEnabled()) {
+            powerOffSatellite(phoneForEmergencyCall);
+        }
+    }
+
+    /**
+     * Attempt to power on the radio (i.e. take the device out of airplane mode). We'll eventually
+     * get an onServiceStateChanged() callback when the radio successfully comes up.
+     */
+    private void powerOnRadio(boolean forEmergencyCall, Phone phoneForEmergencyCall,
+            boolean isTestEmergencyNumber) {
+
+        // Always try to turn on the radio here independent of APM setting - if we got here in the
+        // first place, the radio is off independent of APM setting.
+        for (Phone phone : PhoneFactory.getPhones()) {
+            Rlog.d(TAG, "powerOnRadio, enabling Radio");
+            if (isTestEmergencyNumber) {
+                phone.setRadioPowerOnForTestEmergencyCall(phone == phoneForEmergencyCall);
+            } else {
+                phone.setRadioPower(true, forEmergencyCall, phone == phoneForEmergencyCall,
+                        false);
+            }
+        }
+
+        // If airplane mode is on, we turn it off the same way that the Settings activity turns it
+        // off to keep the setting in sync.
+        if (Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0) > 0) {
+            Rlog.d(TAG, "==> Turning off airplane mode for emergency call.");
+
+            // Change the system setting
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.AIRPLANE_MODE_ON, 0);
+
+            // Post the broadcast intend for change in airplane mode TODO: We really should not be
+            // in charge of sending this broadcast. If changing the setting is sufficient to trigger
+            // all of the rest of the logic, then that should also trigger the broadcast intent.
+            Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intent.putExtra("state", false);
+            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+        }
+    }
+
+    /**
+     * Attempt to power off the satellite modem. We'll eventually get an
+     * onSatelliteModemStateChanged() callback when the satellite modem is successfully disabled.
+     */
+    private void powerOffSatellite(Phone phoneForEmergencyCall) {
+        SatelliteController satelliteController = SatelliteController.getInstance();
+        satelliteController.requestSatelliteEnabled(phoneForEmergencyCall.getSubId(),
+                false /* enableSatellite */, false /* enableDemoMode */,
+                new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+
+                    }
+                });
+    }
+
+    /**
+     * This method is called from multiple Listeners on the Main Looper. Synchronization is not
+     * necessary.
+     */
+    @Override
+    public void onComplete(RadioOnStateListener listener, boolean isRadioReady) {
+        mIsRadioReady |= isRadioReady;
+        mInProgressListeners.remove(listener);
+        if (mCallback != null && mInProgressListeners.isEmpty()) {
+            mCallback.onComplete(null, mIsRadioReady);
+        }
+    }
+
+    @Override
+    public boolean isOkToCall(Phone phone, int serviceState, boolean imsVoiceCapable) {
+        return (mCallback == null)
+                ? false : mCallback.isOkToCall(phone, serviceState, imsVoiceCapable);
+    }
+
+    @Override
+    public boolean onTimeout(Phone phone, int serviceState, boolean imsVoiceCapable) {
+        return (mCallback == null)
+                ? false : mCallback.onTimeout(phone, serviceState, imsVoiceCapable);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
new file mode 100644
index 0000000..d61c146
--- /dev/null
+++ b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
@@ -0,0 +1,584 @@
+/*
+ * 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.emergency;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.satellite.ISatelliteStateCallback;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.telephony.Rlog;
+
+import java.util.Locale;
+
+/**
+ * Helper class that listens to a Phone's radio state and sends an onComplete callback when we
+ * return true for isOkToCall.
+ */
+public class RadioOnStateListener {
+
+    public interface Callback {
+        /**
+         * Receives the result of the RadioOnStateListener's attempt to turn on the radio
+         * and turn off the satellite modem.
+         */
+        void onComplete(RadioOnStateListener listener, boolean isRadioReady);
+
+        /**
+         * Returns whether or not this phone is ok to call.
+         * If it is, onComplete will be called shortly after.
+         *
+         * @param phone The Phone associated.
+         * @param serviceState The service state of that phone.
+         * @param imsVoiceCapable The IMS voice capability of that phone.
+         * @return {@code true} if this phone is ok to call. Otherwise, {@code false}.
+         */
+        boolean isOkToCall(Phone phone, int serviceState, boolean imsVoiceCapable);
+
+        /**
+         * Returns whether or not this phone is ok to call.
+         * This callback will be called when timeout happens.
+         * If this returns {@code true}, onComplete will be called shortly after.
+         * Otherwise, a new timer will be started again to keep waiting for next timeout.
+         * The timeout interval will be passed to {@link #waitForRadioOn()} when registering
+         * this callback.
+         *
+         * @param phone The Phone associated.
+         * @param serviceState The service state of that phone.
+         * @param imsVoiceCapable The IMS voice capability of that phone.
+         * @return {@code true} if this phone is ok to call. Otherwise, {@code false}.
+         */
+        boolean onTimeout(Phone phone, int serviceState, boolean imsVoiceCapable);
+    }
+
+    private static final String TAG = "RadioOnStateListener";
+
+    // Number of times to retry the call, and time between retry attempts.
+    // not final for testing
+    private static int MAX_NUM_RETRIES = 5;
+    // not final for testing
+    private static long TIME_BETWEEN_RETRIES_MILLIS = 5000; // msec
+
+    // Handler message codes; see handleMessage()
+    private static final int MSG_START_SEQUENCE = 1;
+    @VisibleForTesting
+    public static final int MSG_SERVICE_STATE_CHANGED = 2;
+    private static final int MSG_RETRY_TIMEOUT = 3;
+    @VisibleForTesting
+    public static final int MSG_RADIO_ON = 4;
+    public static final int MSG_RADIO_OFF_OR_NOT_AVAILABLE = 5;
+    public static final int MSG_IMS_CAPABILITY_CHANGED = 6;
+    public static final int MSG_TIMEOUT_ONTIMEOUT_CALLBACK = 7;
+    @VisibleForTesting
+    public static final int MSG_SATELLITE_ENABLED_CHANGED = 8;
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_START_SEQUENCE:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        Phone phone = (Phone) args.arg1;
+                        RadioOnStateListener.Callback callback =
+                                (RadioOnStateListener.Callback) args.arg2;
+                        boolean forEmergencyCall = (boolean) args.arg3;
+                        boolean isSelectedPhoneForEmergencyCall = (boolean) args.arg4;
+                        int onTimeoutCallbackInterval = args.argi1;
+                        startSequenceInternal(phone, callback, forEmergencyCall,
+                                isSelectedPhoneForEmergencyCall, onTimeoutCallbackInterval);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                case MSG_SERVICE_STATE_CHANGED:
+                    onServiceStateChanged((ServiceState) ((AsyncResult) msg.obj).result);
+                    break;
+                case MSG_RADIO_ON:
+                    onRadioOn();
+                    break;
+                case MSG_RADIO_OFF_OR_NOT_AVAILABLE:
+                    registerForRadioOn();
+                    break;
+                case MSG_RETRY_TIMEOUT:
+                    onRetryTimeout();
+                    break;
+                case MSG_IMS_CAPABILITY_CHANGED:
+                    onImsCapabilityChanged();
+                    break;
+                case MSG_TIMEOUT_ONTIMEOUT_CALLBACK:
+                    onTimeoutCallbackTimeout();
+                    break;
+                case MSG_SATELLITE_ENABLED_CHANGED:
+                    onSatelliteEnabledChanged();
+                    break;
+                default:
+                    Rlog.w(TAG, String.format(Locale.getDefault(),
+                        "handleMessage: unexpected message: %d.", msg.what));
+                    break;
+            }
+        }
+    };
+
+    private final ISatelliteStateCallback mSatelliteCallback = new ISatelliteStateCallback.Stub() {
+        @Override
+        public void onSatelliteModemStateChanged(int state) {
+            mHandler.obtainMessage(MSG_SATELLITE_ENABLED_CHANGED).sendToTarget();
+        }
+    };
+
+    private Callback mCallback; // The callback to notify upon completion.
+    private Phone mPhone; // The phone that will attempt to place the call.
+    // SatelliteController instance to check whether satellite has been disabled.
+    private SatelliteController mSatelliteController;
+    private boolean mForEmergencyCall; // Whether radio is being turned on for emergency call.
+    // Whether this phone is selected to place emergency call. Can be true only if
+    // mForEmergencyCall is true.
+    private boolean mSelectedPhoneForEmergencyCall;
+    private int mNumRetriesSoFar;
+    private int mOnTimeoutCallbackInterval; // the interval between onTimeout callbacks
+
+    /**
+     * Starts the "wait for radio" sequence. This is the (single) external API of the
+     * RadioOnStateListener class.
+     *
+     * This method kicks off the following sequence:
+     * - Listen for the service state change event telling us the radio has come up.
+     * - Listen for the satellite state changed event telling us the satellite service is disabled.
+     * - Retry if we've gone {@link #TIME_BETWEEN_RETRIES_MILLIS} without any response from the
+     *   radio.
+     * - Finally, clean up any leftover state.
+     *
+     * This method is safe to call from any thread, since it simply posts a message to the
+     * RadioOnStateListener's handler (thus ensuring that the rest of the sequence is entirely
+     * serialized, and runs only on the handler thread.)
+     */
+    public void waitForRadioOn(Phone phone, Callback callback,
+            boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall,
+            int onTimeoutCallbackInterval) {
+        Rlog.d(TAG, "waitForRadioOn: Phone " + phone.getPhoneId());
+
+        if (mPhone != null) {
+            // If there already is an ongoing request, ignore the new one!
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = phone;
+        args.arg2 = callback;
+        args.arg3 = forEmergencyCall;
+        args.arg4 = isSelectedPhoneForEmergencyCall;
+        args.argi1 = onTimeoutCallbackInterval;
+        mHandler.obtainMessage(MSG_START_SEQUENCE, args).sendToTarget();
+    }
+
+    /**
+     * Actual implementation of waitForRadioOn(), guaranteed to run on the handler thread.
+     *
+     * @see #waitForRadioOn
+     */
+    private void startSequenceInternal(Phone phone, Callback callback,
+            boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall,
+            int onTimeoutCallbackInterval) {
+        Rlog.d(TAG, "startSequenceInternal: Phone " + phone.getPhoneId());
+        mSatelliteController = SatelliteController.getInstance();
+
+        // First of all, clean up any state left over from a prior RadioOn call sequence. This
+        // ensures that we'll behave sanely if another startTurnOnRadioSequence() comes in while
+        // we're already in the middle of the sequence.
+        cleanup();
+
+        mPhone = phone;
+        mCallback = callback;
+        mForEmergencyCall = forEmergencyCall;
+        mSelectedPhoneForEmergencyCall = isSelectedPhoneForEmergencyCall;
+        mOnTimeoutCallbackInterval = onTimeoutCallbackInterval;
+
+        registerForServiceStateChanged();
+        // Register for RADIO_OFF to handle cases where emergency call is dialed before
+        // we receive UNSOL_RESPONSE_RADIO_STATE_CHANGED with RADIO_OFF.
+        registerForRadioOff();
+        if (mSatelliteController.isSatelliteEnabled()) {
+            // Register for satellite modem state changed to notify when satellite is disabled.
+            registerForSatelliteEnabledChanged();
+        }
+        // Next step: when the SERVICE_STATE_CHANGED or SATELLITE_ENABLED_CHANGED event comes in,
+        // we'll retry the call; see onServiceStateChanged() and onSatelliteEnabledChanged().
+        // But also, just in case, start a timer to make sure we'll retry the call even if the
+        // SERVICE_STATE_CHANGED or SATELLITE_ENABLED_CHANGED events never come in for some reason.
+        startRetryTimer();
+        registerForImsCapabilityChanged();
+        startOnTimeoutCallbackTimer();
+    }
+
+    private void onImsCapabilityChanged() {
+        if (mPhone == null) {
+            return;
+        }
+
+        boolean imsVoiceCapable = mPhone.isVoiceOverCellularImsEnabled();
+
+        Rlog.d(TAG, String.format("onImsCapabilityChanged, capable = %s, Phone = %s",
+                imsVoiceCapable, mPhone.getPhoneId()));
+
+        if (isOkToCall(mPhone.getServiceState().getState(), imsVoiceCapable)) {
+            Rlog.d(TAG, "onImsCapabilityChanged: ok to call!");
+
+            onComplete(true);
+            cleanup();
+        } else {
+            // The IMS capability changed, but we're still not ready to call yet.
+            Rlog.d(TAG, "onImsCapabilityChanged: not ready to call yet, keep waiting.");
+        }
+    }
+
+    private void onTimeoutCallbackTimeout() {
+        if (mPhone == null) {
+            return;
+        }
+
+        if (onTimeout(mPhone.getServiceState().getState(),
+                  mPhone.isVoiceOverCellularImsEnabled())) {
+            Rlog.d(TAG, "onTimeout: ok to call!");
+
+            onComplete(true);
+            cleanup();
+        } else if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
+            Rlog.w(TAG, "onTimeout: Hit MAX_NUM_RETRIES; giving up.");
+            cleanup();
+        } else {
+            Rlog.d(TAG, "onTimeout: not ready to call yet, keep waiting.");
+            startOnTimeoutCallbackTimer();
+        }
+    }
+
+    /**
+     * Handles the SERVICE_STATE_CHANGED event. This event tells us that the radio state has changed
+     * and is probably coming up. We can now check to see if the conditions are met to place the
+     * call with {@link Callback#isOkToCall}
+     */
+    private void onServiceStateChanged(ServiceState state) {
+        if (mPhone == null) {
+            return;
+        }
+        Rlog.d(TAG, String.format("onServiceStateChanged(), new state = %s, Phone = %s", state,
+                mPhone.getPhoneId()));
+
+        // Possible service states:
+        // - STATE_IN_SERVICE        // Normal operation
+        // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
+        //                           // or no radio signal
+        // - STATE_EMERGENCY_ONLY    // Only emergency numbers are allowed; currently not used
+        // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
+
+        if (isOkToCall(state.getState(), mPhone.isVoiceOverCellularImsEnabled())) {
+            // Woo hoo! It's OK to actually place the call.
+            Rlog.d(TAG, "onServiceStateChanged: ok to call!");
+
+            onComplete(true);
+            cleanup();
+        } else {
+            // The service state changed, but we're still not ready to call yet.
+            Rlog.d(TAG, "onServiceStateChanged: not ready to call yet, keep waiting.");
+        }
+    }
+
+    private void onRadioOn() {
+        if (mPhone == null) {
+            return;
+        }
+        ServiceState state = mPhone.getServiceState();
+        Rlog.d(TAG, String.format("onRadioOn, state = %s, Phone = %s", state, mPhone.getPhoneId()));
+        if (isOkToCall(state.getState(), mPhone.isVoiceOverCellularImsEnabled())) {
+            onComplete(true);
+            cleanup();
+        } else {
+            Rlog.d(TAG, "onRadioOn: not ready to call yet, keep waiting.");
+        }
+    }
+
+    private void onSatelliteEnabledChanged() {
+        if (mPhone == null) {
+            return;
+        }
+        if (isOkToCall(mPhone.getServiceState().getState(),
+                mPhone.isVoiceOverCellularImsEnabled())) {
+            onComplete(true);
+            cleanup();
+        } else {
+            Rlog.d(TAG, "onSatelliteEnabledChanged: not ready to call yet, keep waiting.");
+        }
+    }
+
+    /**
+     * Callback to see if it is okay to call yet, given the current conditions.
+     */
+    private boolean isOkToCall(int serviceState, boolean imsVoiceCapable) {
+        return (mCallback == null)
+                ? false : mCallback.isOkToCall(mPhone, serviceState, imsVoiceCapable);
+    }
+
+    /**
+     * Callback to see if it is okay to call yet, given the current conditions.
+     */
+    private boolean onTimeout(int serviceState, boolean imsVoiceCapable) {
+        return (mCallback == null)
+                ? false : mCallback.onTimeout(mPhone, serviceState, imsVoiceCapable);
+    }
+
+    /**
+     * Handles the retry timer expiring.
+     */
+    private void onRetryTimeout() {
+        if (mPhone == null) {
+            return;
+        }
+        int serviceState = mPhone.getServiceState().getState();
+        Rlog.d(TAG,
+                String.format(Locale.getDefault(),
+                        "onRetryTimeout():  phone state = %s, service state = %d, retries = %d.",
+                        mPhone.getState(), serviceState, mNumRetriesSoFar));
+
+        // - If we're actually in a call, we've succeeded.
+        // - Otherwise, if the radio is now on, that means we successfully got out of airplane mode
+        //   but somehow didn't get the service state change event. In that case, try to place the
+        //   call.
+        // - If the radio is still powered off, try powering it on again.
+
+        if (isOkToCall(serviceState, mPhone.isVoiceOverCellularImsEnabled())) {
+            Rlog.d(TAG, "onRetryTimeout: Radio is on. Cleaning up.");
+
+            // Woo hoo -- we successfully got out of airplane mode.
+            onComplete(true);
+            cleanup();
+        } else {
+            // Uh oh; we've waited the full TIME_BETWEEN_RETRIES_MILLIS and the radio is still not
+            // powered-on. Try again.
+
+            mNumRetriesSoFar++;
+            Rlog.d(TAG, "mNumRetriesSoFar is now " + mNumRetriesSoFar);
+
+            if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
+                if (mHandler.hasMessages(MSG_TIMEOUT_ONTIMEOUT_CALLBACK)) {
+                    Rlog.w(TAG, "Hit MAX_NUM_RETRIES; waiting onTimeout callback");
+                    return;
+                }
+                Rlog.w(TAG, "Hit MAX_NUM_RETRIES; giving up.");
+                cleanup();
+            } else {
+                Rlog.d(TAG, "Trying (again) to turn the radio on and satellite modem off.");
+                mPhone.setRadioPower(true, mForEmergencyCall, mSelectedPhoneForEmergencyCall,
+                        false);
+                if (mSatelliteController.isSatelliteEnabled()) {
+                    mSatelliteController.requestSatelliteEnabled(mPhone.getSubId(),
+                            false /* enableSatellite */, false /* enableDemoMode */,
+                            new IIntegerConsumer.Stub() {
+                                @Override
+                                public void accept(int result) {
+                                    mHandler.obtainMessage(MSG_SATELLITE_ENABLED_CHANGED)
+                                            .sendToTarget();
+                                }
+                            });
+                }
+                startRetryTimer();
+            }
+        }
+    }
+
+    /**
+     * Clean up when done with the whole sequence: either after successfully turning on the radio,
+     * or after bailing out because of too many failures.
+     *
+     * The exact cleanup steps are:
+     * - Notify callback if we still hadn't sent it a response.
+     * - Double-check that we're not still registered for any telephony events
+     * - Clean up any extraneous handler messages (like retry timeouts) still in the queue
+     *
+     * Basically this method guarantees that there will be no more activity from the
+     * RadioOnStateListener until someone kicks off the whole sequence again with another call to
+     * {@link #waitForRadioOn}
+     *
+     * TODO: Do the work for the comment below: Note we don't call this method simply after a
+     * successful call to placeCall(), since it's still possible the call will disconnect very
+     * quickly with an OUT_OF_SERVICE error.
+     */
+    public void cleanup() {
+        Rlog.d(TAG, "cleanup()");
+
+        // This will send a failure call back if callback has yet to be invoked. If the callback was
+        // already invoked, it's a no-op.
+        onComplete(false);
+
+        unregisterForServiceStateChanged();
+        unregisterForRadioOff();
+        unregisterForRadioOn();
+        unregisterForSatelliteEnabledChanged();
+        cancelRetryTimer();
+        unregisterForImsCapabilityChanged();
+
+        // Used for unregisterForServiceStateChanged() so we null it out here instead.
+        mPhone = null;
+        mNumRetriesSoFar = 0;
+        mOnTimeoutCallbackInterval = 0;
+    }
+
+    private void startRetryTimer() {
+        cancelRetryTimer();
+        mHandler.sendEmptyMessageDelayed(MSG_RETRY_TIMEOUT, TIME_BETWEEN_RETRIES_MILLIS);
+    }
+
+    private void cancelRetryTimer() {
+        mHandler.removeMessages(MSG_RETRY_TIMEOUT);
+    }
+
+    private void registerForServiceStateChanged() {
+        // Unregister first, just to make sure we never register ourselves twice. (We need this
+        // because Phone.registerForServiceStateChanged() does not prevent multiple registration of
+        // the same handler.)
+        unregisterForServiceStateChanged();
+        mPhone.registerForServiceStateChanged(mHandler, MSG_SERVICE_STATE_CHANGED, null);
+    }
+
+    private void unregisterForServiceStateChanged() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.unregisterForServiceStateChanged(mHandler); // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_SERVICE_STATE_CHANGED); // Clean up any pending messages too
+    }
+
+    private void registerForRadioOff() {
+        mPhone.mCi.registerForOffOrNotAvailable(mHandler, MSG_RADIO_OFF_OR_NOT_AVAILABLE, null);
+    }
+
+    private void unregisterForRadioOff() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.mCi.unregisterForOffOrNotAvailable(mHandler); // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_RADIO_OFF_OR_NOT_AVAILABLE); // Clean up any pending messages
+    }
+
+    private void registerForRadioOn() {
+        unregisterForRadioOff();
+        mPhone.mCi.registerForOn(mHandler, MSG_RADIO_ON, null);
+    }
+
+    private void unregisterForRadioOn() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.mCi.unregisterForOn(mHandler); // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_RADIO_ON); // Clean up any pending messages too
+    }
+
+    private void registerForSatelliteEnabledChanged() {
+        mSatelliteController.registerForSatelliteModemStateChanged(
+                mPhone.getSubId(), mSatelliteCallback);
+    }
+
+    private void unregisterForSatelliteEnabledChanged() {
+        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        if (mPhone != null) {
+            subId = mPhone.getSubId();
+        }
+        mSatelliteController.unregisterForSatelliteModemStateChanged(subId, mSatelliteCallback);
+        mHandler.removeMessages(MSG_SATELLITE_ENABLED_CHANGED);
+    }
+
+    private void registerForImsCapabilityChanged() {
+        unregisterForImsCapabilityChanged();
+        mPhone.getServiceStateTracker()
+                .registerForImsCapabilityChanged(mHandler, MSG_IMS_CAPABILITY_CHANGED, null);
+    }
+
+    private void unregisterForImsCapabilityChanged() {
+        if (mPhone != null) {
+            mPhone.getServiceStateTracker()
+                    .unregisterForImsCapabilityChanged(mHandler);
+        }
+        mHandler.removeMessages(MSG_IMS_CAPABILITY_CHANGED);
+    }
+
+    private void startOnTimeoutCallbackTimer() {
+        Rlog.d(TAG, "startOnTimeoutCallbackTimer: mOnTimeoutCallbackInterval="
+                + mOnTimeoutCallbackInterval);
+        mHandler.removeMessages(MSG_TIMEOUT_ONTIMEOUT_CALLBACK);
+        if (mOnTimeoutCallbackInterval > 0) {
+            mHandler.sendEmptyMessageDelayed(MSG_TIMEOUT_ONTIMEOUT_CALLBACK,
+                    mOnTimeoutCallbackInterval);
+        }
+    }
+
+    private void onComplete(boolean isRadioReady) {
+        if (mCallback != null) {
+            Callback tempCallback = mCallback;
+            mCallback = null;
+            tempCallback.onComplete(this, isRadioReady);
+        }
+    }
+
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    @VisibleForTesting
+    public void setMaxNumRetries(int retries) {
+        MAX_NUM_RETRIES = retries;
+    }
+
+    @VisibleForTesting
+    public void setTimeBetweenRetriesMillis(long timeMs) {
+        TIME_BETWEEN_RETRIES_MILLIS = timeMs;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || !getClass().equals(o.getClass()))
+            return false;
+
+        RadioOnStateListener that = (RadioOnStateListener) o;
+
+        if (mNumRetriesSoFar != that.mNumRetriesSoFar) {
+            return false;
+        }
+        if (mCallback != null ? !mCallback.equals(that.mCallback) : that.mCallback != null) {
+            return false;
+        }
+        return mPhone != null ? mPhone.equals(that.mPhone) : that.mPhone == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 31 * hash + mNumRetriesSoFar;
+        hash = 31 * hash + (mCallback == null ? 0 : mCallback.hashCode());
+        hash = 31 * hash + (mPhone == null ? 0 : mPhone.hashCode());
+        return hash;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccCardController.java b/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
index bb42b2a..2f73c91 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
@@ -39,8 +39,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
@@ -416,7 +414,7 @@
         // if there is no iccid enabled on this port, return null.
         if (TextUtils.isEmpty(iccId)) {
             try {
-                callback.onComplete(EuiccCardManager.RESULT_PROFILE_NOT_FOUND, null);
+                callback.onComplete(EuiccCardManager.RESULT_PROFILE_DOES_NOT_EXIST, null);
             } catch (RemoteException exception) {
                 loge("getEnabledProfile callback failure.", exception);
             }
@@ -652,14 +650,8 @@
             @Override
             public void onResult(Void result) {
                 Log.i(TAG, "Request subscription info list refresh after delete.");
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
-                            List.of(mUiccController.convertToPublicCardId(cardId)), null);
-                } else {
-                    SubscriptionController.getInstance()
-                            .requestEmbeddedSubscriptionInfoListRefresh(
-                                    mUiccController.convertToPublicCardId(cardId));
-                }
+                SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
+                        List.of(mUiccController.convertToPublicCardId(cardId)), null);
                 try {
                     callback.onComplete(EuiccCardManager.RESULT_OK);
                 } catch (RemoteException exception) {
@@ -709,14 +701,8 @@
             @Override
             public void onResult(Void result) {
                 Log.i(TAG, "Request subscription info list refresh after reset memory.");
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
-                            List.of(mUiccController.convertToPublicCardId(cardId)), null);
-                } else {
-                    SubscriptionController.getInstance()
-                            .requestEmbeddedSubscriptionInfoListRefresh(
-                                    mUiccController.convertToPublicCardId(cardId));
-                }
+                SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
+                        List.of(mUiccController.convertToPublicCardId(cardId)), null);
                 try {
                     callback.onComplete(EuiccCardManager.RESULT_OK);
                 } catch (RemoteException exception) {
@@ -1203,14 +1189,8 @@
             @Override
             public void onResult(byte[] result) {
                 Log.i(TAG, "Request subscription info list refresh after install.");
-                if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                    SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
-                            List.of(mUiccController.convertToPublicCardId(cardId)), null);
-                } else {
-                    SubscriptionController.getInstance()
-                            .requestEmbeddedSubscriptionInfoListRefresh(
-                                    mUiccController.convertToPublicCardId(cardId));
-                }
+                SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
+                        List.of(mUiccController.convertToPublicCardId(cardId)), null);
                 try {
                     callback.onComplete(EuiccCardManager.RESULT_OK, result);
                 } catch (RemoteException exception) {
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
index 974acf9..c417a34 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
@@ -101,7 +101,8 @@
      * true or onServiceDisconnected is called (and no package change has occurred which should
      * force us to reestablish the binding).
      */
-    private static final int BIND_TIMEOUT_MILLIS = 30000;
+    @VisibleForTesting
+    static final int BIND_TIMEOUT_MILLIS = 30000;
 
     /**
      * Maximum amount of idle time to hold the binding while in {@link ConnectedState}. After this,
@@ -225,6 +226,8 @@
     static class GetMetadataRequest {
         DownloadableSubscription mSubscription;
         boolean mForceDeactivateSim;
+        boolean mSwitchAfterDownload;
+        int mPortIndex;
         GetMetadataCommandCallback mCallback;
     }
 
@@ -389,6 +392,9 @@
         mSm = (SubscriptionManager)
                 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
 
+        // TODO(b/239277548): Disable debug logging after analysing this bug.
+        setDbg(true);
+
         // Unavailable/Available both monitor for package changes and update mSelectedComponent but
         // do not need to adjust the binding.
         mUnavailableState = new UnavailableState();
@@ -444,13 +450,15 @@
 
     /** Asynchronously fetch metadata for the given downloadable subscription. */
     @VisibleForTesting(visibility = PACKAGE)
-    public void getDownloadableSubscriptionMetadata(int cardId,
-            DownloadableSubscription subscription,
+    public void getDownloadableSubscriptionMetadata(int cardId, int portIndex,
+            DownloadableSubscription subscription, boolean switchAfterDownload,
             boolean forceDeactivateSim, GetMetadataCommandCallback callback) {
         GetMetadataRequest request =
                 new GetMetadataRequest();
         request.mSubscription = subscription;
         request.mForceDeactivateSim = forceDeactivateSim;
+        request.mSwitchAfterDownload = switchAfterDownload;
+        request.mPortIndex = portIndex;
         request.mCallback = callback;
         sendMessage(CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA, cardId, 0 /* arg2 */, request);
     }
@@ -549,6 +557,11 @@
                 callback);
     }
 
+    @VisibleForTesting
+    public final IEuiccService getBinder() {
+        return mEuiccService;
+    }
+
     /**
      * State in which no EuiccService is available.
      *
@@ -686,6 +699,7 @@
                 }
                 return HANDLED;
             } else if (message.what == CMD_CONNECT_TIMEOUT) {
+                unbind();
                 transitionTo(mAvailableState);
                 return HANDLED;
             } else if (isEuiccCommand(message.what)) {
@@ -749,7 +763,9 @@
                         case CMD_GET_DOWNLOADABLE_SUBSCRIPTION_METADATA: {
                             GetMetadataRequest request = (GetMetadataRequest) message.obj;
                             mEuiccService.getDownloadableSubscriptionMetadata(slotId,
+                                    request.mPortIndex,
                                     request.mSubscription,
+                                    request.mSwitchAfterDownload,
                                     request.mForceDeactivateSim,
                                     new IGetDownloadableSubscriptionMetadataCallback.Stub() {
                                         @Override
@@ -1057,9 +1073,8 @@
         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.");
+                Log.i(TAG, "No UiccSlotInfo found for slotIndex: " + slotIndex);
+                return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
             }
             String retrievedCardId = slotInfos[slotIndex] != null
                     ? slotInfos[slotIndex].getCardId() : null;
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index 294299a..a5b95c3 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -59,7 +59,6 @@
 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.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.IccUtils;
@@ -386,6 +385,7 @@
 
     void getDownloadableSubscriptionMetadata(int cardId, DownloadableSubscription subscription,
             boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) {
+        Log.d(TAG, " getDownloadableSubscriptionMetadata callingPackage: " + callingPackage);
         if (!callerCanWriteEmbeddedSubscriptions()) {
             throw new SecurityException("Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get metadata");
         }
@@ -393,7 +393,8 @@
         long token = Binder.clearCallingIdentity();
         try {
             mConnector.getDownloadableSubscriptionMetadata(cardId,
-                    subscription, forceDeactivateSim,
+                    TelephonyManager.DEFAULT_PORT_INDEX, subscription,
+                    false /* switchAfterDownload */, forceDeactivateSim,
                     new GetMetadataCommandCallback(
                             token, subscription, callingPackage, callbackIntent));
         } finally {
@@ -602,8 +603,8 @@
             if (!isConsentNeededToResolvePortIndex
                     && canManageSubscriptionOnTargetSim(cardId, callingPackage, true,
                     portIndex)) {
-                mConnector.getDownloadableSubscriptionMetadata(cardId, subscription,
-                    forceDeactivateSim,
+                mConnector.getDownloadableSubscriptionMetadata(cardId, portIndex,
+                        subscription, switchAfterDownload, forceDeactivateSim,
                     new DownloadSubscriptionGetMetadataCommandCallback(token, subscription,
                         switchAfterDownload, callingPackage, forceDeactivateSim,
                         callbackIntent, false /* withUserConsent */, portIndex));
@@ -714,7 +715,8 @@
         Log.d(TAG, " downloadSubscriptionPrivilegedCheckMetadata cardId: " + cardId
                 + " switchAfterDownload: " + switchAfterDownload + " portIndex: " + portIndex
                 + " forceDeactivateSim: " + forceDeactivateSim);
-        mConnector.getDownloadableSubscriptionMetadata(cardId, subscription, forceDeactivateSim,
+        mConnector.getDownloadableSubscriptionMetadata(cardId, portIndex,
+                subscription, switchAfterDownload, forceDeactivateSim,
                 new DownloadSubscriptionGetMetadataCommandCallback(callingToken, subscription,
                         switchAfterDownload, callingPackage, forceDeactivateSim, callbackIntent,
                         true /* withUserConsent */, portIndex));
@@ -863,6 +865,7 @@
 
     void getDefaultDownloadableSubscriptionList(int cardId,
             boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent) {
+        Log.d(TAG, " getDefaultDownloadableSubscriptionList callingPackage: " + callingPackage);
         if (!callerCanWriteEmbeddedSubscriptions()) {
             throw new SecurityException(
                     "Must have WRITE_EMBEDDED_SUBSCRIPTIONS to get default list");
@@ -1148,7 +1151,8 @@
      * Returns the resolved portIndex or {@link TelephonyManager#INVALID_PORT_INDEX} if calling
      * cannot manage any active subscription.
      */
-    private int getResolvedPortIndexForDisableSubscription(int cardId, String callingPackage,
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public int getResolvedPortIndexForDisableSubscription(int cardId, String callingPackage,
             boolean callerCanWriteEmbeddedSubscriptions) {
         List<SubscriptionInfo> subInfoList = mSubscriptionManager
                 .getActiveSubscriptionInfoList(/* userVisibleOnly */false);
@@ -1176,7 +1180,8 @@
      * Returns the resolved portIndex or {@link TelephonyManager#INVALID_PORT_INDEX} if no port
      * is available without user consent.
      */
-    private int getResolvedPortIndexForSubscriptionSwitch(int cardId) {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public int getResolvedPortIndexForSubscriptionSwitch(int cardId) {
         int slotIndex = getSlotIndexFromCardId(cardId);
         // Euicc Slot
         UiccSlot slot = UiccController.getInstance().getUiccSlot(slotIndex);
@@ -1586,15 +1591,9 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void refreshSubscriptionsAndSendResult(
             PendingIntent callbackIntent, int resultCode, Intent extrasIntent) {
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
-                    List.of(mTelephonyManager.getCardIdForDefaultEuicc()),
-                    () -> sendResult(callbackIntent, resultCode, extrasIntent));
-        } else {
-            SubscriptionController.getInstance()
-                    .requestEmbeddedSubscriptionInfoListRefresh(
-                            () -> sendResult(callbackIntent, resultCode, extrasIntent));
-        }
+        SubscriptionManagerService.getInstance().updateEmbeddedSubscriptions(
+                List.of(mTelephonyManager.getCardIdForDefaultEuicc()),
+                () -> sendResult(callbackIntent, resultCode, extrasIntent));
     }
 
     /** Dispatch the given callback intent with the given result code and data. */
@@ -1888,8 +1887,6 @@
             boolean hasActiveEmbeddedSubscription = subInfoList.stream().anyMatch(
                     subInfo -> subInfo.isEmbedded() && subInfo.getCardId() == cardId
                             && (!usePortIndex || subInfo.getPortIndex() == targetPortIndex));
-            Log.d(TAG, "canManageSubscriptionOnTargetSim hasActiveEmbeddedSubscriptions: "
-                    + hasActiveEmbeddedSubscription);
             if (hasActiveEmbeddedSubscription) {
                 // hasActiveEmbeddedSubscription is true if there is an active embedded subscription
                 // on the target port(in case of usePortIndex is true) or if there is an active
@@ -1946,59 +1943,84 @@
 
     @Override
     public boolean isSimPortAvailable(int cardId, int portIndex, String callingPackage) {
-        List<UiccCardInfo> cardInfos;
+        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
+        // If calling app is targeted for Android U and beyond, check for other conditions
+        // to decide the port availability.
+        boolean shouldCheckConditionsForInactivePort = isCompatChangeEnabled(callingPackage,
+                EuiccManager.INACTIVE_PORT_AVAILABILITY_CHECK);
+        // In the event that this check is coming from ONS, WRITE_EMBEDDED_SUBSCRIPTIONS will be
+        // required for the case where a port is inactive but could trivially be enabled without
+        // requiring user consent.
+        boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions();
         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) {
+            List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
+            for (UiccCardInfo info : cardInfos) {
+                if (info == null || info.getCardId() != cardId) {
                     continue;
                 }
-                // Return false if port is not active.
-                if (!portInfo.isActive()) {
+                // 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;
                 }
-                // 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;
+                for (UiccPortInfo portInfo : info.getPorts()) {
+                    if (portInfo == null || portInfo.getPortIndex() != portIndex) {
+                        continue;
+                    }
+                    if (!portInfo.isActive()) {
+                        // port is inactive, check whether the caller can activate a new profile
+                        // seamlessly. This is possible in below condition:
+                        // 1. Device in DSDS Mode(P+E).
+                        // 2. pSIM slot is active but no active subscription.
+                        // 3. Caller has carrier privileges on any phone or has
+                        // WRITE_EMBEDDED_SUBSCRIPTIONS. The latter covers calls from ONS
+                        // which does not have carrier privileges.
+                        if (!shouldCheckConditionsForInactivePort) {
+                            return false;
+                        }
+                        boolean hasActiveRemovableNonEuiccSlot = getRemovableNonEuiccSlot() != null
+                                && getRemovableNonEuiccSlot().isActive();
+                        boolean hasCarrierPrivileges = mTelephonyManager
+                                .checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
+                                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+                        return mTelephonyManager.isMultiSimEnabled()
+                                && hasActiveRemovableNonEuiccSlot
+                                && !isRemovalNonEuiccSlotHasActiveSubscription()
+                                && (hasCarrierPrivileges || callerCanWriteEmbeddedSubscriptions);
+                    }
+                    // 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);
                 }
-                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);
             }
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
         return false;
     }
diff --git a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
index 0abd4ab..907f158 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
@@ -24,10 +24,12 @@
 import android.content.IntentFilter;
 import android.os.AsyncResult;
 import android.os.Build;
+import android.os.Looper;
 import android.os.Message;
 import android.os.SystemProperties;
 import android.provider.Telephony.Sms.Intents;
 
+import com.android.ims.ImsManager;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.Phone;
@@ -43,7 +45,7 @@
  */
 public class GsmInboundSmsHandler extends InboundSmsHandler {
 
-    private static BroadcastReceiver sTestBroadcastReceiver;
+    private BroadcastReceiver mTestBroadcastReceiver;
     /** Handler for SMS-PP data download messages to UICC. */
     private final UsimDataDownloadHandler mDataDownloadHandler;
 
@@ -56,18 +58,18 @@
      * Create a new GSM inbound SMS handler.
      */
     private GsmInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
-            Phone phone) {
-        super("GsmInboundSmsHandler", context, storageMonitor, phone);
+            Phone phone, Looper looper) {
+        super("GsmInboundSmsHandler", context, storageMonitor, phone, looper);
         phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null);
         mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi, phone.getPhoneId());
         mCellBroadcastServiceManager.enable();
 
         if (TEST_MODE) {
-            if (sTestBroadcastReceiver == null) {
-                sTestBroadcastReceiver = new GsmCbTestBroadcastReceiver();
+            if (mTestBroadcastReceiver == null) {
+                mTestBroadcastReceiver = new GsmCbTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(TEST_ACTION);
-                context.registerReceiver(sTestBroadcastReceiver, filter,
+                context.registerReceiver(mTestBroadcastReceiver, filter,
                         Context.RECEIVER_EXPORTED);
             }
         }
@@ -127,8 +129,9 @@
      * Wait for state machine to enter startup state. We can't send any messages until then.
      */
     public static GsmInboundSmsHandler makeInboundSmsHandler(Context context,
-            SmsStorageMonitor storageMonitor, Phone phone) {
-        GsmInboundSmsHandler handler = new GsmInboundSmsHandler(context, storageMonitor, phone);
+            SmsStorageMonitor storageMonitor, Phone phone, Looper looper) {
+        GsmInboundSmsHandler handler =
+                new GsmInboundSmsHandler(context, storageMonitor, phone, looper);
         handler.start();
         return handler;
     }
@@ -153,7 +156,8 @@
      * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC
      */
     @Override
-    protected int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource) {
+    protected int dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource,
+            int token) {
         SmsMessage sms = (SmsMessage) smsb;
 
         if (sms.isTypeZero()) {
@@ -177,7 +181,7 @@
         // Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section 7.1.1.
         if (sms.isUsimDataDownload()) {
             UsimServiceTable ust = mPhone.getUsimServiceTable();
-            return mDataDownloadHandler.handleUsimDataDownload(ust, sms, smsSource);
+            return mDataDownloadHandler.handleUsimDataDownload(ust, sms, smsSource, token);
         }
 
         boolean handled = false;
@@ -268,4 +272,15 @@
                 android.telephony.SmsMessage.FORMAT_3GPP);
         mPhone.getSmsStats().onIncomingSmsVoicemail(false /* is3gpp2 */, smsSource);
     }
+
+    /**
+     * sets ImsManager object.
+     */
+    public boolean setImsManager(ImsManager imsManager) {
+        if (mDataDownloadHandler != null) {
+            mDataDownloadHandler.setImsManager(imsManager);
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 7f5b607..9de3ee9 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -49,6 +49,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CallWaitingController;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.GsmCdmaPhone;
@@ -1168,11 +1169,25 @@
                 int serviceClass = siToServiceClass(mSia);
 
                 if (isActivate() || isDeactivate()) {
+                    if (serviceClass == SERVICE_CLASS_NONE
+                            || (serviceClass & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE) {
+                        if (mPhone.getTerminalBasedCallWaitingState(true)
+                                != CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED) {
+                            mPhone.setCallWaiting(isActivate(), serviceClass,
+                                    obtainMessage(EVENT_SET_COMPLETE, this));
+                            return;
+                        }
+                    }
                     mPhone.mCi.setCallWaiting(isActivate(), serviceClass,
                             obtainMessage(EVENT_SET_COMPLETE, this));
                 } else if (isInterrogate()) {
-                    mPhone.mCi.queryCallWaiting(serviceClass,
-                            obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    if (mPhone.getTerminalBasedCallWaitingState(true)
+                            != CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED) {
+                        mPhone.getCallWaiting(obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    } else {
+                        mPhone.mCi.queryCallWaiting(serviceClass,
+                                obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    }
                 } else {
                     throw new RuntimeException ("Invalid or Unsupported MMI Code");
                 }
diff --git a/src/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java b/src/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
index ed819c1..bae56d1 100644
--- a/src/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
@@ -17,13 +17,19 @@
 package com.android.internal.telephony.gsm;
 
 import android.app.Activity;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.SmsManager;
+import android.telephony.ims.stub.ImsSmsImplBase;
 
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.PhoneFactory;
@@ -61,10 +67,14 @@
 
     private final CommandsInterface mCi;
     private final int mPhoneId;
+    private ImsManager mImsManager;
+    Resources mResource;
 
     public UsimDataDownloadHandler(CommandsInterface commandsInterface, int phoneId) {
         mCi = commandsInterface;
         mPhoneId = phoneId;
+        mImsManager = null; // will get initialized when ImsManager connection is ready
+        mResource = Resources.getSystem();
     }
 
     /**
@@ -79,7 +89,7 @@
      * @return {@code Activity.RESULT_OK} on success; {@code RESULT_SMS_GENERIC_ERROR} on failure
      */
     int handleUsimDataDownload(UsimServiceTable ust, SmsMessage smsMessage,
-            @InboundSmsHandler.SmsSource int smsSource) {
+            @InboundSmsHandler.SmsSource int smsSource, int token) {
         // If we receive an SMS-PP message before the UsimServiceTable has been loaded,
         // assume that the data download service is not present. This is very unlikely to
         // happen because the IMS connection will not be established until after the ISIM
@@ -87,7 +97,7 @@
         if (ust != null && ust.isAvailable(
                 UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP)) {
             Rlog.d(TAG, "Received SMS-PP data download, sending to UICC.");
-            return startDataDownload(smsMessage, smsSource);
+            return startDataDownload(smsMessage, smsSource, token);
         } else {
             Rlog.d(TAG, "DATA_DL_VIA_SMS_PP service not available, storing message to UICC.");
             String smsc = IccUtils.bytesToHexString(
@@ -95,7 +105,8 @@
                             smsMessage.getServiceCenterAddress()));
             mCi.writeSmsToSim(SmsManager.STATUS_ON_ICC_UNREAD, smsc,
                     IccUtils.bytesToHexString(smsMessage.getPdu()),
-                    obtainMessage(EVENT_WRITE_SMS_COMPLETE));
+                    obtainMessage(EVENT_WRITE_SMS_COMPLETE,
+                            new int[]{ smsSource, smsMessage.mMessageRef, token }));
             addUsimDataDownloadToMetrics(false, smsSource);
             return Activity.RESULT_OK;  // acknowledge after response from write to USIM
         }
@@ -111,9 +122,9 @@
      * @return {@code Activity.RESULT_OK} on success; {@code RESULT_SMS_GENERIC_ERROR} on failure
      */
     public int startDataDownload(SmsMessage smsMessage,
-            @InboundSmsHandler.SmsSource int smsSource) {
+            @InboundSmsHandler.SmsSource int smsSource, int token) {
         if (sendMessage(obtainMessage(EVENT_START_DATA_DOWNLOAD,
-                smsSource, 0 /* unused */, smsMessage))) {
+                smsSource, token, smsMessage))) {
             return Activity.RESULT_OK;  // we will send SMS ACK/ERROR based on UICC response
         } else {
             Rlog.e(TAG, "startDataDownload failed to send message to start data download.");
@@ -122,7 +133,7 @@
     }
 
     private void handleDataDownload(SmsMessage smsMessage,
-            @InboundSmsHandler.SmsSource int smsSource) {
+            @InboundSmsHandler.SmsSource int smsSource, int token) {
         int dcs = smsMessage.getDataCodingScheme();
         int pid = smsMessage.getProtocolIdentifier();
         byte[] pdu = smsMessage.getPdu();           // includes SC address
@@ -139,6 +150,7 @@
 
         byte[] envelope = new byte[totalLength];
         int index = 0;
+        Rlog.d(TAG, "smsSource: " + smsSource + "Token: " + token);
 
         // SMS-PP download tag and length (assumed to be < 256 bytes).
         envelope[index++] = (byte) BER_SMS_PP_DOWNLOAD_TAG;
@@ -173,14 +185,16 @@
         // Verify that we calculated the payload size correctly.
         if (index != envelope.length) {
             Rlog.e(TAG, "startDataDownload() calculated incorrect envelope length, aborting.");
-            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR);
+            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR,
+                    smsSource, token, smsMessage.mMessageRef);
             addUsimDataDownloadToMetrics(false, smsSource);
             return;
         }
 
         String encodedEnvelope = IccUtils.bytesToHexString(envelope);
         mCi.sendEnvelopeWithStatus(encodedEnvelope, obtainMessage(
-                EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid }));
+                EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid, smsSource,
+                    smsMessage.mMessageRef, token }));
 
         addUsimDataDownloadToMetrics(true, smsSource);
     }
@@ -211,7 +225,8 @@
      * @param response UICC response encoded as hexadecimal digits. First two bytes are the
      *  UICC SW1 and SW2 status bytes.
      */
-    private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid) {
+    private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid,
+            int smsSource, int token, int messageRef) {
         int sw1 = response.sw1;
         int sw2 = response.sw2;
 
@@ -221,7 +236,8 @@
             success = true;
         } else if (sw1 == 0x93 && sw2 == 0x00) {
             Rlog.e(TAG, "USIM data download failed: Toolkit busy");
-            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY);
+            acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY,
+                    smsSource, token, messageRef);
             return;
         } else if (sw1 == 0x62 || sw1 == 0x63) {
             Rlog.e(TAG, "USIM data download failed: " + response.toString());
@@ -234,10 +250,11 @@
         byte[] responseBytes = response.payload;
         if (responseBytes == null || responseBytes.length == 0) {
             if (success) {
-                mCi.acknowledgeLastIncomingGsmSms(true, 0, null);
+                acknowledgeSmsWithSuccess(0, smsSource, token, messageRef);
             } else {
                 acknowledgeSmsWithError(
-                        CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
+                        CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR, smsSource,
+                        token, messageRef);
             }
             return;
         }
@@ -268,12 +285,32 @@
 
         System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length);
 
-        mCi.acknowledgeIncomingGsmSmsWithPdu(success,
-                IccUtils.bytesToHexString(smsAckPdu), null);
+        if (smsSource == InboundSmsHandler.SOURCE_INJECTED_FROM_IMS && ackViaIms()) {
+            acknowledgeImsSms(token, messageRef, true, smsAckPdu);
+        } else {
+            mCi.acknowledgeIncomingGsmSmsWithPdu(success,
+                    IccUtils.bytesToHexString(smsAckPdu), null);
+        }
     }
 
-    private void acknowledgeSmsWithError(int cause) {
-        mCi.acknowledgeLastIncomingGsmSms(false, cause, null);
+    private void acknowledgeSmsWithSuccess(int cause, int smsSource, int token, int messageRef) {
+        Rlog.d(TAG, "acknowledgeSmsWithSuccess- cause: " + cause + " smsSource: " + smsSource
+                + " token: " + token + " messageRef: " + messageRef);
+        if (smsSource == InboundSmsHandler.SOURCE_INJECTED_FROM_IMS && ackViaIms()) {
+            acknowledgeImsSms(token, messageRef, true, null);
+        } else {
+            mCi.acknowledgeLastIncomingGsmSms(true, cause, null);
+        }
+    }
+
+    private void acknowledgeSmsWithError(int cause, int smsSource, int token, int messageRef) {
+        Rlog.d(TAG, "acknowledgeSmsWithError- cause: " + cause + " smsSource: " + smsSource
+                + " token: " + token + " messageRef: " + messageRef);
+        if (smsSource == InboundSmsHandler.SOURCE_INJECTED_FROM_IMS && ackViaIms()) {
+            acknowledgeImsSms(token, messageRef, false, null);
+        } else {
+            mCi.acknowledgeLastIncomingGsmSms(false, cause, null);
+        }
     }
 
     /**
@@ -300,6 +337,45 @@
     }
 
     /**
+     * Route resposes via ImsManager based on config
+     */
+    private boolean ackViaIms() {
+        boolean isViaIms;
+
+        try {
+            isViaIms = mResource.getBoolean(
+                    com.android.internal.R.bool.config_smppsim_response_via_ims);
+        } catch (NotFoundException e) {
+            isViaIms = false;
+        }
+
+        Rlog.d(TAG, "ackViaIms : " + isViaIms);
+        return isViaIms;
+    }
+
+    /**
+     * Acknowledges IMS SMS and delivers the result based on the envelope or SIM saving respose
+     * received from SIM for SMS-PP Data.
+     */
+    private void acknowledgeImsSms(int token, int messageRef, boolean success, byte[] pdu) {
+        int result = success ? ImsSmsImplBase.DELIVER_STATUS_OK :
+                    ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC;
+        Rlog.d(TAG, "sending result via acknowledgeImsSms: " + result + " token: " + token);
+
+        try {
+            if (mImsManager != null) {
+                if (pdu != null && pdu.length > 0) {
+                    mImsManager.acknowledgeSms(token, messageRef, result, pdu);
+                } else {
+                    mImsManager.acknowledgeSms(token, messageRef, result);
+                }
+            }
+        } catch (ImsException e) {
+            Rlog.e(TAG, "Failed to acknowledgeSms(). Error: " + e.getMessage());
+        }
+    }
+
+    /**
      * Handle UICC envelope response and send SMS acknowledgement.
      *
      * @param msg the message to handle
@@ -307,35 +383,60 @@
     @Override
     public void handleMessage(Message msg) {
         AsyncResult ar;
+        int smsSource = InboundSmsHandler.SOURCE_INJECTED_FROM_UNKNOWN;
+        int token = 0;
+        int messageRef = 0;
+        int[] responseInfo;
 
         switch (msg.what) {
             case EVENT_START_DATA_DOWNLOAD:
-                handleDataDownload((SmsMessage) msg.obj, msg.arg1 /* smsSource */);
+                Rlog.d(TAG, "EVENT_START_DATA_DOWNLOAD");
+                handleDataDownload((SmsMessage) msg.obj, msg.arg1 /* smsSource */,
+                        msg.arg2 /* token */);
                 break;
 
             case EVENT_SEND_ENVELOPE_RESPONSE:
                 ar = (AsyncResult) msg.obj;
 
+                responseInfo = (int[]) ar.userObj;
+                smsSource = responseInfo[2];
+                messageRef = responseInfo[3];
+                token = responseInfo[4];
+
+                Rlog.d(TAG, "Received EVENT_SEND_ENVELOPE_RESPONSE from source : " + smsSource);
+
                 if (ar.exception != null) {
                     Rlog.e(TAG, "UICC Send Envelope failure, exception: " + ar.exception);
+
                     acknowledgeSmsWithError(
-                            CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
+                            CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR,
+                            smsSource, token, messageRef);
                     return;
                 }
 
-                int[] dcsPid = (int[]) ar.userObj;
-                sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, dcsPid[0], dcsPid[1]);
+                Rlog.d(TAG, "Successful in sending envelope response");
+                sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, responseInfo[0],
+                            responseInfo[1], smsSource, token, messageRef);
                 break;
 
             case EVENT_WRITE_SMS_COMPLETE:
                 ar = (AsyncResult) msg.obj;
+
+                responseInfo = (int[]) ar.userObj;
+                smsSource = responseInfo[0];
+                messageRef = responseInfo[1];
+                token = responseInfo[2];
+
+                Rlog.d(TAG, "Received EVENT_WRITE_SMS_COMPLETE from source : " + smsSource);
+
                 if (ar.exception == null) {
                     Rlog.d(TAG, "Successfully wrote SMS-PP message to UICC");
-                    mCi.acknowledgeLastIncomingGsmSms(true, 0, null);
+                    acknowledgeSmsWithSuccess(0, smsSource, token, messageRef);
                 } else {
                     Rlog.d(TAG, "Failed to write SMS-PP message to UICC", ar.exception);
-                    mCi.acknowledgeLastIncomingGsmSms(false,
-                            CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR, null);
+                    acknowledgeSmsWithError(
+                            CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR,
+                            smsSource, token, messageRef);
                 }
                 break;
 
@@ -343,4 +444,23 @@
                 Rlog.e(TAG, "Ignoring unexpected message, what=" + msg.what);
         }
     }
+
+    /**
+     * Called when ImsManager connection is ready. ImsManager object will be used to send ACK to IMS
+     * which doesn't use RIL interface.
+     * @param imsManager object
+     */
+    public void setImsManager(ImsManager imsManager) {
+        mImsManager = imsManager;
+    }
+
+    /**
+     * Called to set mocked object of type Resources during unit testing of this file.
+     * @param resource object
+     */
+    @VisibleForTesting
+    public void setResourcesForTest(Resources resource) {
+        mResource = resource;
+        Rlog.d(TAG, "setResourcesForTest");
+    }
 }
diff --git a/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
old mode 100755
new mode 100644
index e594ab6..48be16c
--- a/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -32,6 +32,7 @@
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 /**
  * This class implements reading and parsing USIM records.
@@ -233,7 +234,7 @@
 
             int emailEfid = email.getEfid();
             log("EF_EMAIL exists in PBR. efid = 0x" +
-                    Integer.toHexString(emailEfid).toUpperCase());
+                    Integer.toHexString(emailEfid).toUpperCase(Locale.ROOT));
 
             /**
              * Make sure this EF_EMAIL was never read earlier. Sometimes two PBR record points
@@ -348,7 +349,7 @@
                 emailList = new ArrayList<String>();
             }
             log("Adding email #" + i + " list to index 0x" +
-                    Integer.toHexString(index).toUpperCase());
+                    Integer.toHexString(index).toUpperCase(Locale.ROOT));
             emailList.add(email);
             mEmailsForAdnRec.put(index, emailList);
         }
@@ -402,7 +403,7 @@
                 }
                 emailList.add(email);
                 log("Adding email list to index 0x" +
-                        Integer.toHexString(index).toUpperCase());
+                        Integer.toHexString(index).toUpperCase(Locale.ROOT));
                 mEmailsForAdnRec.put(index, emailList);
             }
         }
@@ -446,8 +447,9 @@
             System.arraycopy(emailList.toArray(), 0, emails, 0, emailList.size());
             rec.setEmails(emails);
             log("Adding email list to ADN (0x" +
-                    Integer.toHexString(mPhoneBookRecords.get(i).getEfid()).toUpperCase() +
-                    ") record #" + mPhoneBookRecords.get(i).getRecId());
+                    Integer.toHexString(mPhoneBookRecords.get(i).getEfid())
+                            .toUpperCase(Locale.ROOT) + ") record #"
+                    + mPhoneBookRecords.get(i).getRecId());
             mPhoneBookRecords.set(i, rec);
         }
     }
diff --git a/src/java/com/android/internal/telephony/ims/ImsEnablementTracker.java b/src/java/com/android/internal/telephony/ims/ImsEnablementTracker.java
new file mode 100644
index 0000000..e54561f
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsEnablementTracker.java
@@ -0,0 +1,939 @@
+/*
+ * 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 android.content.ComponentName;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.aidl.IImsServiceController;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IState;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class will abstract away all the new enablement logic and take the reset/enable/disable
+ * IMS commands as inputs.
+ * The IMS commands will call enableIms, disableIms or resetIms to match the enablement state only
+ * when it changes.
+ */
+public class ImsEnablementTracker {
+    private static final String LOG_TAG = "ImsEnablementTracker";
+    private static final long REQUEST_THROTTLE_TIME_MS = 3 * 1000L; // 3 seconds
+
+    private static final int COMMAND_NONE_MSG = 0;
+    // Indicate that the enableIms command has been received.
+    @VisibleForTesting
+    public static final int COMMAND_ENABLE_MSG = 1;
+    // Indicate that the disableIms command has been received.
+    @VisibleForTesting
+    public static final int COMMAND_DISABLE_MSG = 2;
+    // Indicate that the resetIms command has been received.
+    private static final int COMMAND_RESET_MSG = 3;
+    // Indicate that the internal enable message with delay has been received.
+    private static final int COMMAND_ENABLING_DONE = 4;
+    // Indicate that the internal disable message with delay has been received.
+    private static final int COMMAND_DISABLING_DONE = 5;
+    // Indicate that the internal reset message with delay has been received.
+    @VisibleForTesting
+    public static final int COMMAND_RESETTING_DONE = 6;
+    // The ImsServiceController binder is connected.
+    private static final int COMMAND_CONNECTED_MSG = 7;
+    // The ImsServiceController binder is disconnected.
+    private static final int COMMAND_DISCONNECTED_MSG = 8;
+    // The subId is changed to INVALID_SUBSCRIPTION_ID.
+    private static final int COMMAND_INVALID_SUBID_MSG = 9;
+    // Indicate that the internal post reset message with delay has been received.
+    @VisibleForTesting
+    public static final int COMMAND_POST_RESETTING_DONE = 10;
+
+    private static final Map<Integer, String> EVENT_DESCRIPTION = new HashMap<>();
+    static {
+        EVENT_DESCRIPTION.put(COMMAND_NONE_MSG, "COMMAND_NONE_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_ENABLE_MSG, "COMMAND_ENABLE_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_DISABLE_MSG, "COMMAND_DISABLE_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_RESET_MSG, "COMMAND_RESET_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_ENABLING_DONE, "COMMAND_ENABLING_DONE");
+        EVENT_DESCRIPTION.put(COMMAND_DISABLING_DONE, "COMMAND_DISABLING_DONE");
+        EVENT_DESCRIPTION.put(COMMAND_RESETTING_DONE, "COMMAND_RESETTING_DONE");
+        EVENT_DESCRIPTION.put(COMMAND_CONNECTED_MSG, "COMMAND_CONNECTED_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_DISCONNECTED_MSG, "COMMAND_DISCONNECTED_MSG");
+        EVENT_DESCRIPTION.put(COMMAND_INVALID_SUBID_MSG, "COMMAND_INVALID_SUBID_MSG");
+    }
+
+    @VisibleForTesting
+    protected static final int STATE_IMS_DISCONNECTED = 0;
+    @VisibleForTesting
+    protected static final int STATE_IMS_DEFAULT = 1;
+    @VisibleForTesting
+    protected static final int STATE_IMS_ENABLED = 2;
+    @VisibleForTesting
+    protected static final int STATE_IMS_DISABLING = 3;
+    @VisibleForTesting
+    protected static final int STATE_IMS_DISABLED = 4;
+    @VisibleForTesting
+    protected static final int STATE_IMS_ENABLING = 5;
+    @VisibleForTesting
+    protected static final int STATE_IMS_RESETTING = 6;
+
+    @VisibleForTesting
+    protected static final int STATE_IMS_POSTRESETTING = 7;
+
+    protected final Object mLock = new Object();
+    private IImsServiceController mIImsServiceController;
+    private long mLastImsOperationTimeMs = 0L;
+    private final ComponentName mComponentName;
+    private final SparseArray<ImsEnablementTrackerStateMachine> mStateMachines;
+
+    private final Looper mLooper;
+    private final int mState;
+
+    /**
+     * Provides Ims Enablement Tracker State Machine responsible for ims enable/disable/reset
+     * command interactions with Ims service controller binder.
+     * The enable/disable/reset ims commands have a time interval of at least
+     * {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second between
+     * processing each command.
+     * For example, the enableIms command is received and the binder's enableIms is called.
+     * After that, if the disableIms command is received, the binder's disableIms will be
+     * called after {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second.
+     * A time of {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} will be used
+     * {@link Handler#sendMessageDelayed(Message, long)},
+     * and the enabled, disabled and reset states are responsible for waiting for
+     * that delay message.
+     */
+    class ImsEnablementTrackerStateMachine extends StateMachine {
+        /**
+         * The initial state of this class and waiting for an ims commands.
+         */
+        @VisibleForTesting
+        public final Default mDefault;
+
+        /**
+         * Indicates that {@link IImsServiceController#enableIms(int, int)} has been called and
+         * waiting for an ims commands.
+         * Common transitions are to
+         * {@link #mDisabling} state when the disable command is received
+         * or {@link #mResetting} state when the reset command is received
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        @VisibleForTesting
+        public final Enabled mEnabled;
+
+        /**
+         * Indicates that the state waiting for the throttle time to elapse before calling
+         * {@link IImsServiceController#disableIms(int, int)}.
+         * Common transitions are to
+         * {@link #mEnabled} when the enable command is received.
+         * or {@link #mResetting} when the reset command is received.
+         * or {@link #mDisabled} the previous binder API call has passed
+         * {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second, and if
+         * {@link IImsServiceController#disableIms(int, int)} called.
+         * or {@link #mDisabling} received a disableIms message and the previous binder API call
+         * has not passed {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second.
+         * Then send a disableIms message with delay.
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        @VisibleForTesting
+        public final Disabling mDisabling;
+
+        /**
+         * Indicates that {@link IImsServiceController#disableIms(int, int)} has been called and
+         * waiting for an ims commands.
+         * Common transitions are to
+         * {@link #mEnabling} state when the enable command is received.
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        @VisibleForTesting
+        public final Disabled mDisabled;
+
+        /**
+         * Indicates that the state waiting for the throttle time to elapse before calling
+         * {@link IImsServiceController#enableIms(int, int)}.
+         * Common transitions are to
+         * {@link #mEnabled} the previous binder API call has passed
+         * {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second, and
+         * {@link IImsServiceController#enableIms(int, int)} called.
+         * or {@link #mDisabled} when the disable command is received.
+         * or {@link #mEnabling} received an enableIms message and the previous binder API call
+         * has not passed {@link ImsEnablementTracker#REQUEST_THROTTLE_TIME_MS} second.
+         * Then send an enableIms message with delay.
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        @VisibleForTesting
+        public final Enabling mEnabling;
+
+        /**
+         * Indicates that the state waiting for the throttle time to elapse before calling
+         * {@link IImsServiceController#resetIms(int, int)}.
+         * Common transitions are to
+         * {@link #mPostResetting} state to call either enableIms or disableIms after calling
+         * {@link IImsServiceController#resetIms(int, int)}
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        @VisibleForTesting
+        public final Resetting mResetting;
+
+        /**
+         * Indicates that the state waiting after resetIms for the throttle time to elapse before
+         * calling {@link IImsServiceController#enableIms(int, int)} or
+         * {@link IImsServiceController#disableIms(int, int)}.
+         * Common transitions are to
+         * {@link #mEnabled} state when the disable command is received,
+         * {@link #mDisabled} state when the enable command is received after calling
+         * {@link IImsServiceController#enableIms(int, int)},
+         * {@link IImsServiceController#disableIms(int, int)}
+         * or {@link #mDisconnected} if the binder is disconnected.
+         */
+        public final PostResetting mPostResetting;
+
+        /**
+         * Indicates that {@link IImsServiceController} has not been set.
+         * Common transition is to
+         * {@link #mDefault} state when the binder is set.
+         * or {@link #mDisabling} If the disable command is received while the binder is
+         * disconnected
+         * or {@link #mEnabling} If the enable command is received while the binder is
+         * disconnected
+         */
+
+        private final Disconnected mDisconnected;
+        private int mSlotId;
+        private int mSubId;
+
+        private final int mPhoneId;
+
+        private IState mPreviousState;
+
+        private int mLastMsg = COMMAND_NONE_MSG;
+
+        ImsEnablementTrackerStateMachine(String name, Looper looper, int state, int slotId) {
+            super(name, looper);
+            mPhoneId = slotId;
+            mDefault = new Default();
+            mEnabled = new Enabled();
+            mDisabling = new Disabling();
+            mDisabled = new Disabled();
+            mEnabling = new Enabling();
+            mResetting = new Resetting();
+            mDisconnected = new Disconnected();
+            mPostResetting = new PostResetting();
+
+            addState(mDefault);
+            addState(mEnabled);
+            addState(mDisabling);
+            addState(mDisabled);
+            addState(mEnabling);
+            addState(mResetting);
+            addState(mDisconnected);
+            addState(mPostResetting);
+
+            setInitialState(getState(state));
+            mPreviousState = getState(state);
+        }
+
+        public void clearAllMessage() {
+            Log.d(LOG_TAG, "clearAllMessage");
+            removeMessages(COMMAND_ENABLE_MSG);
+            removeMessages(COMMAND_DISABLE_MSG);
+            removeMessages(COMMAND_RESET_MSG);
+            removeMessages(COMMAND_ENABLING_DONE);
+            removeMessages(COMMAND_DISABLING_DONE);
+            removeMessages(COMMAND_RESETTING_DONE);
+            removeMessages(COMMAND_POST_RESETTING_DONE);
+        }
+
+        public void serviceBinderConnected() {
+            clearAllMessage();
+            sendMessage(COMMAND_CONNECTED_MSG);
+        }
+
+        public void serviceBinderDisconnected() {
+            clearAllMessage();
+            sendMessage(COMMAND_DISCONNECTED_MSG);
+        }
+
+        @VisibleForTesting
+        public boolean isState(int state) {
+            State expect = null;
+            switch (state) {
+                case Default.STATE_NO:
+                    expect = mDefault;
+                    break;
+                case Enabled.STATE_NO:
+                    expect = mEnabled;
+                    break;
+                case Disabling.STATE_NO:
+                    expect = mDisabling;
+                    break;
+                case Disabled.STATE_NO:
+                    expect = mDisabled;
+                    break;
+                case Enabling.STATE_NO:
+                    expect = mEnabling;
+                    break;
+                case Resetting.STATE_NO:
+                    expect = mResetting;
+                    break;
+                case Disconnected.STATE_NO:
+                    expect = mDisconnected;
+                    break;
+                case PostResetting.STATE_NO:
+                    expect = mPostResetting;
+                    break;
+                default:
+                    break;
+            }
+            return (getCurrentState() == expect) ? true : false;
+        }
+
+        private State getState(int state) {
+            switch (state) {
+                case ImsEnablementTracker.STATE_IMS_ENABLED:
+                    return mEnabled;
+                case ImsEnablementTracker.STATE_IMS_DISABLING:
+                    return mDisabling;
+                case ImsEnablementTracker.STATE_IMS_DISABLED:
+                    return mDisabled;
+                case ImsEnablementTracker.STATE_IMS_ENABLING:
+                    return mEnabling;
+                case ImsEnablementTracker.STATE_IMS_RESETTING:
+                    return mResetting;
+                case ImsEnablementTracker.STATE_IMS_DISCONNECTED:
+                    return mDisconnected;
+                case ImsEnablementTracker.STATE_IMS_POSTRESETTING:
+                    return mPostResetting;
+                default:
+                    return mDefault;
+            }
+        }
+
+        private void handleInvalidSubIdMessage() {
+            clearAllMessage();
+            transitionState(mDefault);
+        }
+
+        private void transitionState(State state) {
+            mPreviousState = getCurrentState();
+            transitionTo(state);
+        }
+
+        class Default extends State {
+            private static final int STATE_NO = STATE_IMS_DEFAULT;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Default state:enter");
+                mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Default state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    // When enableIms() is called, enableIms of binder is call and the state
+                    // change to the enabled state.
+                    case COMMAND_ENABLE_MSG:
+                        sendEnableIms(message.arg1, message.arg2);
+                        transitionState(mEnabled);
+                        return HANDLED;
+                    // When disableIms() is called, disableIms of binder is call and the state
+                    // change to the disabled state.
+                    case COMMAND_DISABLE_MSG:
+                        sendDisableIms(message.arg1, message.arg2);
+                        transitionState(mDisabled);
+                        return HANDLED;
+                    // When resetIms() is called, change to the resetting state to call enableIms
+                    // after calling resetIms of binder.
+                    case COMMAND_RESET_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mResetting);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Enabled extends State {
+            private static final int STATE_NO = STATE_IMS_ENABLED;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Enabled state:enter");
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Enabled state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    // the disableIms() is called.
+                    case COMMAND_DISABLE_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mDisabling);
+                        return HANDLED;
+                    // the resetIms() is called.
+                    case COMMAND_RESET_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mResetting);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Disabling extends State {
+            private static final int STATE_NO = STATE_IMS_DISABLING;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disabling state:enter");
+                sendMessageDelayed(COMMAND_DISABLING_DONE, mSlotId, mSubId,
+                        getRemainThrottleTime());
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disabling state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    case COMMAND_ENABLE_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        clearAllMessage();
+                        if (mPreviousState == mResetting) {
+                            // if we are moving from Resetting -> Disabling and receive
+                            // the COMMAND_ENABLE_MSG, we need to send the enableIms command,
+                            // so move to Enabling state.
+                            transitionState(mEnabling);
+                        } else {
+                            // When moving from Enabled -> Disabling and we receive an ENABLE_MSG,
+                            // we can move straight back to Enabled state because we have not sent
+                            // the disableIms command to IMS yet.
+                            transitionState(mEnabled);
+                        }
+                        return HANDLED;
+                    case COMMAND_DISABLING_DONE:
+                        // If the disable command is received before disableIms is processed,
+                        // it will be ignored because the disable command processing is in progress.
+                        removeMessages(COMMAND_DISABLE_MSG);
+                        sendDisableIms(message.arg1, message.arg2);
+                        transitionState(mDisabled);
+                        return HANDLED;
+                    case COMMAND_RESET_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        clearAllMessage();
+                        transitionState(mResetting);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Disabled extends State {
+            private static final int STATE_NO = STATE_IMS_DISABLED;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disabled state:enter");
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disabled state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    case COMMAND_ENABLE_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mEnabling);
+                        return HANDLED;
+                    case COMMAND_RESET_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mResetting);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Enabling extends State {
+            private static final int STATE_NO = STATE_IMS_ENABLING;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Enabling state:enter");
+                sendMessageDelayed(COMMAND_ENABLING_DONE, mSlotId, mSubId, getRemainThrottleTime());
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Enabling state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    // Enabling state comes from Resetting and disableIms() is called.
+                    // In this case disableIms() of binder should be called.
+                    // When enabling state comes from disabled, just change state to the disabled.
+                    case COMMAND_DISABLE_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        clearAllMessage();
+                        if (mPreviousState == mResetting) {
+                            transitionState(mDisabling);
+                        } else {
+                            transitionState(mDisabled);
+                        }
+                        return HANDLED;
+                    case COMMAND_RESET_MSG:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        transitionState(mResetting);
+                        return HANDLED;
+                    case COMMAND_ENABLING_DONE:
+                        // If the enable command is received before enableIms is processed,
+                        // it will be ignored because the enable command processing is in progress.
+                        removeMessages(COMMAND_ENABLE_MSG);
+                        sendEnableIms(message.arg1, message.arg2);
+                        transitionState(mEnabled);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Resetting extends State {
+            private static final int STATE_NO = STATE_IMS_RESETTING;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Resetting state:enter");
+                sendMessageDelayed(COMMAND_RESETTING_DONE, mSlotId, mSubId,
+                        getRemainThrottleTime());
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Resetting state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    case COMMAND_DISABLE_MSG:
+                        mLastMsg = COMMAND_DISABLE_MSG;
+                        return HANDLED;
+                    case COMMAND_ENABLE_MSG:
+                        mLastMsg = COMMAND_ENABLE_MSG;
+                        return HANDLED;
+                    case COMMAND_RESETTING_DONE:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        // If the reset command is received before disableIms is processed,
+                        // it will be ignored because the reset command processing is in progress.
+                        removeMessages(COMMAND_RESET_MSG);
+                        sendResetIms(mSlotId, mSubId);
+                        transitionState(mPostResetting);
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class Disconnected extends State {
+            private static final int STATE_NO = STATE_IMS_DISCONNECTED;
+
+            private int mLastMsg = COMMAND_NONE_MSG;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disconnected state:enter");
+                clearAllMessage();
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]Disconnected state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    case COMMAND_CONNECTED_MSG:
+                        clearAllMessage();
+                        transitionState(mDefault);
+                        if (mLastMsg != COMMAND_NONE_MSG) {
+                            sendMessageDelayed(mLastMsg, mSlotId, mSubId, 0);
+                            mLastMsg = COMMAND_NONE_MSG;
+                        }
+                        return HANDLED;
+                    case COMMAND_ENABLE_MSG:
+                    case COMMAND_DISABLE_MSG:
+                    case COMMAND_RESET_MSG:
+                        mLastMsg = message.what;
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+
+        class PostResetting extends State {
+            private static final int STATE_NO = STATE_IMS_POSTRESETTING;
+
+            @Override
+            public void enter() {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]PostResetting state:enter");
+                sendMessageDelayed(COMMAND_POST_RESETTING_DONE, mSlotId, mSubId,
+                        getRemainThrottleTime());
+            }
+
+            @Override
+            public void exit() {
+                mLastMsg = COMMAND_NONE_MSG;
+            }
+
+            @Override
+            public boolean processMessage(Message message) {
+                Log.d(LOG_TAG, "[" + mPhoneId + "]PostResetting state:processMessage. msg.what="
+                        + EVENT_DESCRIPTION.get(message.what) + ",component:" + mComponentName);
+
+                switch (message.what) {
+                    case COMMAND_POST_RESETTING_DONE:
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        if (mLastMsg == COMMAND_DISABLE_MSG) {
+                            sendDisableIms(mSlotId, mSubId);
+                            transitionState(mDisabled);
+                        } else {
+                            // if mLastMsg is COMMAND_NONE_MSG or COMMAND_ENABLE_MSG
+                            sendEnableIms(mSlotId, mSubId);
+                            transitionState(mEnabled);
+                        }
+                        return HANDLED;
+                    case COMMAND_ENABLE_MSG:
+                    case COMMAND_DISABLE_MSG:
+                        mLastMsg = message.what;
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        return HANDLED;
+                    case COMMAND_RESET_MSG:
+                        // when resetIms() called again, skip to call
+                        // IImsServiceController.resetIms(slotId, subId), but after throttle time
+                        // IImsServiceController.enableIms(slotId, subId) should be called.
+                        mLastMsg = COMMAND_ENABLE_MSG;
+                        mSlotId = message.arg1;
+                        mSubId = message.arg2;
+                        return HANDLED;
+                    case COMMAND_DISCONNECTED_MSG:
+                        transitionState(mDisconnected);
+                        return HANDLED;
+                    case COMMAND_INVALID_SUBID_MSG:
+                        handleInvalidSubIdMessage();
+                        return HANDLED;
+                    default:
+                        return NOT_HANDLED;
+                }
+            }
+        }
+    }
+
+    public ImsEnablementTracker(Looper looper, ComponentName componentName) {
+        mIImsServiceController = null;
+        mStateMachines = new SparseArray<>();
+        mLooper = looper;
+        mState = ImsEnablementTracker.STATE_IMS_DISCONNECTED;
+        mComponentName = componentName;
+    }
+
+    @VisibleForTesting
+    public ImsEnablementTracker(Looper looper, IImsServiceController controller, int state,
+            int numSlots) {
+        mIImsServiceController = controller;
+        mStateMachines = new SparseArray<>();
+        mLooper = looper;
+        mState = state;
+        mComponentName = null;
+
+        setNumOfSlots(numSlots);
+    }
+
+    /**
+     * Set the number of SIM slots.
+     * @param numOfSlots the number of SIM slots.
+     */
+    public void setNumOfSlots(int numOfSlots) {
+        int oldNumSlots = mStateMachines.size();
+        Log.d(LOG_TAG, "set the slots: old[" + oldNumSlots + "], new[" + numOfSlots + "],"
+                + "component:" + mComponentName);
+        if (numOfSlots == oldNumSlots) {
+            return;
+        }
+        ImsEnablementTrackerStateMachine enablementStateMachine = null;
+        if (oldNumSlots < numOfSlots) {
+            for (int i = oldNumSlots; i < numOfSlots; i++) {
+                enablementStateMachine = new ImsEnablementTrackerStateMachine(
+                        "ImsEnablementTracker", mLooper, mState, i);
+                enablementStateMachine.start();
+                mStateMachines.put(i, enablementStateMachine);
+            }
+        } else if (oldNumSlots > numOfSlots) {
+            for (int i = (oldNumSlots - 1); i > (numOfSlots - 1); i--) {
+                enablementStateMachine = mStateMachines.get(i);
+                mStateMachines.remove(i);
+                enablementStateMachine.quitNow();
+            }
+        }
+    }
+
+    @VisibleForTesting
+    public Handler getHandler(int slotId) {
+        return mStateMachines.get(slotId).getHandler();
+    }
+
+    /**
+     * Check that the current state and the input state are the same.
+     * @param state the input state.
+     * @return true if the current state and input state are the same or false.
+     */
+    @VisibleForTesting
+    public boolean isState(int slotId, int state) {
+        return mStateMachines.get(slotId).isState(state);
+    }
+
+    /**
+     * Notify the state machine that the subId has changed to invalid.
+     * @param slotId subscription id
+     */
+    public void subIdChangedToInvalid(int slotId) {
+        Log.d(LOG_TAG, "[" + slotId + "] subId changed to invalid, component:" + mComponentName);
+        ImsEnablementTrackerStateMachine stateMachine = mStateMachines.get(slotId);
+        if (stateMachine != null) {
+            stateMachine.sendMessage(COMMAND_INVALID_SUBID_MSG, slotId);
+        } else {
+            Log.w(LOG_TAG, "There is no state machine associated with this slotId.");
+        }
+    }
+
+    /**
+     * Notify ImsService to enable IMS for the framework. This will trigger IMS registration and
+     * trigger ImsFeature status updates.
+     * @param slotId slot id
+     * @param subId subscription id
+     */
+    public void enableIms(int slotId, int subId) {
+        Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]enableIms, component:" + mComponentName);
+        ImsEnablementTrackerStateMachine stateMachine = mStateMachines.get(slotId);
+        if (stateMachine != null) {
+            stateMachine.sendMessage(COMMAND_ENABLE_MSG, slotId, subId);
+        } else {
+            Log.w(LOG_TAG, "There is no state machine associated with this slotId.");
+        }
+    }
+
+    /**
+     * Notify ImsService to disable IMS for the framework. This will trigger IMS de-registration and
+     * trigger ImsFeature capability status to become false.
+     * @param slotId slot id
+     * @param subId subscription id
+     */
+    public void disableIms(int slotId, int subId) {
+        Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]disableIms, component:" + mComponentName);
+        ImsEnablementTrackerStateMachine stateMachine = mStateMachines.get(slotId);
+        if (stateMachine != null) {
+            stateMachine.sendMessage(COMMAND_DISABLE_MSG, slotId, subId);
+        } else {
+            Log.w(LOG_TAG, "There is no state machine associated with this slotId.");
+        }
+    }
+
+    /**
+     * Notify ImsService to reset IMS for the framework. This will trigger ImsService to perform
+     * de-registration and release all resource. After that, if enaleIms is called, the ImsService
+     * performs registration and appropriate initialization to bring up all ImsFeatures.
+     * @param slotId slot id
+     * @param subId subscription id
+     */
+    public void resetIms(int slotId, int subId) {
+        Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]resetIms, component:" + mComponentName);
+        ImsEnablementTrackerStateMachine stateMachine = mStateMachines.get(slotId);
+        if (stateMachine != null) {
+            stateMachine.sendMessage(COMMAND_RESET_MSG, slotId, subId);
+        } else {
+            Log.w(LOG_TAG, "There is no state machine associated with this slotId.");
+        }
+    }
+
+    /**
+     * Sets the IImsServiceController instance.
+     */
+    protected void setServiceController(IBinder serviceController) {
+        synchronized (mLock) {
+            mIImsServiceController = IImsServiceController.Stub.asInterface(serviceController);
+            Log.d(LOG_TAG, "setServiceController with Binder:" + mIImsServiceController
+                    + ", component:" + mComponentName);
+            ImsEnablementTrackerStateMachine stateMachine = null;
+            for (int i = 0; i < mStateMachines.size(); i++) {
+                stateMachine = mStateMachines.get(i);
+                if (stateMachine == null) {
+                    Log.w(LOG_TAG, "There is no state machine associated with"
+                            + "the slotId[" + i + "]");
+                    continue;
+                }
+                if (isServiceControllerAvailable()) {
+                    stateMachine.serviceBinderConnected();
+                } else {
+                    stateMachine.serviceBinderDisconnected();
+                }
+            }
+        }
+    }
+
+    protected long getLastOperationTimeMillis() {
+        return mLastImsOperationTimeMs;
+    }
+
+    /**
+     * Get remaining throttle time value
+     * @return remaining throttle time value
+     */
+    @VisibleForTesting
+    public long getRemainThrottleTime() {
+        long remainTime = REQUEST_THROTTLE_TIME_MS - (System.currentTimeMillis()
+                - getLastOperationTimeMillis());
+
+        if (remainTime < 0) {
+            remainTime = 0L;
+        }
+        Log.d(LOG_TAG, "getRemainThrottleTime:" + remainTime);
+
+        return remainTime;
+    }
+
+    /**
+     * Check to see if the service controller is available.
+     * @return true if available, false otherwise
+     */
+    private boolean isServiceControllerAvailable() {
+        if (mIImsServiceController != null) {
+            return true;
+        }
+        Log.d(LOG_TAG, "isServiceControllerAvailable : binder is not alive");
+        return false;
+    }
+
+    private void sendEnableIms(int slotId, int subId) {
+        try {
+            synchronized (mLock) {
+                if (isServiceControllerAvailable()) {
+                    Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]sendEnableIms,"
+                            + "componentName[" + mComponentName + "]");
+                    mIImsServiceController.enableIms(slotId, subId);
+                    mLastImsOperationTimeMs = System.currentTimeMillis();
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Couldn't enable IMS: " + e.getMessage());
+        }
+    }
+
+    private void sendDisableIms(int slotId, int subId) {
+        try {
+            synchronized (mLock) {
+                if (isServiceControllerAvailable()) {
+                    Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]sendDisableIms"
+                            + " componentName[" + mComponentName + "]");
+                    mIImsServiceController.disableIms(slotId, subId);
+                    mLastImsOperationTimeMs = System.currentTimeMillis();
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Couldn't disable IMS: " + e.getMessage());
+        }
+    }
+
+    private void sendResetIms(int slotId, int subId) {
+        try {
+            synchronized (mLock) {
+                if (isServiceControllerAvailable()) {
+                    Log.d(LOG_TAG, "[" + slotId + "][" + subId + "]sendResetIms");
+                    mIImsServiceController.resetIms(slotId, subId);
+                    mLastImsOperationTimeMs = System.currentTimeMillis();
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Couldn't reset IMS: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index 0cb58aa..49b7e62 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -30,6 +30,7 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.HandlerExecutor;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
@@ -130,6 +131,7 @@
 
     // Delay between dynamic ImsService queries.
     private static final int DELAY_DYNAMIC_QUERY_MS = 5000;
+    private static final HandlerThread sHandlerThread = new HandlerThread(TAG);
 
     private static ImsResolver sInstance;
 
@@ -139,9 +141,9 @@
     public static void make(Context context, String defaultMmTelPackageName,
             String defaultRcsPackageName, int numSlots, ImsFeatureBinderRepository repo) {
         if (sInstance == null) {
-            Looper looper = Looper.getMainLooper();
+            sHandlerThread.start();
             sInstance = new ImsResolver(context, defaultMmTelPackageName, defaultRcsPackageName,
-                    numSlots, repo, looper);
+                    numSlots, repo, sHandlerThread.getLooper());
         }
     }
 
@@ -630,8 +632,13 @@
 
     /**
      * Needs to be called after the constructor to kick off the process of binding to ImsServices.
+     * Should be run on the handler thread of ImsResolver
      */
     public void initialize() {
+        mHandler.post(()-> initializeInternal());
+    }
+
+    private void initializeInternal() {
         mEventLog.log("Initializing");
         Log.i(TAG, "Initializing cache.");
         PhoneConfigurationManager.registerForMultiSimConfigChange(mHandler,
@@ -738,6 +745,15 @@
     }
 
     /**
+     * Notify ImsService to disable IMS for the framework.
+     * And notify ImsService back to enable IMS for the framework.
+     */
+    public void resetIms(int slotId) {
+        getImsServiceControllers(slotId).forEach(
+                (controller) -> controller.resetIms(slotId, getSubId(slotId)));
+    }
+
+    /**
      * Returns the ImsRegistration structure associated with the slotId and feature specified.
      */
     public @Nullable IImsRegistration getImsRegistration(int slotId, int feature) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index 92e7d71..6af7a08 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -85,14 +85,49 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mHandler.getLooper().isCurrentThread()) {
+                onServiceConnectedInternal(name, service);
+            } else {
+                mHandler.post(() -> onServiceConnectedInternal(name, service));
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (mHandler.getLooper().isCurrentThread()) {
+                onServiceDisconnectedInternal(name);
+            } else {
+                mHandler.post(() -> onServiceDisconnectedInternal(name));
+            }
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            if (mHandler.getLooper().isCurrentThread()) {
+                onBindingDiedInternal(name);
+            } else {
+                mHandler.post(() -> onBindingDiedInternal(name));
+            }
+        }
+
+        @Override
+        public void onNullBinding(ComponentName name) {
+            if (mHandler.getLooper().isCurrentThread()) {
+                onNullBindingInternal(name);
+            } else {
+                mHandler.post(() -> onNullBindingInternal(name));
+            }
+        }
+
+        private void onServiceConnectedInternal(ComponentName name, IBinder service) {
             synchronized (mLock) {
                 mBackoff.stop();
                 mIsBound = true;
                 mIsBinding = false;
                 try {
-                    mLocalLog.log("onServiceConnected");
-                    Log.d(LOG_TAG, "ImsService(" + name + "): onServiceConnected with binder: "
-                            + service);
+                    mLocalLog.log("onServiceConnectedInternal");
+                    Log.d(LOG_TAG, "ImsService(" + name
+                            + "): onServiceConnectedInternal with binder: " + service);
                     setServiceController(service);
                     notifyImsServiceReady();
                     retrieveStaticImsServiceCapabilities();
@@ -118,20 +153,18 @@
             }
         }
 
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
+        private void onServiceDisconnectedInternal(ComponentName name) {
             synchronized (mLock) {
                 mIsBinding = false;
                 cleanupConnection();
             }
-            mLocalLog.log("onServiceDisconnected");
-            Log.w(LOG_TAG, "ImsService(" + name + "): onServiceDisconnected. Waiting...");
+            mLocalLog.log("onServiceDisconnectedInternal");
+            Log.w(LOG_TAG, "ImsService(" + name + "): onServiceDisconnectedInternal. Waiting...");
             // Service disconnected, but we are still technically bound. Waiting for reconnect.
             checkAndReportAnomaly(name);
         }
 
-        @Override
-        public void onBindingDied(ComponentName name) {
+        private void onBindingDiedInternal(ComponentName name) {
             mIsServiceConnectionDead = true;
             synchronized (mLock) {
                 mIsBinding = false;
@@ -141,15 +174,15 @@
                 unbindService();
                 startDelayedRebindToService();
             }
-            Log.w(LOG_TAG, "ImsService(" + name + "): onBindingDied. Starting rebind...");
-            mLocalLog.log("onBindingDied, retrying in " + mBackoff.getCurrentDelay() + " mS");
+            Log.w(LOG_TAG, "ImsService(" + name + "): onBindingDiedInternal. Starting rebind...");
+            mLocalLog.log("onBindingDiedInternal, retrying in "
+                    + mBackoff.getCurrentDelay() + " mS");
         }
 
-        @Override
-        public void onNullBinding(ComponentName name) {
-            Log.w(LOG_TAG, "ImsService(" + name + "): onNullBinding. Is service dead = "
+        private void onNullBindingInternal(ComponentName name) {
+            Log.w(LOG_TAG, "ImsService(" + name + "): onNullBindingInternal. Is service dead = "
                     + mIsServiceConnectionDead);
-            mLocalLog.log("onNullBinding, is service dead = " + mIsServiceConnectionDead);
+            mLocalLog.log("onNullBindingInternal, is service dead = " + mIsServiceConnectionDead);
             // onNullBinding will happen after onBindingDied. In this case, we should not
             // permanently unbind and instead let the automatic rebind occur.
             if (mIsServiceConnectionDead) return;
@@ -230,6 +263,7 @@
     private static final boolean ENFORCE_SINGLE_SERVICE_FOR_SIP_TRANSPORT = false;
     private final ComponentName mComponentName;
     private final HandlerThread mHandlerThread = new HandlerThread("ImsServiceControllerHandler");
+    private final Handler mHandler;
     private final LegacyPermissionManager mPermissionManager;
     private ImsFeatureBinderRepository mRepo;
     private ImsServiceControllerCallbacks mCallbacks;
@@ -241,6 +275,7 @@
     private Set<ImsFeatureConfiguration.FeatureSlotPair> mImsFeatures;
     private SparseIntArray mSlotIdToSubIdMap;
     private IImsServiceController mIImsServiceController;
+    private final ImsEnablementTracker mImsEnablementTracker;
     // The Capabilities bitmask of the connected ImsService (see ImsService#ImsServiceCapability).
     private long mServiceCapabilities;
     private ImsServiceConnection mImsServiceConnection;
@@ -323,16 +358,17 @@
         mComponentName = componentName;
         mCallbacks = callbacks;
         mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
         mBackoff = new ExponentialBackoff(
                 mRebindRetry.getStartDelay(),
                 mRebindRetry.getMaximumDelay(),
                 2, /* multiplier */
-                mHandlerThread.getLooper(),
+                mHandler,
                 mRestartImsServiceRunnable);
         mPermissionManager = (LegacyPermissionManager) mContext.getSystemService(
                 Context.LEGACY_PERMISSION_SERVICE);
         mRepo = repo;
-
+        mImsEnablementTracker = new ImsEnablementTracker(mHandlerThread.getLooper(), componentName);
         mPackageManager = mContext.getPackageManager();
         if (mPackageManager != null) {
             mChangedPackages = mPackageManager.getChangedPackages(mLastSequenceNumber);
@@ -351,6 +387,7 @@
         mContext = context;
         mComponentName = componentName;
         mCallbacks = callbacks;
+        mHandler = handler;
         mBackoff = new ExponentialBackoff(
                 rebindRetry.getStartDelay(),
                 rebindRetry.getMaximumDelay(),
@@ -359,6 +396,7 @@
                 mRestartImsServiceRunnable);
         mPermissionManager = null;
         mRepo = repo;
+        mImsEnablementTracker = new ImsEnablementTracker(handler.getLooper(), componentName);
     }
 
     /**
@@ -378,6 +416,8 @@
                 sanitizeFeatureConfig(imsFeatureSet);
                 mImsFeatures = imsFeatureSet;
                 mSlotIdToSubIdMap = slotIdToSubIdMap;
+                // Set the number of slots that support the feature
+                mImsEnablementTracker.setNumOfSlots(mSlotIdToSubIdMap.size());
                 grantPermissionsToService();
                 Intent imsServiceIntent = new Intent(getServiceInterface()).setComponent(
                         mComponentName);
@@ -464,6 +504,14 @@
                             + newSubId);
                     Log.i(LOG_TAG, "subId changed for slot: " + slotID + ", " + oldSubId + " -> "
                             + newSubId);
+                    if (newSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                        /* An INVALID subId can also be set in bind(), however
+                        the ImsEnablementTracker will move into the DEFAULT state, so we only
+                        need to track changes in subId that result in requiring we move
+                        the state machine back to DEFAULT.
+                         */
+                        mImsEnablementTracker.subIdChangedToInvalid(slotID);
+                    }
                 }
             }
             mSlotIdToSubIdMap = slotIdToSubIdMap;
@@ -553,15 +601,7 @@
      * trigger ImsFeature status updates.
      */
     public void enableIms(int slotId, int subId) {
-        try {
-            synchronized (mLock) {
-                if (isServiceControllerAvailable()) {
-                    mIImsServiceController.enableIms(slotId, subId);
-                }
-            }
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Couldn't enable IMS: " + e.getMessage());
-        }
+        mImsEnablementTracker.enableIms(slotId, subId);
     }
 
     /**
@@ -569,15 +609,15 @@
      * trigger ImsFeature capability status to become false.
      */
     public void disableIms(int slotId, int subId) {
-        try {
-            synchronized (mLock) {
-                if (isServiceControllerAvailable()) {
-                    mIImsServiceController.disableIms(slotId, subId);
-                }
-            }
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Couldn't disable IMS: " + e.getMessage());
-        }
+        mImsEnablementTracker.disableIms(slotId, subId);
+    }
+
+    /**
+     * Notify ImsService to disable IMS for the framework.
+     * And notify ImsService back to enable IMS for the framework
+     */
+    public void resetIms(int slotId, int subId) {
+        mImsEnablementTracker.resetIms(slotId, subId);
     }
 
     /**
@@ -651,6 +691,7 @@
      */
     protected void setServiceController(IBinder serviceController) {
         mIImsServiceController = IImsServiceController.Stub.asInterface(serviceController);
+        mImsEnablementTracker.setServiceController(serviceController);
     }
 
     /**
@@ -910,7 +951,7 @@
             return;
         }
         ChangedPackages curChangedPackages =
-                            mPackageManager.getChangedPackages(mLastSequenceNumber);
+                mPackageManager.getChangedPackages(mLastSequenceNumber);
         if (curChangedPackages != null) {
             mLastSequenceNumber = curChangedPackages.getSequenceNumber();
             List<String> packagesNames = curChangedPackages.getPackageNames();
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsCallInfo.java b/src/java/com/android/internal/telephony/imsphone/ImsCallInfo.java
new file mode 100644
index 0000000..79ab9c5
--- /dev/null
+++ b/src/java/com/android/internal/telephony/imsphone/ImsCallInfo.java
@@ -0,0 +1,121 @@
+/*
+ * 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.imsphone;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.ServiceState;
+
+import com.android.internal.telephony.Call;
+
+/**
+ * Contains call state to be notified to modem.
+ */
+public class ImsCallInfo {
+
+    private final int mIndex;
+    private @Nullable ImsPhoneConnection mConnection = null;
+    private Call.State mState = Call.State.IDLE;
+    private boolean mIsHeldByRemote = false;
+
+    public ImsCallInfo(int index) {
+        mIndex = index;
+    }
+
+    /** Clears the call state. */
+    public void reset() {
+        mConnection = null;
+        mState = Call.State.IDLE;
+        mIsHeldByRemote = false;
+    }
+
+    /**
+     * Updates the state of the IMS call.
+     *
+     * @param c The instance of {@link ImsPhoneConnection}.
+     */
+    public void update(@NonNull ImsPhoneConnection c) {
+        mConnection = c;
+        mState = c.getState();
+    }
+
+    /**
+     * Updates the state of the IMS call.
+     *
+     * @param c The instance of {@link ImsPhoneConnection}.
+     * @param holdReceived {@code true} if the remote party held the call.
+     * @param resumeReceived {@code true} if the remote party resumed the call.
+     */
+    public boolean update(@NonNull ImsPhoneConnection c,
+            boolean holdReceived, boolean resumeReceived) {
+        Call.State state = c.getState();
+        boolean changed = mState != state;
+        mState = state;
+
+        if (holdReceived && !mIsHeldByRemote) {
+            changed = true;
+            mIsHeldByRemote = true;
+        } else if (resumeReceived && mIsHeldByRemote) {
+            changed = true;
+            mIsHeldByRemote = false;
+        }
+
+        return changed;
+    }
+
+    /** Called when clearing orphaned connection. */
+    public void onDisconnect() {
+        mState = Call.State.DISCONNECTED;
+    }
+
+    /** @return the call index. */
+    public int getIndex() {
+        return mIndex;
+    }
+
+    /** @return the call state. */
+    public Call.State getCallState() {
+        return mState;
+    }
+
+    /** @return whether the remote party is holding the call. */
+    public boolean isHeldByRemote() {
+        return mIsHeldByRemote;
+    }
+
+    /** @return {@code true} if the call is an incoming call. */
+    public boolean isIncoming() {
+        return mConnection.isIncoming();
+    }
+
+    /** @return {@code true} if the call is an emergency call. */
+    public boolean isEmergencyCall() {
+        return mConnection.isEmergencyCall();
+    }
+
+    /** @return the radio technology used for current connection. */
+    public @AccessNetworkConstants.RadioAccessNetworkType int getCallRadioTech() {
+        return ServiceState.rilRadioTechnologyToAccessNetworkType(mConnection.getCallRadioTech());
+    }
+
+    @Override
+    public String toString() {
+        return "[ id=" + mIndex + ", state=" + mState
+                + ", isMT=" + isIncoming() + ", heldByRemote=" + mIsHeldByRemote + " ]";
+    }
+}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsCallInfoTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsCallInfoTracker.java
new file mode 100644
index 0000000..5783e48
--- /dev/null
+++ b/src/java/com/android/internal/telephony/imsphone/ImsCallInfoTracker.java
@@ -0,0 +1,205 @@
+/*
+ * 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.imsphone;
+
+import static com.android.internal.telephony.Call.State.DISCONNECTED;
+import static com.android.internal.telephony.Call.State.IDLE;
+
+import android.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.telephony.Rlog;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains the state of all IMS calls.
+ */
+public class ImsCallInfoTracker {
+    private static final String LOG_TAG = "ImsCallInfoTracker";
+    private static final boolean DBG = false;
+
+    private final Phone mPhone;
+    private final List<ImsCallInfo> mQueue = new ArrayList<>();
+    private int mNextIndex = 1;
+
+    private final Map<Connection, ImsCallInfo> mImsCallInfo = new HashMap<>();
+
+    public ImsCallInfoTracker(Phone phone) {
+        mPhone = phone;
+    }
+
+    /**
+     * Adds a new instance of the IMS call.
+     *
+     * @param c The instance of {@link ImsPhoneConnection}.
+     */
+    public void addImsCallStatus(@NonNull ImsPhoneConnection c) {
+        if (DBG) Rlog.d(LOG_TAG, "addImsCallStatus");
+
+        synchronized (mImsCallInfo) {
+            if (mQueue.isEmpty()) {
+                mQueue.add(new ImsCallInfo(mNextIndex++));
+            }
+
+            Iterator<ImsCallInfo> it = mQueue.iterator();
+            ImsCallInfo imsCallInfo = it.next();
+            mQueue.remove(imsCallInfo);
+
+            imsCallInfo.update(c);
+            mImsCallInfo.put(c, imsCallInfo);
+
+            notifyImsCallStatus();
+
+            if (DBG) dump();
+        }
+    }
+
+    /**
+     * Updates the list of IMS calls.
+     *
+     * @param c The instance of {@link ImsPhoneConnection}.
+     */
+    public void updateImsCallStatus(@NonNull ImsPhoneConnection c) {
+        updateImsCallStatus(c, false, false);
+    }
+
+    /**
+     * Updates the list of IMS calls.
+     *
+     * @param c The instance of {@link ImsPhoneConnection}.
+     * @param holdReceived {@code true} if the remote party held the call.
+     * @param resumeReceived {@code true} if the remote party resumed the call.
+     */
+    public void updateImsCallStatus(@NonNull ImsPhoneConnection c,
+            boolean holdReceived, boolean resumeReceived) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, "updateImsCallStatus holdReceived=" + holdReceived
+                    + ", resumeReceived=" + resumeReceived);
+        }
+
+        synchronized (mImsCallInfo) {
+            ImsCallInfo info = mImsCallInfo.get(c);
+
+            if (info == null) {
+                // This happens when the user tries to hangup the call after handover has completed.
+                return;
+            }
+
+            boolean changed = info.update(c, holdReceived, resumeReceived);
+
+            if (changed) notifyImsCallStatus();
+
+            Call.State state = c.getState();
+
+            if (DBG) Rlog.d(LOG_TAG, "updateImsCallStatus state=" + state);
+            // Call is disconnected. There are 2 cases in disconnected state:
+            // if silent redial, state == IDLE, otherwise, state == DISCONNECTED.
+            if (state == DISCONNECTED || state == IDLE) {
+                // clear the disconnected call
+                mImsCallInfo.remove(c);
+                info.reset();
+                if (info.getIndex() < (mNextIndex - 1)) {
+                    mQueue.add(info);
+                    sort(mQueue);
+                } else {
+                    mNextIndex--;
+                }
+            }
+
+            if (DBG) dump();
+        }
+    }
+
+    /** Clears all orphaned IMS call information. */
+    public void clearAllOrphanedConnections() {
+        if (DBG) Rlog.d(LOG_TAG, "clearAllOrphanedConnections");
+
+        Collection<ImsCallInfo> infos = mImsCallInfo.values();
+        infos.stream().forEach(info -> { info.onDisconnect(); });
+        notifyImsCallStatus();
+        clearAllCallInfo();
+
+        if (DBG) dump();
+    }
+
+    /** Notifies that SRVCC has completed. */
+    public void notifySrvccCompleted() {
+        if (DBG) Rlog.d(LOG_TAG, "notifySrvccCompleted");
+
+        clearAllCallInfo();
+        notifyImsCallStatus();
+
+        if (DBG) dump();
+    }
+
+    private void clearAllCallInfo() {
+        try {
+            Collection<ImsCallInfo> infos = mImsCallInfo.values();
+            infos.stream().forEach(info -> { info.reset(); });
+            mImsCallInfo.clear();
+            mQueue.clear();
+            mNextIndex = 1;
+        } catch (UnsupportedOperationException e) {
+            Rlog.e(LOG_TAG, "e=" + e);
+        }
+    }
+
+    private void notifyImsCallStatus() {
+        Collection<ImsCallInfo> infos = mImsCallInfo.values();
+        ArrayList<ImsCallInfo> imsCallInfo = new ArrayList<ImsCallInfo>(infos);
+        sort(imsCallInfo);
+        mPhone.updateImsCallStatus(imsCallInfo, null);
+    }
+
+    /**
+     * Sorts the list of IMS calls by the call index.
+     *
+     * @param infos The list of IMS calls.
+     */
+    @VisibleForTesting
+    public static void sort(List<ImsCallInfo> infos) {
+        Collections.sort(infos, new Comparator<ImsCallInfo>() {
+            @Override
+            public int compare(ImsCallInfo l, ImsCallInfo r) {
+                if (l.getIndex() > r.getIndex()) {
+                    return 1;
+                } else if (l.getIndex() < r.getIndex()) {
+                    return -1;
+                }
+                return 0;
+            }
+        });
+    }
+
+    private void dump() {
+        Collection<ImsCallInfo> infos = mImsCallInfo.values();
+        ArrayList<ImsCallInfo> imsCallInfo = new ArrayList<ImsCallInfo>(infos);
+        sort(imsCallInfo);
+        Rlog.d(LOG_TAG, "imsCallInfos=" + imsCallInfo);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java b/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java
new file mode 100644
index 0000000..3dedde8
--- /dev/null
+++ b/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2023 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.imsphone;
+
+import static android.telephony.CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA;
+import static android.telephony.CarrierConfigManager.Ims.KEY_NR_SA_DISABLE_POLICY_INT;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_NONE;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED;
+import static android.telephony.CarrierConfigManager.Ims.NrSaDisablePolicy;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Call;
+
+import java.util.Arrays;
+import java.util.Set;
+
+/**
+ * Enables or Disables NR-SA mode temporarily under certain conditions where WFC is established or
+ * IMS is registered over WiFi in order to improve the delay or voice mute issue when the handover
+ * from ePDG to NR is not supported in UE or network.
+ */
+public class ImsNrSaModeHandler extends Handler{
+
+    public static final String TAG = "ImsNrSaModeHandler";
+    public static final String MMTEL_FEATURE_TAG =
+            "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"";
+
+    private static final int MSG_PRECISE_CALL_STATE_CHANGED = 101;
+    private static final int MSG_REQUEST_IS_VONR_ENABLED = 102;
+    private static final int MSG_RESULT_IS_VONR_ENABLED = 103;
+
+    private final @NonNull ImsPhone mPhone;
+    private @Nullable CarrierConfigManager mCarrierConfigManager;
+
+    private @NrSaDisablePolicy int mNrSaDisablePolicy;
+    private boolean mIsNrSaDisabledForWfc;
+    private boolean mIsVowifiRegistered;
+    private boolean mIsInImsCall;
+    private boolean mIsNrSaSupported;
+
+    private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            (slotIndex, subId, carrierId, specificCarrierId) -> setNrSaDisablePolicy(subId);
+
+    public ImsNrSaModeHandler(@NonNull ImsPhone phone, Looper looper) {
+        super(looper);
+        mPhone = phone;
+        mCarrierConfigManager = (CarrierConfigManager) mPhone.getContext()
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+
+        registerForCarrierConfigChanges();
+    }
+
+    /**
+     * Performs any cleanup required before the ImsNrSaModeHandler is destroyed.
+     */
+    public void tearDown() {
+        unregisterForCarrierConfigChanges();
+        unregisterForPreciseCallStateChanges();
+
+        if (isNrSaDisabledForWfc()) {
+            setNrSaMode(true);
+        }
+    }
+
+    /**
+     * Based on changed VoWiFi reg state and call state, handles NR SA mode if needed.
+     * It is including handover case.
+     *
+     * @param imsRadioTech The current registered RAT.
+     */
+    public void onImsRegistered(
+            @ImsRegistrationTech int imsRadioTech, @NonNull Set<String> featureTags) {
+        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE) {
+            return;
+        }
+
+        Log.d(TAG, "onImsRegistered: ImsRegistrationTech = " + imsRadioTech);
+
+        boolean isVowifiRegChanged = false;
+
+        if (isVowifiRegistered() && imsRadioTech != REGISTRATION_TECH_IWLAN) {
+            setVowifiRegStatus(false);
+            isVowifiRegChanged = true;
+        } else if (!isVowifiRegistered() && imsRadioTech == REGISTRATION_TECH_IWLAN
+                && featureTags.contains(MMTEL_FEATURE_TAG)) {
+            setVowifiRegStatus(true);
+            isVowifiRegChanged = true;
+        }
+
+        if (isVowifiRegChanged) {
+            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED) {
+                setNrSaMode(!isVowifiRegistered());
+            } else if ((mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED
+                    || mNrSaDisablePolicy
+                    == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED)
+                    && isImsCallOngoing()) {
+                if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
+                    requestIsVonrEnabled(!isVowifiRegistered());
+                    return;
+                }
+
+                setNrSaMode(!isVowifiRegistered());
+            }
+        }
+    }
+
+    /**
+     * Based on changed VoWiFi reg state and call state, handles NR SA mode if needed.
+     *
+     * @param imsRadioTech The current un-registered RAT.
+     */
+    public void onImsUnregistered(
+            @ImsRegistrationTech int imsRadioTech) {
+        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE
+                || imsRadioTech != REGISTRATION_TECH_IWLAN || !isVowifiRegistered()) {
+            return;
+        }
+
+        Log.d(TAG, "onImsUnregistered : ImsRegistrationTech = " + imsRadioTech);
+
+        setVowifiRegStatus(false);
+
+        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED) {
+            setNrSaMode(true);
+        } else if ((mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED
+                || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED)
+                && isImsCallOngoing()) {
+            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
+                requestIsVonrEnabled(true);
+                return;
+            }
+
+            setNrSaMode(true);
+        }
+    }
+
+    /**
+     * Based on changed precise call state and VoWiFi reg state, handles NR SA mode if needed.
+     */
+    public void onPreciseCallStateChanged() {
+        Log.d(TAG, "onPreciseCallStateChanged :  foreground state = "
+                + mPhone.getForegroundCall().getState() + ", background state = "
+                + mPhone.getBackgroundCall().getState());
+
+        boolean isImsCallStatusChanged = false;
+
+        if (isImsCallJustEstablished()) {
+            setImsCallStatus(true);
+            isImsCallStatusChanged = true;
+        } else if (isImsCallJustTerminated()) {
+            setImsCallStatus(false);
+            isImsCallStatusChanged = true;
+        }
+
+        if (isVowifiRegistered() && isImsCallStatusChanged) {
+            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
+                requestIsVonrEnabled(!isImsCallOngoing());
+                return;
+            }
+
+            setNrSaMode(!isImsCallOngoing());
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        AsyncResult ar;
+
+        switch (msg.what) {
+            case MSG_PRECISE_CALL_STATE_CHANGED :
+                onPreciseCallStateChanged();
+                break;
+            case MSG_REQUEST_IS_VONR_ENABLED :
+                Log.d(TAG, "request isVoNrEnabled");
+                mPhone.getDefaultPhone().mCi.isVoNrEnabled(
+                        obtainMessage(MSG_RESULT_IS_VONR_ENABLED, msg.obj), null);
+                break;
+            case MSG_RESULT_IS_VONR_ENABLED :
+                ar = (AsyncResult) msg.obj;
+
+                if (ar.result != null) {
+                    boolean vonrEnabled = ((Boolean) ar.result).booleanValue();
+
+                    Log.d(TAG, "result isVoNrEnabled = " + vonrEnabled);
+                    if (!vonrEnabled) {
+                        setNrSaMode(((Boolean) ar.userObj).booleanValue());
+                    }
+                }
+
+                ar = null;
+                break;
+            default :
+                break;
+        }
+    }
+
+    /**
+     * Registers for precise call state changes.
+     */
+    private void registerForPreciseCallStateChanges() {
+        mPhone.registerForPreciseCallStateChanged(this, MSG_PRECISE_CALL_STATE_CHANGED, null);
+    }
+
+    /**
+     * Unregisters for precise call state changes.
+     */
+    private void unregisterForPreciseCallStateChanges() {
+        mPhone.unregisterForPreciseCallStateChanged(this);
+    }
+
+    /**
+     * Registers for carrier config changes.
+     */
+    private void registerForCarrierConfigChanges() {
+        if (mCarrierConfigManager != null) {
+            mCarrierConfigManager.registerCarrierConfigChangeListener(
+                    this::post, mCarrierConfigChangeListener);
+        }
+    }
+
+    /**
+     * Unregisters for carrier config changes.
+     */
+    private void unregisterForCarrierConfigChanges() {
+        if (mCarrierConfigManager != null) {
+            mCarrierConfigManager.unregisterCarrierConfigChangeListener(
+                    mCarrierConfigChangeListener);
+        }
+    }
+
+    private void setNrSaDisablePolicy(int subId) {
+        if (mPhone.getSubId() == subId && mCarrierConfigManager != null) {
+            PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
+                    KEY_NR_SA_DISABLE_POLICY_INT, KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
+            mNrSaDisablePolicy = bundle.getInt(KEY_NR_SA_DISABLE_POLICY_INT);
+            mIsNrSaSupported = Arrays.stream(
+                    bundle.getIntArray(KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY)).anyMatch(
+                        value -> value == CARRIER_NR_AVAILABILITY_SA);
+
+            Log.d(TAG, "setNrSaDisablePolicy : NrSaDisablePolicy = "
+                    + mNrSaDisablePolicy + ", IsNrSaSupported = "  + mIsNrSaSupported);
+
+            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED
+                    || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED) {
+                registerForPreciseCallStateChanges();
+            } else {
+                unregisterForPreciseCallStateChanges();
+            }
+        }
+    }
+
+    private void requestIsVonrEnabled(boolean onOrOff) {
+        Message msg = obtainMessage(MSG_REQUEST_IS_VONR_ENABLED, onOrOff);
+        msg.sendToTarget();
+    }
+
+    private void setNrSaMode(boolean onOrOff) {
+        if (mIsNrSaSupported) {
+            mPhone.getDefaultPhone().mCi.setN1ModeEnabled(onOrOff, null);
+            Log.i(TAG, "setNrSaMode : " + onOrOff);
+
+            setNrSaDisabledForWfc(!onOrOff);
+        }
+    }
+
+    /**
+     * Sets VoWiFi reg status.
+     */
+    @VisibleForTesting
+    public void setVowifiRegStatus(boolean registered) {
+        Log.d(TAG, "setVowifiRegStatus : " + registered);
+        mIsVowifiRegistered = registered;
+    }
+
+    /**
+     * Sets IMS call status
+     */
+    @VisibleForTesting
+    public void setImsCallStatus(boolean inImsCall) {
+        Log.d(TAG, "setImsCallStatus : " + inImsCall);
+        mIsInImsCall = inImsCall;
+    }
+
+    @VisibleForTesting
+    public boolean isVowifiRegistered() {
+        return mIsVowifiRegistered;
+    }
+
+    @VisibleForTesting
+    public boolean isImsCallOngoing() {
+        return mIsInImsCall;
+    }
+
+    @VisibleForTesting
+    public boolean isNrSaDisabledForWfc() {
+        return mIsNrSaDisabledForWfc;
+    }
+
+    @VisibleForTesting
+    public void setNrSaDisabledForWfc(boolean disabled) {
+        mIsNrSaDisabledForWfc = disabled;
+    }
+
+    private boolean isImsCallJustEstablished() {
+        if (!isImsCallOngoing()) {
+            if ((mPhone.getForegroundCall().getState() == Call.State.ACTIVE)
+                    || (mPhone.getBackgroundCall().getState() == Call.State.ACTIVE)) {
+                Log.d(TAG, "isImsCallJustEstablished");
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private boolean isImsCallJustTerminated() {
+        if (isImsCallOngoing() && (!mPhone.getForegroundCall().getState().isAlive()
+                && !mPhone.getBackgroundCall().getState().isAlive())) {
+            Log.d(TAG, "isImsCallJustTerminated");
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 5c14b0e..4b150cc 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -16,9 +16,14 @@
 
 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;
+import static android.telephony.ims.RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
+import static android.telephony.ims.RegistrationManager.REGISTRATION_STATE_REGISTERED;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
 
 import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAIC;
 import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAICr;
@@ -42,6 +47,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -71,7 +77,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;
@@ -79,9 +84,12 @@
 import android.telephony.ims.ImsCallForwardInfo;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.ImsSsData;
 import android.telephony.ims.ImsSsInfo;
 import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.ims.stub.ImsUtImplBase;
 import android.text.TextUtils;
 import android.util.LocalLog;
@@ -107,10 +115,11 @@
 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.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.metrics.ImsStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
@@ -184,6 +193,7 @@
                     return new ImsDialArgs.Builder()
                             .setUusInfo(dialArgs.uusInfo)
                             .setIsEmergency(dialArgs.isEmergency)
+                            .setEccCategory(dialArgs.eccCategory)
                             .setVideoState(dialArgs.videoState)
                             .setIntentExtras(dialArgs.intentExtras)
                             .setRttTextStream(((ImsDialArgs)dialArgs).rttTextStream)
@@ -253,6 +263,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     ImsPhoneCallTracker mCT;
     ImsExternalCallTracker mExternalCallTracker;
+    ImsNrSaModeHandler mImsNrSaModeHandler;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private ArrayList <ImsPhoneMmiCode> mPendingMMIs = new ArrayList<ImsPhoneMmiCode>();
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -289,6 +300,16 @@
 
     private ImsStats mImsStats;
 
+    private int mImsRegistrationState;
+    // The access network type where IMS is registered
+    private @ImsRegistrationImplBase.ImsRegistrationTech int mImsRegistrationTech =
+            REGISTRATION_TECH_NONE;
+    private @RegistrationManager.SuggestedAction int mImsRegistrationSuggestedAction;
+    private @ImsRegistrationImplBase.ImsRegistrationTech int mImsDeregistrationTech =
+            REGISTRATION_TECH_NONE;
+    private int mImsRegistrationCapabilities;
+    private boolean mNotifiedRegisteredState;
+
     // A runnable which is used to automatically exit from Ecm after a period of time.
     private Runnable mExitEcmRunnable = new Runnable() {
         @Override
@@ -453,16 +474,16 @@
                 TelephonyComponentFactory.getInstance()
                         .inject(ImsExternalCallTracker.class.getName())
                         .makeImsExternalCallTracker(this);
+        mImsNrSaModeHandler =
+                TelephonyComponentFactory.getInstance()
+                        .inject(ImsNrSaModeHandler.class.getName())
+                        .makeImsNrSaModeHandler(this);
         mCT = TelephonyComponentFactory.getInstance().inject(ImsPhoneCallTracker.class.getName())
                 .makeImsPhoneCallTracker(this);
         mCT.registerPhoneStateListener(mExternalCallTracker);
         mExternalCallTracker.setCallPuller(mCT);
 
-        boolean legacyMode = true;
-        if (mDefaultPhone.getAccessNetworksManager() != null) {
-            legacyMode = mDefaultPhone.getAccessNetworksManager().isInLegacyMode();
-        }
-        mSS.setOutOfService(legacyMode, false);
+        mSS.setOutOfService(false);
 
         mPhoneId = mDefaultPhone.getPhoneId();
 
@@ -504,6 +525,7 @@
         //super.dispose();
         mPendingMMIs.clear();
         mExternalCallTracker.tearDown();
+        mImsNrSaModeHandler.tearDown();
         mCT.unregisterPhoneStateListener(mExternalCallTracker);
         mCT.unregisterForVoiceCallEnded(this);
         mCT.dispose();
@@ -892,6 +914,9 @@
 
     @Override
     public boolean isInImsEcm() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            return EmergencyStateTracker.getInstance().isInImsEcm();
+        }
         return mIsInImsEcm;
     }
 
@@ -1584,7 +1609,7 @@
     }
 
     @Override
-    public void notifySrvccState(Call.SrvccState state) {
+    public void notifySrvccState(int state) {
         mCT.notifySrvccState(state);
     }
 
@@ -2038,6 +2063,10 @@
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void handleEnterEmergencyCallbackMode() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            logd("DomainSelection enabled: ignore ECBM enter event.");
+            return;
+        }
         if (DBG) logd("handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= " + isInEcm());
         // if phone is not in Ecm mode, and it's changed to Ecm mode
         if (!isInEcm()) {
@@ -2059,6 +2088,10 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     protected void handleExitEmergencyCallbackMode() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            logd("DomainSelection enabled: ignore ECBM exit event.");
+            return;
+        }
         if (DBG) logd("handleExitEmergencyCallbackMode: mIsPhoneInEcmState = " + isInEcm());
 
         if (isInEcm()) {
@@ -2088,6 +2121,7 @@
      * Ecm timer and notify apps the timer is restarted.
      */
     void handleTimerInEmergencyCallbackMode(int action) {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) return;
         switch (action) {
             case CANCEL_ECM_TIMER:
                 removeCallbacks(mExitEcmRunnable);
@@ -2371,7 +2405,7 @@
     /**
      * Update roaming state and WFC mode in the following situations:
      *     1) voice is in service.
-     *     2) data is in service and it is not IWLAN (if in legacy mode).
+     *     2) data is in service.
      * @param ss non-null ServiceState
      */
     private void updateRoamingState(ServiceState ss) {
@@ -2392,15 +2426,7 @@
             logi("updateRoamingState: we are not IN_SERVICE, ignoring roaming change.");
             return;
         }
-        // We ignore roaming changes when moving to IWLAN because it always sets the roaming
-        // mode to home and masks the actual cellular roaming status if voice is not registered. If
-        // we just moved to IWLAN because WFC roaming mode is IWLAN preferred and WFC home mode is
-        // cell preferred, we can get into a condition where the modem keeps bouncing between
-        // IWLAN->cell->IWLAN->cell...
-        if (isCsNotInServiceAndPsWwanReportingWlan(ss)) {
-            logi("updateRoamingState: IWLAN masking roaming, ignore roaming change.");
-            return;
-        }
+
         if (mCT.getState() == PhoneConstants.State.IDLE) {
             if (DBG) logd("updateRoamingState now: " + newRoamingState);
             mLastKnownRoamingState = newRoamingState;
@@ -2419,30 +2445,6 @@
         }
     }
 
-    /**
-     * In legacy mode, data registration will report IWLAN when we are using WLAN for data,
-     * effectively masking the true roaming state of the device if voice is not registered.
-     *
-     * @return true if we are reporting not in service for CS domain over WWAN transport and WLAN
-     * for PS domain over WWAN transport.
-     */
-    private boolean isCsNotInServiceAndPsWwanReportingWlan(ServiceState ss) {
-        // We can not get into this condition if we are in AP-Assisted mode.
-        if (mDefaultPhone.getAccessNetworksManager() == null
-                || !mDefaultPhone.getAccessNetworksManager().isInLegacyMode()) {
-            return false;
-        }
-        NetworkRegistrationInfo csInfo = ss.getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        NetworkRegistrationInfo psInfo = ss.getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        // We will return roaming state correctly if the CS domain is in service because
-        // ss.getRoaming() returns isVoiceRoaming||isDataRoaming result and isDataRoaming==false
-        // when the modem reports IWLAN RAT.
-        return psInfo != null && csInfo != null && !csInfo.isInService()
-                && psInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_IWLAN;
-    }
-
     public RegistrationManager.RegistrationCallback getImsMmTelRegistrationCallback() {
         return mImsMmTelRegistrationHelper.getCallback();
     }
@@ -2453,12 +2455,18 @@
     public void resetImsRegistrationState() {
         if (DBG) logd("resetImsRegistrationState");
         mImsMmTelRegistrationHelper.reset();
+        int subId = getSubId();
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            updateImsRegistrationInfo(REGISTRATION_STATE_NOT_REGISTERED,
+                    REGISTRATION_TECH_NONE, SUGGESTED_ACTION_NONE);
+        }
     }
 
     private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mMmTelRegistrationUpdate = new
             ImsRegistrationCallbackHelper.ImsRegistrationUpdate() {
         @Override
-        public void handleImsRegistered(int imsRadioTech) {
+        public void handleImsRegistered(@NonNull ImsRegistrationAttributes attributes) {
+            int imsRadioTech = attributes.getTransportType();
             if (DBG) {
                 logd("handleImsRegistered: onImsMmTelConnected imsRadioTech="
                         + AccessNetworkConstants.transportTypeToString(imsRadioTech));
@@ -2469,6 +2477,10 @@
             getDefaultPhone().setImsRegistrationState(true);
             mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.CONNECTED, null);
             mImsStats.onImsRegistered(imsRadioTech);
+            mImsNrSaModeHandler.onImsRegistered(
+                    attributes.getRegistrationTechnology(), attributes.getFeatureTags());
+            updateImsRegistrationInfo(REGISTRATION_STATE_REGISTERED,
+                    attributes.getRegistrationTechnology(), SUGGESTED_ACTION_NONE);
         }
 
         @Override
@@ -2487,10 +2499,13 @@
         }
 
         @Override
-        public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) {
+        public void handleImsUnregistered(ImsReasonInfo imsReasonInfo,
+                @RegistrationManager.SuggestedAction int suggestedAction,
+                @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
             if (DBG) {
                 logd("handleImsUnregistered: onImsMmTelDisconnected imsReasonInfo="
-                        + imsReasonInfo);
+                        + imsReasonInfo + ", suggestedAction=" + suggestedAction
+                        + ", disconnectedRadioTech=" + imsRadioTech);
             }
             mRegLocalLog.log("handleImsUnregistered: onImsMmTelDisconnected imsRadioTech="
                     + imsReasonInfo);
@@ -2500,6 +2515,17 @@
             mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.DISCONNECTED,
                     imsReasonInfo);
             mImsStats.onImsUnregistered(imsReasonInfo);
+            mImsNrSaModeHandler.onImsUnregistered(imsRadioTech);
+            mImsRegistrationTech = REGISTRATION_TECH_NONE;
+            int suggestedModemAction = SUGGESTED_ACTION_NONE;
+            if (imsReasonInfo.getCode() == ImsReasonInfo.CODE_REGISTRATION_ERROR) {
+                if ((suggestedAction == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK)
+                        || (suggestedAction == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT)) {
+                    suggestedModemAction = suggestedAction;
+                }
+            }
+            updateImsRegistrationInfo(REGISTRATION_STATE_NOT_REGISTERED,
+                    imsRadioTech, suggestedModemAction);
         }
 
         @Override
@@ -2520,44 +2546,24 @@
         int subId = getSubId();
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             // Defending b/219080264:
-            // SubscriptionController.setSubscriptionProperty validates input subId
+            // SubscriptionManagerService.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;
         }
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = mSubscriptionManagerService
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo != null) {
-                phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber,
-                        subInfo.getCountryIso());
-                if (phoneNumber == null) {
-                    return;
-                }
-                mSubscriptionManagerService.setNumberFromIms(subId, phoneNumber);
-            }
-        } else {
-            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);
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerService
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo != null) {
+            phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber,
+                    subInfo.getCountryIso());
             if (phoneNumber == null) {
                 return;
             }
-            subController.setSubscriptionProperty(subId, COLUMN_PHONE_NUMBER_SOURCE_IMS,
-                    phoneNumber);
+            mSubscriptionManagerService.setNumberFromIms(subId, 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.
      *
@@ -2632,6 +2638,131 @@
         return mLastKnownRoamingState;
     }
 
+    /**
+     * Update IMS registration information to modem.
+     *
+     * @param capabilities indicate MMTEL capability such as VOICE, VIDEO and SMS.
+     */
+    public void updateImsRegistrationInfo(int capabilities) {
+        if (mImsRegistrationState == REGISTRATION_STATE_REGISTERED) {
+            if (mNotifiedRegisteredState && (capabilities == mImsRegistrationCapabilities)) {
+                // Duplicated notification, no change in capabilities.
+                return;
+            }
+
+            mImsRegistrationCapabilities = capabilities;
+            if (capabilities == 0) {
+                // Ignore this as this usually happens just before onUnregistered callback.
+                // We can notify modem when onUnregistered() flow occurs.
+                return;
+            }
+
+            mDefaultPhone.mCi.updateImsRegistrationInfo(mImsRegistrationState,
+                    mImsRegistrationTech, 0, capabilities, null);
+            mNotifiedRegisteredState = true;
+        }
+    }
+
+    /**
+     * Update IMS registration info
+     *
+     * @param regState indicates IMS registration state.
+     * @param imsRadioTech indicates the type of the radio access network where IMS is registered.
+     * @param suggestedAction indicates the suggested action for the radio to perform.
+     */
+    private void updateImsRegistrationInfo(
+            @RegistrationManager.ImsRegistrationState int regState,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
+            @RegistrationManager.SuggestedAction int suggestedAction) {
+
+        if (regState == mImsRegistrationState) {
+            if ((regState == REGISTRATION_STATE_REGISTERED && imsRadioTech == mImsRegistrationTech)
+                    || (regState == REGISTRATION_STATE_NOT_REGISTERED
+                            && suggestedAction == mImsRegistrationSuggestedAction
+                            && imsRadioTech == mImsDeregistrationTech)) {
+                // Filter duplicate notification.
+                return;
+            }
+        }
+
+        if (regState == REGISTRATION_STATE_NOT_REGISTERED) {
+            mDefaultPhone.mCi.updateImsRegistrationInfo(regState,
+                    imsRadioTech, suggestedAction, 0, null);
+        } else if (mImsRegistrationState == REGISTRATION_STATE_REGISTERED) {
+            // This happens when radio tech is changed while in REGISTERED state.
+            if (mImsRegistrationCapabilities > 0) {
+                // Capability has been updated. Notify REGISTRATION_STATE_REGISTERED.
+                mDefaultPhone.mCi.updateImsRegistrationInfo(regState, imsRadioTech, 0,
+                        mImsRegistrationCapabilities, null);
+                mImsRegistrationTech = imsRadioTech;
+                mNotifiedRegisteredState = true;
+                return;
+            }
+        }
+
+        mImsRegistrationState = regState;
+        mImsRegistrationTech = imsRadioTech;
+        mImsRegistrationSuggestedAction = suggestedAction;
+        if (regState == REGISTRATION_STATE_NOT_REGISTERED) {
+            mImsDeregistrationTech = imsRadioTech;
+        } else {
+            mImsDeregistrationTech = REGISTRATION_TECH_NONE;
+        }
+        mImsRegistrationCapabilities = 0;
+        // REGISTRATION_STATE_REGISTERED will be notified when the capability is updated.
+        mNotifiedRegisteredState = false;
+    }
+
+    @Override
+    public void setTerminalBasedCallWaitingStatus(int state) {
+        mCT.setTerminalBasedCallWaitingStatus(state);
+    }
+
+    @Override
+    public void triggerEpsFallback(@MmTelFeature.EpsFallbackReason int reason, Message response) {
+        mDefaultPhone.triggerEpsFallback(reason, response);
+    }
+
+    @Override
+    public void startImsTraffic(int token,
+            @MmTelFeature.ImsTrafficType int trafficType,
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+            @MmTelFeature.ImsTrafficDirection int trafficDirection, Message response) {
+        mDefaultPhone.startImsTraffic(token, trafficType,
+                accessNetworkType, trafficDirection, response);
+    }
+
+    @Override
+    public void stopImsTraffic(int token, Message response) {
+        mDefaultPhone.stopImsTraffic(token, response);
+    }
+
+    @Override
+    public void registerForConnectionSetupFailure(Handler h, int what, Object obj) {
+        mDefaultPhone.registerForConnectionSetupFailure(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForConnectionSetupFailure(Handler h) {
+        mDefaultPhone.unregisterForConnectionSetupFailure(h);
+    }
+
+    @Override
+    public void triggerImsDeregistration(
+            @ImsRegistrationImplBase.ImsDeregistrationReason int reason) {
+        mCT.triggerImsDeregistration(reason);
+    }
+
+    @Override
+    public void updateImsCallStatus(List<ImsCallInfo> imsCallInfo, Message response) {
+        mDefaultPhone.updateImsCallStatus(imsCallInfo, response);
+    }
+
+    @Override
+    public void triggerNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+        mCT.triggerNotifyAnbr(mediaType, direction, bitsPerSecond);
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index b5c7da1..8a1041d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -24,11 +24,13 @@
 import android.sysprop.TelephonyProperties;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.CallQuality;
+import android.telephony.CallState;
 import android.telephony.NetworkScanRequest;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.MediaQualityStatus;
 import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -138,6 +140,10 @@
         mNotifier.notifyCallQualityChanged(this, callQuality, callNetworkType);
     }
 
+    public void onMediaQualityStatusChanged(MediaQualityStatus status) {
+        mNotifier.notifyMediaQualityStatusChanged(this, status);
+    }
+
     @Override
     public ServiceState getServiceState() {
         // FIXME: we may need to provide this when data connectivity is lost
@@ -192,7 +198,43 @@
      */
     public void notifyPreciseCallStateChanged() {
         /* we'd love it if this was package-scoped*/
-        super.notifyPreciseCallStateChangedP();
+        AsyncResult ar = new AsyncResult(null, this, null);
+        mPreciseCallStateRegistrants.notifyRegistrants(ar);
+
+        notifyPreciseCallStateToNotifier();
+    }
+
+    public void notifyPreciseCallStateToNotifier() {
+        ImsPhoneCall ringingCall = (ImsPhoneCall) getRingingCall();
+        ImsPhoneCall foregroundCall = (ImsPhoneCall) getForegroundCall();
+        ImsPhoneCall backgroundCall = (ImsPhoneCall) getBackgroundCall();
+
+        if (ringingCall != null && foregroundCall != null && backgroundCall != null) {
+            //Array for IMS call session ID of RINGING/FOREGROUND/BACKGROUND call
+            String[] imsCallIds = new String[CallState.CALL_CLASSIFICATION_MAX];
+            //Array for IMS call service type of RINGING/FOREGROUND/BACKGROUND call
+            int[] imsCallServiceTypes = new int[CallState.CALL_CLASSIFICATION_MAX];
+            //Array for IMS call type of RINGING/FOREGROUND/BACKGROUND call
+            int[] imsCallTypes = new int[CallState.CALL_CLASSIFICATION_MAX];
+            imsCallIds[CallState.CALL_CLASSIFICATION_RINGING] =
+                    ringingCall.getCallSessionId();
+            imsCallIds[CallState.CALL_CLASSIFICATION_FOREGROUND] =
+                    foregroundCall.getCallSessionId();
+            imsCallIds[CallState.CALL_CLASSIFICATION_BACKGROUND] =
+                    backgroundCall.getCallSessionId();
+            imsCallServiceTypes[CallState.CALL_CLASSIFICATION_RINGING] =
+                    ringingCall.getServiceType();
+            imsCallServiceTypes[CallState.CALL_CLASSIFICATION_FOREGROUND] =
+                    foregroundCall.getServiceType();
+            imsCallServiceTypes[CallState.CALL_CLASSIFICATION_BACKGROUND] =
+                    backgroundCall.getServiceType();
+            imsCallTypes[CallState.CALL_CLASSIFICATION_RINGING] = ringingCall.getCallType();
+            imsCallTypes[CallState.CALL_CLASSIFICATION_FOREGROUND] =
+                    foregroundCall.getCallType();
+            imsCallTypes[CallState.CALL_CLASSIFICATION_BACKGROUND] =
+                    backgroundCall.getCallType();
+            mNotifier.notifyPreciseCallState(this, imsCallIds, imsCallServiceTypes, imsCallTypes);
+        }
     }
 
     public void notifyDisconnect(Connection cn) {
@@ -300,6 +342,11 @@
     }
 
     @Override
+    public int getImeiType() {
+        return Phone.IMEI_TYPE_UNKNOWN;
+    }
+
+    @Override
     public String getEsn() {
         Rlog.e(LOG_TAG, "[VoltePhone] getEsn() is a CDMA method");
         return "0";
@@ -530,4 +577,14 @@
             notifyPhoneStateChanged();
         }
     }
+
+    @Override
+    public int getTerminalBasedCallWaitingState(boolean forCsOnly) {
+        return getDefaultPhone().getTerminalBasedCallWaitingState(forCsOnly);
+    }
+
+    @Override
+    public void setTerminalBasedCallWaitingSupported(boolean supported) {
+        getDefaultPhone().setTerminalBasedCallWaitingSupported(supported);
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
index 98cc441..eaa6ab6 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
@@ -19,6 +19,8 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.telephony.DisconnectCause;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.util.Log;
 
@@ -327,6 +329,41 @@
         return (connection == null) ? null : connection.getImsCall();
     }
 
+    /**
+     * Retrieves the {@link ImsCallSession#getCallId()} for the current {@link ImsPhoneCall}.
+     */
+    @VisibleForTesting
+    public String getCallSessionId() {
+        return ((getImsCall() == null) ? null : getImsCall().getSession()) == null
+                ? null : getImsCall().getSession().getCallId();
+    }
+
+    /**
+     * Retrieves the service type in {@link ImsCallProfile} for the current {@link ImsPhoneCall}.
+     */
+    @VisibleForTesting
+    public int getServiceType() {
+        if (getFirstConnection() == null) {
+            return ImsCallProfile.SERVICE_TYPE_NONE;
+        } else {
+            return getFirstConnection().isEmergencyCall()
+                    ? ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
+        }
+    }
+
+    /**
+     * Retrieves the call type in {@link ImsCallProfile} for the current {@link ImsPhoneCall}.
+     */
+    @VisibleForTesting
+    public int getCallType() {
+        if (getImsCall() == null) {
+            return ImsCallProfile.CALL_TYPE_NONE;
+        } else {
+            return getImsCall().isVideoCall()
+                    ? ImsCallProfile.CALL_TYPE_VT : ImsCallProfile.CALL_TYPE_VOICE;
+        }
+    }
+
     /*package*/ static boolean isLocalTone(ImsCall imsCall) {
         if ((imsCall == null) || (imsCall.getCallProfile() == null)
                 || (imsCall.getCallProfile().mMediaProfile == null)) {
@@ -432,6 +469,15 @@
         return mIsRingbackTonePlaying;
     }
 
+    public void maybeClearRemotelyHeldStatus() {
+        for (Connection conn : getConnections()) {
+            ImsPhoneConnection c = (ImsPhoneConnection) conn;
+            if (c.isHeldByRemote()) {
+                c.setRemotelyUnheld();
+            }
+        }
+    }
+
     private void takeOver(ImsPhoneCall that) {
         copyConnectionFrom(that);
         mState = that.mState;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 895d09b..c3ee0f6 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -16,12 +16,32 @@
 
 package com.android.internal.telephony.imsphone;
 
+import static android.telephony.CarrierConfigManager.ImsVoice.ALERTING_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.BASIC_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.MIDCALL_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.PREALERTING_SRVCC_SUPPORT;
 import static android.telephony.CarrierConfigManager.USSD_OVER_CS_PREFERRED;
 import static android.telephony.CarrierConfigManager.USSD_OVER_IMS_ONLY;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ACTIVE;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ALERTING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_DIALING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_HOLDING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING_SETUP;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_WAITING;
+import static android.telephony.ims.ImsService.CAPABILITY_TERMINAL_BASED_CALL_WAITING;
+import static android.telephony.ims.feature.ConnectionFailureInfo.REASON_UNSPECIFIED;
+import static android.telephony.ims.feature.MmTelFeature.ImsTrafficSessionCallbackWrapper.INVALID_TOKEN;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.internal.telephony.CallWaitingController.TERMINAL_BASED_ACTIVATED;
+import static com.android.internal.telephony.CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_SMS;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_VIDEO;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_VOICE;
 import static com.android.internal.telephony.Phone.CS_FALLBACK;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.usage.NetworkStatsManager;
@@ -56,6 +76,7 @@
 import android.telecom.Connection.VideoProvider;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CallQuality;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
@@ -74,9 +95,16 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.ImsSuppServiceNotification;
+import android.telephony.ims.MediaQualityStatus;
+import android.telephony.ims.MediaThreshold;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.RtpHeaderExtension;
 import android.telephony.ims.RtpHeaderExtensionType;
+import android.telephony.ims.SrvccCall;
+import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.telephony.ims.aidl.IImsTrafficSessionCallback;
+import android.telephony.ims.aidl.ISrvccStartedCallback;
+import android.telephony.ims.feature.ConnectionFailureInfo;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -114,10 +142,12 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.SrvccConnection;
 import com.android.internal.telephony.d2d.RtpTransport;
 import com.android.internal.telephony.data.DataSettingsManager;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs;
 import com.android.internal.telephony.metrics.CallQualityMetrics;
@@ -133,8 +163,10 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -145,11 +177,14 @@
 import java.util.concurrent.CompletionException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * {@hide}
@@ -180,6 +215,20 @@
         SharedPreferences getDefaultSharedPreferences(Context context);
     }
 
+    private static class ImsTrafficSession {
+        private final @MmTelFeature.ImsTrafficType int mTrafficType;
+        private final @MmTelFeature.ImsTrafficDirection int mTrafficDirection;
+        private final @NonNull IImsTrafficSessionCallback mCallback;
+
+        ImsTrafficSession(@MmTelFeature.ImsTrafficType int trafficType,
+                @MmTelFeature.ImsTrafficDirection int trafficDirection,
+                @NonNull IImsTrafficSessionCallback callback) {
+            mTrafficType = trafficType;
+            mTrafficDirection = trafficDirection;
+            mCallback = callback;
+        }
+    }
+
     private static final boolean DBG = true;
 
     // When true, dumps the state of ImsPhoneCallTracker after changes to foreground and background
@@ -210,16 +259,18 @@
     private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener();
     private class MmTelFeatureListener extends MmTelFeature.Listener {
 
-        private void processIncomingCall(IImsCallSession c, Bundle extras) {
+        private IImsCallSessionListener processIncomingCall(@NonNull IImsCallSession c,
+                @Nullable String callId, @Nullable Bundle extras) {
             if (DBG) log("processIncomingCall: incoming call intent");
 
             if (extras == null) extras = new Bundle();
-            if (mImsManager == null) return;
+            if (mImsManager == null) return null;
 
             try {
+                IImsCallSessionListener iimsCallSessionListener;
                 // Network initiated USSD will be treated by mImsUssdListener
                 boolean isUssd = extras.getBoolean(MmTelFeature.EXTRA_IS_USSD, false);
-                // For compatibility purposes with older vendor implmentations.
+                // For compatibility purposes with older vendor implementations.
                 isUssd |= extras.getBoolean(ImsManager.EXTRA_USSD, false);
                 if (isUssd) {
                     if (DBG) log("processIncomingCall: USSD");
@@ -228,11 +279,14 @@
                     if (mUssdSession != null) {
                         mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
                     }
-                    return;
+                    if (callId != null) mUssdSession.getCallSession().setCallId(callId);
+                    iimsCallSessionListener = (IImsCallSessionListener) mUssdSession
+                            .getCallSession().getIImsCallSessionListenerProxy();
+                    return iimsCallSessionListener;
                 }
 
                 boolean isUnknown = extras.getBoolean(MmTelFeature.EXTRA_IS_UNKNOWN_CALL, false);
-                // For compatibility purposes with older vendor implmentations.
+                // For compatibility purposes with older vendor implementations.
                 isUnknown |= extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false);
                 if (DBG) {
                     log("processIncomingCall: isUnknown = " + isUnknown
@@ -242,6 +296,9 @@
 
                 // Normal MT/Unknown call
                 ImsCall imsCall = mImsManager.takeCall(c, mImsCallListener);
+                if (callId != null) imsCall.getCallSession().setCallId(callId);
+                iimsCallSessionListener = (IImsCallSessionListener) imsCall
+                        .getCallSession().getIImsCallSessionListenerProxy();
                 ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall,
                         ImsPhoneCallTracker.this,
                         (isUnknown ? mForegroundCall : mRingingCall), isUnknown);
@@ -264,13 +321,13 @@
                 if ((c != null) && (c.getCallProfile() != null)
                         && (c.getCallProfile().getCallExtras() != null)
                         && (c.getCallProfile().getCallExtras()
-                          .containsKey(ImsCallProfile.EXTRA_CALL_DISCONNECT_CAUSE))) {
+                        .containsKey(ImsCallProfile.EXTRA_CALL_DISCONNECT_CAUSE))) {
                     String error = c.getCallProfile()
                             .getCallExtra(ImsCallProfile.EXTRA_CALL_DISCONNECT_CAUSE, null);
                     if (error != null) {
                         try {
                             int cause = getDisconnectCauseFromReasonInfo(
-                                        new ImsReasonInfo(Integer.parseInt(error), 0, null),
+                                    new ImsReasonInfo(Integer.parseInt(error), 0, null),
                                     conn.getState());
                             if (cause == DisconnectCause.INCOMING_AUTO_REJECTED) {
                                 conn.setDisconnectCause(cause);
@@ -315,18 +372,20 @@
 
                 updatePhoneState();
                 mPhone.notifyPreciseCallStateChanged();
+                mImsCallInfoTracker.addImsCallStatus(conn);
+                return iimsCallSessionListener;
             } catch (ImsException | RemoteException e) {
                 loge("processIncomingCall: exception " + e);
                 mOperationLocalLog.log("onIncomingCall: exception processing: "  + e);
+                return null;
             }
         }
 
         @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));
+        @Nullable
+        public IImsCallSessionListener onIncomingCall(
+                @NonNull IImsCallSession c, @Nullable String callId, @Nullable Bundle extras) {
+            return executeAndWaitForReturn(()-> processIncomingCall(c, callId, extras));
         }
 
         @Override
@@ -341,6 +400,102 @@
             }, mExecutor);
         }
 
+        @Override
+        public void onAudioModeIsVoipChanged(int imsAudioHandler) {
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                ImsCall imsCall = null;
+                if (mForegroundCall.hasConnections()) {
+                    imsCall = mForegroundCall.getImsCall();
+                } else if (mBackgroundCall.hasConnections()) {
+                    imsCall = mBackgroundCall.getImsCall();
+                } else if (mRingingCall.hasConnections()) {
+                    imsCall = mRingingCall.getImsCall();
+                } else if (mHandoverCall.hasConnections()) {
+                    imsCall = mHandoverCall.getImsCall();
+                } else {
+                    Rlog.e(LOG_TAG, "onAudioModeIsVoipChanged: no Call");
+                }
+
+                if (imsCall != null) {
+                    ImsPhoneConnection conn = findConnection(imsCall);
+                    if (conn != null) {
+                        conn.onAudioModeIsVoipChanged(imsAudioHandler);
+                    }
+                } else {
+                    Rlog.e(LOG_TAG, "onAudioModeIsVoipChanged: no ImsCall");
+                }
+            }, mExecutor);
+        }
+
+        @Override
+        public void onTriggerEpsFallback(@MmTelFeature.EpsFallbackReason int reason) {
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                if (DBG) log("onTriggerEpsFallback reason=" + reason);
+                mPhone.triggerEpsFallback(reason, null);
+            }, mExecutor);
+        }
+
+        @Override
+        public void onStartImsTrafficSession(int token,
+                @MmTelFeature.ImsTrafficType int trafficType,
+                @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType,
+                @MmTelFeature.ImsTrafficDirection int trafficDirection,
+                IImsTrafficSessionCallback callback) {
+            registerImsTrafficSession(token, trafficType, trafficDirection, callback);
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                if (DBG) {
+                    log("onStartImsTrafficSession token=" + token + ", traffic=" + trafficType
+                            + ", networkType=" + accessNetworkType
+                            + ", direction=" + trafficDirection);
+                }
+                mPhone.startImsTraffic(token, trafficType, accessNetworkType, trafficDirection,
+                        obtainMessage(EVENT_START_IMS_TRAFFIC_DONE, callback));
+            }, mExecutor);
+        }
+
+        @Override
+        public void onModifyImsTrafficSession(int token,
+                @AccessNetworkConstants.RadioAccessNetworkType int accessNetworkType) {
+            ImsTrafficSession session = getImsTrafficSession(token);
+            if (session == null) {
+                loge("onModifyImsTrafficSession unknown session, token=" + token);
+                return;
+            }
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                if (DBG) {
+                    log("onModifyImsTrafficSession token=" + token
+                            + ", networkType=" + accessNetworkType);
+                }
+                mPhone.startImsTraffic(token, session.mTrafficType,
+                        accessNetworkType, session.mTrafficDirection,
+                        obtainMessage(EVENT_START_IMS_TRAFFIC_DONE, session.mCallback));
+            }, mExecutor);
+        }
+
+        @Override
+        public void onStopImsTrafficSession(int token) {
+            unregisterImsTrafficSession(token);
+            if (token == INVALID_TOKEN) return;
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                if (DBG) {
+                    log("onStopImsTrafficSession token=" + token);
+                }
+                mPhone.stopImsTraffic(token, null);
+            }, mExecutor);
+        }
+
+        @Override
+        public void onMediaQualityStatusChanged(MediaQualityStatus status) {
+            TelephonyUtils.runWithCleanCallingIdentity(()-> {
+                if (mPhone != null && mPhone.mDefaultPhone != null) {
+                    if (DBG) log("onMediaQualityStatusChanged " + status);
+                    mPhone.onMediaQualityStatusChanged(status);
+                } else {
+                    loge("onMediaQualityStatusChanged: null phone");
+                }
+            }, mExecutor);
+        }
+
         /**
          * Schedule the given Runnable on mExecutor and block this thread until it finishes.
          * @param r The Runnable to run.
@@ -353,6 +508,24 @@
                 logw("Binder - exception: " + e.getMessage());
             }
         }
+
+        /**
+         * Schedule the given Runnable on mExecutor and block this thread until it finishes.
+         * @param r The Runnable to run.
+         */
+        private <T> T executeAndWaitForReturn(Supplier<T> r) {
+
+            CompletableFuture<T> future = CompletableFuture.supplyAsync(
+                    () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
+
+            try {
+                return future.get();
+            } catch (ExecutionException | InterruptedException e) {
+                Log.w(LOG_TAG, "ImsPhoneCallTracker : executeAndWaitForReturn exception: "
+                        + e.getMessage());
+                return null;
+            }
+        }
     }
 
     /**
@@ -397,31 +570,35 @@
         }
     }
 
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            new CarrierConfigManager.CarrierConfigChangeListener() {
+                @Override
+                public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
+                        int specificCarrierId) {
+                    if (mPhone.getPhoneId() != slotIndex) {
+                        log("onReceive: Skipping indication for other phoneId: " + slotIndex);
+                        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);
+                    }
+                }
+            };
+
     private final 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,
-                        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);
-                }
-            } else if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
+            if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
                 mDefaultDialerUid.set(getPackageUid(context, intent.getStringExtra(
                         TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME)));
             }
@@ -484,6 +661,9 @@
     private static final int EVENT_ANSWER_WAITING_CALL = 30;
     private static final int EVENT_RESUME_NOW_FOREGROUND_CALL = 31;
     private static final int EVENT_REDIAL_WITHOUT_RTT = 32;
+    private static final int EVENT_START_IMS_TRAFFIC_DONE = 33;
+    private static final int EVENT_CONNECTION_SETUP_FAILURE = 34;
+    private static final int EVENT_NEW_ACTIVE_CALL_STARTED = 35;
 
     private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
 
@@ -555,6 +735,13 @@
         }
     }
 
+    private class SrvccStartedCallback extends ISrvccStartedCallback.Stub {
+        @Override
+        public void onSrvccCallNotified(List<SrvccCall> profiles) {
+            handleSrvccConnectionInfo(profiles);
+        }
+    }
+
     private volatile NetworkStats mVtDataUsageSnapshot = null;
     private volatile NetworkStats mVtDataUsageUidSnapshot = null;
     private final VtDataUsageProvider mVtDataUsageProvider = new VtDataUsageProvider();
@@ -609,14 +796,22 @@
     private boolean mSupportCepOnPeer = true;
     private boolean mSupportD2DUsingRtp = false;
     private boolean mSupportSdpForRtpHeaderExtensions = false;
+    private int mThresholdRtpPacketLoss;
+    private int mThresholdRtpJitter;
+    private long mThresholdRtpInactivityTime;
+    private final List<Integer> mSrvccTypeSupported = new ArrayList<>();
+    private final SrvccStartedCallback mSrvccStartedCallback = new SrvccStartedCallback();
     // Tracks the state of our background/foreground calls while a call hold/swap operation is
     // in progress. Values listed above.
     private HoldSwapState mHoldSwitchingState = HoldSwapState.INACTIVE;
+    private MediaThreshold mMediaThreshold;
 
     private String mLastDialString = null;
     private ImsDialArgs mLastDialArgs = null;
     private Executor mExecutor = Runnable::run;
 
+    private final ImsCallInfoTracker mImsCallInfoTracker;
+
     /**
      * Listeners to changes in the phone state.  Intended for use by other interested IMS components
      * without the need to register a full blown {@link android.telephony.PhoneStateListener}.
@@ -988,6 +1183,9 @@
     // Used for important operational related events for logging.
     private final LocalLog mOperationLocalLog = new LocalLog(64);
 
+    private final ConcurrentHashMap<Integer, ImsTrafficSession> mImsTrafficSessions =
+            new ConcurrentHashMap<>();
+
     /**
      * Container to ease passing around a tuple of two objects. This object provides a sensible
      * implementation of equals(), returning true/false using equals() for one object (Integer)
@@ -1036,6 +1234,7 @@
             return (first == null ? 0 : first.hashCode());
         }
     }
+
     //***** Events
 
 
@@ -1055,10 +1254,20 @@
         mMetrics = TelephonyMetrics.getInstance();
 
         IntentFilter intentfilter = new IntentFilter();
-        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()));
+
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        // Callback of listener directly access global states which are limited on main thread.
+        // The callback can only be executed on main thread.
+        if (ccm != null) {
+            ccm.registerCarrierConfigChangeListener(
+                    mPhone.getContext().getMainExecutor(), mCarrierConfigChangeListener);
+            updateCarrierConfiguration(
+                    mPhone.getSubId(), getCarrierConfigBundle(mPhone.getSubId()));
+        } else {
+            loge("CarrierConfigManager is not available.");
+        }
 
         mSettingsCallback = new DataSettingsManager.DataSettingsManagerCallback(this::post) {
                 @Override
@@ -1097,10 +1306,15 @@
                             postDelayed(mConnectorRunnable, CONNECTOR_RETRY_DELAY_MS);
                         }
                         stopListeningForCalls();
+                        stopAllImsTrafficTypes();
                     }
                 }, executor);
         // It can take some time for ITelephony to get published, so defer connecting.
         post(mConnectorRunnable);
+
+        mImsCallInfoTracker = new ImsCallInfoTracker(phone);
+
+        mPhone.registerForConnectionSetupFailure(this, EVENT_CONNECTION_SETUP_FAILURE, null);
     }
 
     /**
@@ -1177,6 +1391,8 @@
         // For compatibility with apps that still use deprecated intent
         sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_UP);
         mCurrentlyConnectedSubId = Optional.of(subId);
+
+        initializeTerminalBasedCallWaiting();
     }
 
     /**
@@ -1237,6 +1453,7 @@
             mUtInterface = null;
         }
         mCurrentlyConnectedSubId = Optional.empty();
+        mMediaThreshold = null;
         resetImsCapabilities();
         hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
         // For compatibility with apps that still use deprecated intent
@@ -1277,6 +1494,7 @@
         // above. Remove all references to it.
         mPendingMO = null;
         updatePhoneState();
+        mImsCallInfoTracker.clearAllOrphanedConnections();
     }
 
     /**
@@ -1310,6 +1528,10 @@
 
         clearDisconnected();
         mPhone.getContext().unregisterReceiver(mReceiver);
+        CarrierConfigManager ccm = mPhone.getContext().getSystemService(CarrierConfigManager.class);
+        if (ccm != null && mCarrierConfigChangeListener != null) {
+            ccm.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+        }
         mPhone.getDefaultPhone().getDataSettingsManager().unregisterCallback(mSettingsCallback);
         mImsManagerConnector.disconnect();
 
@@ -1317,6 +1539,8 @@
                 (NetworkStatsManager) mPhone.getContext().getSystemService(
                         Context.NETWORK_STATS_SERVICE);
         statsManager.unregisterNetworkStatsProvider(mVtDataUsageProvider);
+
+        mPhone.unregisterForConnectionSetupFailure(this);
     }
 
     @Override
@@ -1508,7 +1732,7 @@
             mLastDialString = dialString;
             mLastDialArgs = dialArgs;
             mPendingMO = new ImsPhoneConnection(mPhone, dialString, this, mForegroundCall,
-                    isEmergencyNumber, isWpsCall);
+                    isEmergencyNumber, isWpsCall, dialArgs);
             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(
@@ -1525,9 +1749,22 @@
         addConnection(mPendingMO);
 
         if (!holdBeforeDial) {
+            // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
             if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
                 dialInternal(mPendingMO, clirMode, videoState, dialArgs.retryCallFailCause,
                         dialArgs.retryCallFailNetworkType, dialArgs.intentExtras);
+            } else if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                final int finalClirMode = clirMode;
+                final int finalVideoState = videoState;
+                Runnable onComplete = new Runnable() {
+                    @Override
+                    public void run() {
+                        dialInternal(mPendingMO, finalClirMode, finalVideoState,
+                                dialArgs.retryCallFailCause, dialArgs.retryCallFailNetworkType,
+                                dialArgs.intentExtras);
+                    }
+                };
+                EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete);
             } else {
                 try {
                     getEcbmInterface().exitEmergencyCallbackMode();
@@ -1619,20 +1856,12 @@
         // Check for changes due to carrier config.
         maybeConfigureRtpHeaderExtensions();
 
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo == null || !subInfo.isActive()) {
-                loge("updateCarrierConfiguration: skipping notification to ImsService, non"
-                        + "active subId = " + subId);
-                return;
-            }
-        } else {
-            if (!SubscriptionController.getInstance().isActiveSubId(subId)) {
-                loge("updateCarrierConfiguration: skipping notification to ImsService, non"
-                        + "active subId = " + subId);
-                return;
-            }
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo == null || !subInfo.isActive()) {
+            loge("updateCarrierConfiguration: skipping notification to ImsService, non"
+                    + "active subId = " + subId);
+            return;
         }
 
         Phone defaultPhone = getPhone().getDefaultPhone();
@@ -1659,6 +1888,8 @@
         logi("updateCarrierConfiguration: Updating ImsService configs.");
         mCarrierConfigLoadedForSubscription = true;
         updateImsServiceConfig();
+        updateMediaThreshold(
+                mThresholdRtpPacketLoss, mThresholdRtpJitter, mThresholdRtpInactivityTime);
     }
 
     /**
@@ -1707,6 +1938,13 @@
         mSupportSdpForRtpHeaderExtensions = carrierConfig.getBoolean(
                 CarrierConfigManager
                         .KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL);
+        mThresholdRtpPacketLoss = carrierConfig.getInt(
+                CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_PACKET_LOSS_RATE_THRESHOLD_INT);
+        mThresholdRtpInactivityTime = carrierConfig.getLong(
+                CarrierConfigManager.ImsVoice
+                        .KEY_VOICE_RTP_INACTIVITY_TIME_THRESHOLD_MILLIS_LONG);
+        mThresholdRtpJitter = carrierConfig.getInt(
+                CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_JITTER_THRESHOLD_MILLIS_INT);
 
         if (mPhone.getContext().getResources().getBoolean(
                 com.android.internal.R.bool.config_allow_ussd_over_ims)) {
@@ -1753,6 +1991,41 @@
         } else {
             log("No carrier ImsReasonInfo mappings defined.");
         }
+
+        mSrvccTypeSupported.clear();
+        int[] srvccType =
+                carrierConfig.getIntArray(CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY);
+        if (srvccType != null && srvccType.length > 0) {
+            mSrvccTypeSupported.addAll(
+                    Arrays.stream(srvccType).boxed().collect(Collectors.toList()));
+        }
+    }
+
+    private void updateMediaThreshold(
+            int thresholdPacketLoss, int thresholdJitter, long thresholdInactivityTime) {
+        if (!MediaThreshold.isValidRtpInactivityTimeMillis(thresholdInactivityTime)
+                && !MediaThreshold.isValidJitterMillis(thresholdJitter)
+                && !MediaThreshold.isValidRtpPacketLossRate(thresholdPacketLoss)) {
+            logi("There is no valid RTP threshold value");
+            return;
+        }
+        int[] thPacketLosses = {thresholdPacketLoss};
+        long[] thInactivityTimesMillis = {thresholdInactivityTime};
+        int[] thJitters = {thresholdJitter};
+        MediaThreshold threshold = new MediaThreshold.Builder()
+                .setThresholdsRtpPacketLossRate(thPacketLosses)
+                .setThresholdsRtpInactivityTimeMillis(thInactivityTimesMillis)
+                .setThresholdsRtpJitterMillis(thJitters).build();
+        if (mMediaThreshold == null || !mMediaThreshold.equals(threshold)) {
+            logi("setMediaThreshold :" + threshold);
+            try {
+                mImsManager.setMediaThreshold(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO,
+                        threshold);
+                mMediaThreshold = threshold;
+            } catch (ImsException e) {
+                loge("setMediaThreshold Failed: " + e);
+            }
+        }
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1855,6 +2128,11 @@
                     conn.setPulledDialogId(dialogId);
                 }
 
+                if (intentExtras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE)) {
+                    logi("dialInternal containing EXTRA_CALL_RAT_TYPE, "
+                            +  intentExtras.getString(ImsCallProfile.EXTRA_CALL_RAT_TYPE));
+                }
+
                 // Pack the OEM-specific call extras.
                 profile.mCallExtras.putBundle(ImsCallProfile.EXTRA_OEM_EXTRAS, intentExtras);
 
@@ -1876,6 +2154,7 @@
             setVideoCallProvider(conn, imsCall);
             conn.setAllowAddCallDuringVideoCall(mAllowAddCallDuringVideoCall);
             conn.setAllowHoldingVideoCall(mAllowHoldingVideoCall);
+            mImsCallInfoTracker.addImsCallStatus(conn);
         } catch (ImsException e) {
             loge("dialInternal : " + e);
             mOperationLocalLog.log("dialInternal exception: " + e);
@@ -2597,6 +2876,7 @@
                 + System.identityHashCode(conn));
 
         call.onHangupLocal();
+        mImsCallInfoTracker.updateImsCallStatus(conn);
 
         try {
             if (imsCall != null) {
@@ -2797,14 +3077,26 @@
             conn.maybeChangeRingbackState();
 
             maybeSetVideoCallProvider(conn, imsCall);
+            // IMS call profile might be changed while call state is maintained. In this case, it's
+            // required to notify to CallAttributesListener.
+            // Since call state is not changed, TelephonyRegistry will not notify to
+            // PreciseCallStateListener.
+            mPhone.notifyPreciseCallStateToNotifier();
             return;
         }
 
         // Do not log operations that do not change the state
         mOperationLocalLog.log("processCallStateChange: state=" + state + " cause=" + cause
                 + " connId=" + System.identityHashCode(conn));
-
+        boolean noActiveCall = false;
+        if (mForegroundCall.getState() != ImsPhoneCall.State.ACTIVE
+                && mBackgroundCall.getState() != ImsPhoneCall.State.ACTIVE) {
+            noActiveCall = true;
+        }
         changed = conn.update(imsCall, state);
+        if (noActiveCall && changed && state == ImsPhoneCall.State.ACTIVE) {
+            sendMessage(obtainMessage(EVENT_NEW_ACTIVE_CALL_STARTED));
+        }
         if (state == ImsPhoneCall.State.DISCONNECTED) {
             changed = conn.onDisconnect(cause) || changed;
             //detach the disconnected connections
@@ -2834,6 +3126,7 @@
         }
 
         if (changed) {
+            mImsCallInfoTracker.updateImsCallStatus(conn);
             if (conn.getCall() == mHandoverCall) return;
             updatePhoneState();
             mPhone.notifyPreciseCallStateChanged();
@@ -2865,7 +3158,7 @@
     @VisibleForTesting
     public void addReasonCodeRemapping(Integer fromCode, String message, Integer toCode) {
         if (message != null) {
-            message = message.toLowerCase();
+            message = message.toLowerCase(Locale.ROOT);
         }
         mImsReasonCodeMap.put(new ImsReasonInfoKeyPair(fromCode, message), toCode);
     }
@@ -2886,7 +3179,7 @@
         if (reason == null) {
             reason = "";
         } else {
-            reason = reason.toLowerCase();
+            reason = reason.toLowerCase(Locale.ROOT);
         }
         log("maybeRemapReasonCode : fromCode = " + reasonInfo.getCode() + " ; message = "
                 + reason);
@@ -3096,6 +3389,13 @@
                 break;
 
             case ImsReasonInfo.CODE_SIP_BAD_REQUEST:
+                // Auto-missed/rejected calls can sometimes use this reason cause, but if we see it
+                // for outgoing calls it is just a server error.
+                if (callState == Call.State.DIALING || callState == Call.State.ALERTING) {
+                    return DisconnectCause.SERVER_ERROR;
+                } else {
+                    return DisconnectCause.INCOMING_AUTO_REJECTED;
+                }
             case ImsReasonInfo.CODE_REJECT_CALL_ON_OTHER_SUB:
             case ImsReasonInfo.CODE_REJECT_ONGOING_E911_CALL:
             case ImsReasonInfo.CODE_REJECT_ONGOING_CALL_SETUP:
@@ -3248,6 +3548,28 @@
                                     reasonInfo.mExtraCode,
                                     reasonInfo.mExtraMessage));
 
+            if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                ImsPhoneConnection conn = findConnection(imsCall);
+                // Since onCallInitiating and onCallProgressing reset mPendingMO,
+                // we can't depend on mPendingMO.
+                if ((reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL
+                        || reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED
+                        || reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED)
+                        && conn != null) {
+                    logi("onCallStartFailed eccCategory=" + eccCategory);
+                    if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL
+                            || reasonInfo.getExtraCode()
+                                    == ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY) {
+                        conn.setNonDetectableEmergencyCallInfo(eccCategory);
+                    }
+                    conn.setImsReasonInfo(reasonInfo);
+                    sendCallStartFailedDisconnect(imsCall, reasonInfo);
+                    mMetrics.writeOnImsCallStartFailed(mPhone.getPhoneId(),
+                            imsCall.getCallSession(), reasonInfo);
+                    return;
+                }
+            }
+
             if (mPendingMO != null) {
                 // To initiate dialing circuit-switched call
                 if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
@@ -3255,6 +3577,7 @@
                         && isForegroundHigherPriority()) {
                     mForegroundCall.detach(mPendingMO);
                     removeConnection(mPendingMO);
+                    mImsCallInfoTracker.updateImsCallStatus(mPendingMO);
                     mPendingMO.finalize();
                     mPendingMO = null;
                     // if we need to perform CSFB of call, hang up any background call
@@ -3286,6 +3609,7 @@
                 if (conn != null) {
                     mForegroundCall.detach(conn);
                     removeConnection(conn);
+                    mImsCallInfoTracker.updateImsCallStatus(conn);
                 }
                 updatePhoneState();
                 mPhone.initiateSilentRedial(reasonInfo.getExtraCode() ==
@@ -3375,6 +3699,12 @@
                 cause = DisconnectCause.IMS_MERGED_SUCCESSFULLY;
             }
 
+            // Ensure the background call is correctly marked as MERGE_COMPLETE before it is
+            // disconnected as part of the IMS merge conference process:
+            if (cause == DisconnectCause.IMS_MERGED_SUCCESSFULLY && conn != null) {
+                conn.onConnectionEvent(android.telecom.Connection.EVENT_MERGE_COMPLETE, null);
+            }
+
             EmergencyNumberTracker emergencyNumberTracker = null;
             EmergencyNumber num = null;
 
@@ -3405,6 +3735,18 @@
             }
 
             if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL
+                    && DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                if (conn != null) {
+                    int eccCategory = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+                    if (imsCall != null && imsCall.getCallProfile() != null) {
+                        eccCategory = imsCall.getCallProfile().getEmergencyServiceCategories();
+                        logi("onCallTerminated eccCategory=" + eccCategory);
+                    }
+                    conn.setNonDetectableEmergencyCallInfo(eccCategory);
+                }
+                processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
+                return;
+            } else if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL
                     && mAutoRetryFailedWifiEmergencyCall) {
                 Pair<ImsCall, ImsReasonInfo> callInfo = new Pair<>(imsCall, reasonInfo);
                 mPhone.getDefaultPhone().mCi.registerForOn(ImsPhoneCallTracker.this,
@@ -3704,7 +4046,8 @@
                     mPhone.stopOnHoldTone(conn);
                     mOnHoldToneStarted = false;
                 }
-                conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_UNHELD, null);
+                conn.setRemotelyUnheld();
+                mImsCallInfoTracker.updateImsCallStatus(conn, false, true);
             }
 
             boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean(
@@ -4114,6 +4457,28 @@
                 conn.receivedRtpHeaderExtensions(rtpHeaderExtensionData);
             }
         }
+
+        /**
+         * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+         * This API triggers radio to send ANBRQ message to the access network to query the desired
+         * bitrate.
+         *
+         * @param imsCall The ImsCall the data was received on.
+         * @param mediaType MediaType is used to identify media stream such as audio or video.
+         * @param direction Direction of this packet stream (e.g. uplink or downlink).
+         * @param bitsPerSecond This value is the bitrate requested by the other party UE through
+         *        RTP CMR, RTCPAPP or TMMBR, and ImsStack converts this value to the MAC bitrate
+         *        (defined in TS36.321, range: 0 ~ 8000 kbit/s).
+         */
+        @Override
+        public void onCallSessionSendAnbrQuery(ImsCall imsCall, int mediaType, int direction,
+                int bitsPerSecond) {
+            if (DBG) {
+                log("onCallSessionSendAnbrQuery mediaType=" + mediaType + ", direction="
+                    + direction + ", bitPerSecond=" + bitsPerSecond);
+            }
+            handleSendAnbrQuery(mediaType, direction, bitsPerSecond);
+        }
     };
 
     /**
@@ -4251,7 +4616,8 @@
             configChangedIntent.putExtra(ImsConfig.EXTRA_CHANGED_ITEM, item);
             configChangedIntent.putExtra(ImsConfig.EXTRA_NEW_VALUE, value);
             if (mPhone != null && mPhone.getContext() != null) {
-                mPhone.getContext().sendBroadcast(configChangedIntent);
+                mPhone.getContext().sendBroadcast(
+                        configChangedIntent, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
             }
         }
     };
@@ -4331,21 +4697,58 @@
      * Notify of a change to SRVCC state
      * @param state the new SRVCC state.
      */
-    public void notifySrvccState(Call.SrvccState state) {
+    public void notifySrvccState(int state) {
         if (DBG) log("notifySrvccState state=" + state);
 
-        mSrvccState = state;
+        if (mImsManager != null) {
+            try {
+                if (state == TelephonyManager.SRVCC_STATE_HANDOVER_STARTED) {
+                    mImsManager.notifySrvccStarted(mSrvccStartedCallback);
+                } else if (state == TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED) {
+                    mImsManager.notifySrvccCompleted();
+                } else if (state == TelephonyManager.SRVCC_STATE_HANDOVER_FAILED) {
+                    mImsManager.notifySrvccFailed();
+                } else if (state == TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED) {
+                    mImsManager.notifySrvccCanceled();
+                }
+            } catch (ImsException e) {
+                loge("notifySrvccState : exception " + e);
+            }
+        }
 
-        if (mSrvccState == Call.SrvccState.COMPLETED) {
-            // If the dialing call had ringback, ensure it stops now, otherwise it'll keep playing
-            // afer the SRVCC completes.
-            mForegroundCall.maybeStopRingback();
+        switch(state) {
+            case TelephonyManager.SRVCC_STATE_HANDOVER_STARTED:
+                mSrvccState = Call.SrvccState.STARTED;
+                break;
 
-            resetState();
-            transferHandoverConnections(mForegroundCall);
-            transferHandoverConnections(mBackgroundCall);
-            transferHandoverConnections(mRingingCall);
-            updatePhoneState();
+            case TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED:
+                mSrvccState = Call.SrvccState.COMPLETED;
+
+                // If the dialing call had ringback, ensure it stops now,
+                // otherwise it'll keep playing afer the SRVCC completes.
+                mForegroundCall.maybeStopRingback();
+                mForegroundCall.maybeClearRemotelyHeldStatus();
+                mBackgroundCall.maybeClearRemotelyHeldStatus();
+
+                resetState();
+                transferHandoverConnections(mForegroundCall);
+                transferHandoverConnections(mBackgroundCall);
+                transferHandoverConnections(mRingingCall);
+                updatePhoneState();
+                mImsCallInfoTracker.notifySrvccCompleted();
+                break;
+
+            case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
+                mSrvccState = Call.SrvccState.FAILED;
+                break;
+
+            case TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED:
+                mSrvccState = Call.SrvccState.CANCELED;
+                break;
+
+            default:
+                //ignore invalid state
+                return;
         }
     }
 
@@ -4476,6 +4879,7 @@
                 try {
                     ImsFeature.Capabilities capabilities = (ImsFeature.Capabilities) args.arg1;
                     handleFeatureCapabilityChanged(capabilities);
+                    updateImsRegistrationInfo();
                 } finally {
                     args.recycle();
                 }
@@ -4558,6 +4962,55 @@
                 }
                 break;
             }
+
+            case EVENT_START_IMS_TRAFFIC_DONE: // fallthrough
+            case EVENT_CONNECTION_SETUP_FAILURE: {
+                ar = (AsyncResult) msg.obj;
+                // Not-null with EVENT_START_IMS_TRAFFIC_DONE
+                IImsTrafficSessionCallback callback = (IImsTrafficSessionCallback) ar.userObj;
+                try {
+                    if (ar.exception == null) {
+                        Object[] result = (Object[]) ar.result;
+                        if (result != null && result.length > 1) {
+                            if (callback == null) {
+                                //EVENT_CONNECTION_SETUP_FAILURE
+                                ImsTrafficSession session =
+                                        getImsTrafficSession((int) result[0]);
+                                if (session != null) callback = session.mCallback;
+                            }
+                            if (callback == null) break;
+
+                            if (result[1] == null) callback.onReady();
+                            else callback.onError((ConnectionFailureInfo) result[1]);
+                            break;
+                        }
+                    }
+                    if (callback != null) {
+                        callback.onError(new ConnectionFailureInfo(REASON_UNSPECIFIED, 0, -1));
+                    }
+                } catch (RemoteException e) {
+                    Rlog.e(LOG_TAG, "Exception: " + e);
+                }
+                break;
+            }
+
+            case EVENT_NEW_ACTIVE_CALL_STARTED: {
+                try {
+                    MediaQualityStatus status = mImsManager
+                            .queryMediaQualityStatus(MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO);
+                    if (status != null) {
+                        if (mPhone != null && mPhone.mDefaultPhone != null) {
+                            if (DBG) log("notify media quality status: " + status);
+                            mPhone.onMediaQualityStatusChanged(status);
+                        } else {
+                            loge("onMediaQualityStatusChanged: null phone");
+                        }
+                    }
+                } catch (ImsException e) {
+                    Rlog.e(LOG_TAG, "Exception in queryMediaQualityStatus: " + e);
+                }
+                break;
+            }
         }
     }
 
@@ -4732,6 +5185,7 @@
                         + mSupportSdpForRtpHeaderExtensions);
             }
         }
+        pw.println(" mSrvccTypeSupported=" + mSrvccTypeSupported);
         pw.println(" Event Log:");
         pw.increaseIndent();
         mOperationLocalLog.dump(pw);
@@ -5375,7 +5829,8 @@
                 mOnHoldToneStarted = true;
                 mOnHoldToneId = System.identityHashCode(conn);
             }
-            conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null);
+            conn.setRemotelyHeld();
+            mImsCallInfoTracker.updateImsCallStatus(conn, true, false);
 
             boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_useVideoPauseWorkaround);
@@ -5503,4 +5958,256 @@
         }
         return false;
     }
+
+    private void initializeTerminalBasedCallWaiting() {
+        boolean capable = false;
+        if (mImsManager != null) {
+            try {
+                capable = mImsManager.isCapable(CAPABILITY_TERMINAL_BASED_CALL_WAITING);
+            } catch (ImsException e) {
+                loge("initializeTerminalBasedCallWaiting : exception " + e);
+            }
+        }
+        logi("initializeTerminalBasedCallWaiting capable=" + capable);
+        mPhone.setTerminalBasedCallWaitingSupported(capable);
+
+        if (capable) {
+            setTerminalBasedCallWaitingStatus(mPhone.getTerminalBasedCallWaitingState(false));
+        }
+    }
+
+    /**
+     * Notifies the change of the user setting of the terminal-based call waiting service
+     * to IMS service.
+     */
+    public void setTerminalBasedCallWaitingStatus(int state) {
+        if (state == TERMINAL_BASED_NOT_SUPPORTED) return;
+        if (mImsManager != null) {
+            try {
+                log("setTerminalBasedCallWaitingStatus state=" + state);
+                mImsManager.setTerminalBasedCallWaitingStatus(
+                        state == TERMINAL_BASED_ACTIVATED);
+            } catch (ImsException e) {
+                loge("setTerminalBasedCallWaitingStatus : exception " + e);
+            }
+        }
+    }
+
+    /** Send the list of SrvccConnection instances to the radio */
+    public void handleSrvccConnectionInfo(List<SrvccCall> profileList) {
+        mPhone.getDefaultPhone().mCi.setSrvccCallInfo(
+                convertToSrvccConnectionInfo(profileList), null);
+    }
+
+    /** Converts SrvccCall to SrvccConnection. */
+    @VisibleForTesting
+    public SrvccConnection[] convertToSrvccConnectionInfo(List<SrvccCall> profileList) {
+        if (mSrvccTypeSupported.isEmpty() || profileList == null || profileList.isEmpty()) {
+            loge("convertToSrvccConnectionInfo empty list");
+            return null;
+        }
+
+        List<SrvccConnection> connList = new ArrayList<>();
+        for (SrvccCall profile : profileList) {
+            if (isCallProfileSupported(profile)) {
+                addConnection(connList,
+                        profile, findConnection(profile.getCallId()));
+            } else {
+                logi("convertToSrvccConnectionInfo not supported"
+                        + " state=" + profile.getPreciseCallState());
+            }
+        }
+
+        logi("convertToSrvccConnectionInfo size=" + connList.size());
+        if (connList.isEmpty()) return null;
+        return connList.toArray(new SrvccConnection[0]);
+    }
+
+    /** Send the mediaType, direction, bitrate for ANBR Query to the radio */
+    public void handleSendAnbrQuery(int mediaType, int direction, int bitsPerSecond) {
+        if (DBG) log("handleSendAnbrQuery - mediaType=" + mediaType);
+        mPhone.getDefaultPhone().mCi.sendAnbrQuery(mediaType, direction, bitsPerSecond, null);
+    }
+
+
+    /**
+     * Notifies the recommended bit rate for the indicated logical channel and direction.
+     *
+     * @param mediaType MediaType is used to identify media stream such as audio or video.
+     * @param direction Direction of this packet stream (e.g. uplink or downlink).
+     * @param bitsPerSecond The recommended bit rate for the UE for a specific logical channel and
+     *        a specific direction by NW.
+     */
+    public void triggerNotifyAnbr(int mediaType, int direction, int bitsPerSecond) {
+        ImsCall activeCall = mForegroundCall.getFirstConnection().getImsCall();
+
+        if (activeCall != null) {
+            if (DBG) log("triggerNotifyAnbr - mediaType=" + mediaType);
+            activeCall.callSessionNotifyAnbr(mediaType, direction, bitsPerSecond);
+        }
+    }
+
+    private boolean isCallProfileSupported(SrvccCall profile) {
+        if (profile == null) {
+            loge("isCallProfileSupported null profile");
+            return false;
+        }
+
+        switch (profile.getPreciseCallState()) {
+            case PRECISE_CALL_STATE_ACTIVE:
+                return mSrvccTypeSupported.contains(BASIC_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_HOLDING:
+                return mSrvccTypeSupported.contains(MIDCALL_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_DIALING:
+                return mSrvccTypeSupported.contains(PREALERTING_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_ALERTING:
+                return mSrvccTypeSupported.contains(ALERTING_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_INCOMING:
+                return mSrvccTypeSupported.contains(ALERTING_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_WAITING:
+                return mSrvccTypeSupported.contains(ALERTING_SRVCC_SUPPORT);
+            case PRECISE_CALL_STATE_INCOMING_SETUP:
+                return mSrvccTypeSupported.contains(PREALERTING_SRVCC_SUPPORT);
+            default:
+                loge("isCallProfileSupported invalid state="
+                        + profile.getPreciseCallState());
+                break;
+        }
+        return false;
+    }
+
+    private synchronized ImsPhoneConnection findConnection(String callId) {
+        for (ImsPhoneConnection c : mConnections) {
+            ImsCall imsCall = c.getImsCall();
+            if (imsCall == null) continue;
+            ImsCallSession session = imsCall.getCallSession();
+            if (session == null) continue;
+
+            if (TextUtils.equals(session.getCallId(), callId)) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Update the list of SrvccConnection with the given SrvccCall and ImsPhoneconnection.
+     *
+     * @param destList the list of SrvccConnection the new connection will be added
+     * @param profile the SrvccCall of the connection to be added
+     * @param c the ImsPhoneConnection of the connection to be added
+     */
+    private void addConnection(
+            List<SrvccConnection> destList, SrvccCall profile, ImsPhoneConnection c) {
+        if (destList == null) return;
+        if (profile == null) return;
+
+        int preciseCallState = profile.getPreciseCallState();
+        if (!isAlive(preciseCallState)) {
+            Rlog.i(LOG_TAG, "addConnection not alive, " + preciseCallState);
+            return;
+        }
+
+        List<ConferenceParticipant> participants = getConferenceParticipants(c);
+        if (participants != null) {
+            for (ConferenceParticipant cp : participants) {
+                if (cp.getState() == android.telecom.Connection.STATE_DISCONNECTED) {
+                    Rlog.i(LOG_TAG, "addConnection participant is disconnected");
+                    continue;
+                }
+                SrvccConnection srvccConnection = new SrvccConnection(cp, preciseCallState);
+                Rlog.i(LOG_TAG, "addConnection " + srvccConnection);
+                destList.add(srvccConnection);
+            }
+        } else {
+            SrvccConnection srvccConnection =
+                    new SrvccConnection(profile.getImsCallProfile(), c, preciseCallState);
+            Rlog.i(LOG_TAG, "addConnection " + srvccConnection);
+            destList.add(srvccConnection);
+        }
+    }
+
+    private List<ConferenceParticipant> getConferenceParticipants(ImsPhoneConnection c) {
+        if (!mSrvccTypeSupported.contains(MIDCALL_SRVCC_SUPPORT)) return null;
+
+        ImsCall imsCall = c.getImsCall();
+        if (imsCall == null) return null;
+
+        List<ConferenceParticipant> participants = imsCall.getConferenceParticipants();
+        if (participants == null || participants.isEmpty()) return null;
+        return participants;
+    }
+
+    private static boolean isAlive(int preciseCallState) {
+        switch (preciseCallState) {
+            case PRECISE_CALL_STATE_ACTIVE: return true;
+            case PRECISE_CALL_STATE_HOLDING: return true;
+            case PRECISE_CALL_STATE_DIALING: return true;
+            case PRECISE_CALL_STATE_ALERTING: return true;
+            case PRECISE_CALL_STATE_INCOMING: return true;
+            case PRECISE_CALL_STATE_WAITING: return true;
+            case PRECISE_CALL_STATE_INCOMING_SETUP: return true;
+            default:
+        }
+        return false;
+    }
+
+    /**
+     * Notifies that radio triggered IMS deregistration.
+     * @param reason the reason why the deregistration is triggered.
+     */
+    public void triggerImsDeregistration(
+            @ImsRegistrationImplBase.ImsDeregistrationReason int reason) {
+        if (mImsManager == null) return;
+        try {
+            mImsManager.triggerDeregistration(reason);
+        } catch (ImsException e) {
+            loge("triggerImsDeregistration: exception " + e);
+        }
+    }
+
+    private void updateImsRegistrationInfo() {
+        int capabilities = 0;
+
+        if (mMmTelCapabilities.isCapable(
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
+            capabilities |= IMS_MMTEL_CAPABILITY_VOICE;
+        }
+        if (mMmTelCapabilities.isCapable(
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO)) {
+            capabilities |= IMS_MMTEL_CAPABILITY_VIDEO;
+        }
+        if (mMmTelCapabilities.isCapable(
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS)) {
+            capabilities |= IMS_MMTEL_CAPABILITY_SMS;
+        }
+
+        mPhone.updateImsRegistrationInfo(capabilities);
+    }
+
+    private void registerImsTrafficSession(int token,
+                @MmTelFeature.ImsTrafficType int trafficType,
+                @MmTelFeature.ImsTrafficDirection int trafficDirection,
+                @NonNull IImsTrafficSessionCallback callback) {
+        mImsTrafficSessions.put(Integer.valueOf(token),
+                new ImsTrafficSession(trafficType, trafficDirection, callback));
+    }
+
+    private void unregisterImsTrafficSession(int token) {
+        mImsTrafficSessions.remove(Integer.valueOf(token));
+    }
+
+    private ImsTrafficSession getImsTrafficSession(int token) {
+        return mImsTrafficSessions.get(Integer.valueOf(token));
+    }
+
+    private void stopAllImsTrafficTypes() {
+        boolean isEmpty = mImsTrafficSessions.isEmpty();
+        logi("stopAllImsTrafficTypes empty=" + isEmpty);
+
+        if (isEmpty) return;
+
+        mImsTrafficSessions.forEachKey(1, token -> mPhone.stopImsTraffic(token, null));
+        mImsTrafficSessions.clear();
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
index 14952b7..7125763 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
@@ -511,6 +511,10 @@
     }
 
     @Override
+    public void getImei(Message response) {
+    }
+
+    @Override
     public void getCDMASubscription(Message response) {
     }
 
@@ -603,12 +607,13 @@
     public void iccOpenLogicalChannel(String AID, int p2, Message response) {}
 
     @Override
-    public void iccCloseLogicalChannel(int channel, Message response) {}
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response) {}
 
     @Override
     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
                                               int p1, int p2, int p3, String data,
-                                              Message response) {}
+                                              boolean isEs10Command, Message response) {}
+
     @Override
     public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
                                             int p3, String data, Message response) {}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
old mode 100755
new mode 100644
index 68de4a3..b984d84
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -152,6 +152,11 @@
      */
     private ImsReasonInfo mImsReasonInfo;
 
+    /**
+     * Used to indicate that this call is held by remote party.
+     */
+    private boolean mIsHeldByRemote = false;
+
     //***** Event Constants
     private static final int EVENT_DTMF_DONE = 1;
     private static final int EVENT_PAUSE_DONE = 2;
@@ -244,7 +249,8 @@
 
     /** This is an MO call, created when dialing */
     public ImsPhoneConnection(Phone phone, String dialString, ImsPhoneCallTracker ct,
-            ImsPhoneCall parent, boolean isEmergency, boolean isWpsCall) {
+            ImsPhoneCall parent, boolean isEmergency, boolean isWpsCall,
+            ImsPhone.ImsDialArgs dialArgs) {
         super(PhoneConstants.PHONE_TYPE_IMS);
         createWakeLock(phone.getContext());
         acquireWakeLock();
@@ -272,6 +278,13 @@
         mIsEmergency = isEmergency;
         if (isEmergency) {
             setEmergencyCallInfo(mOwner);
+
+            if (getEmergencyNumberInfo() == null) {
+                // There was no emergency number info found for this call, however it is
+                // still marked as an emergency number. This may happen if it was a redialed
+                // non-detectable emergency call from IMS.
+                setNonDetectableEmergencyCallInfo(dialArgs.eccCategory);
+            }
         }
 
         mIsWpsCall = isWpsCall;
@@ -1580,7 +1593,30 @@
      */
     public void handleMergeComplete() {
         mIsMergeInProcess = false;
-        onConnectionEvent(android.telecom.Connection.EVENT_MERGE_COMPLETE, null);
+    }
+
+    /**
+     * Mark the call is held by remote party and inform to the UI.
+     */
+    public void setRemotelyHeld() {
+        mIsHeldByRemote = true;
+        onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null);
+    }
+
+    /**
+     * Mark the call is Unheld by remote party and inform to the UI.
+     */
+    public void setRemotelyUnheld() {
+        mIsHeldByRemote = false;
+        onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_UNHELD, null);
+    }
+
+    /**
+     * @return whether the remote party is holding the call.
+     */
+    public boolean isHeldByRemote() {
+        Rlog.i(LOG_TAG, "isHeldByRemote=" + mIsHeldByRemote);
+        return mIsHeldByRemote;
     }
 
     public void changeToPausedState() {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 738439a..25fa8a2 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -58,6 +58,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CallWaitingController;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.MmiCode;
@@ -1102,10 +1103,25 @@
                 int serviceClass = siToServiceClass(mSia);
 
                 if (isActivate() || isDeactivate()) {
+                    if (serviceClass == SERVICE_CLASS_NONE
+                            || (serviceClass & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE) {
+                        if (mPhone.getTerminalBasedCallWaitingState(false)
+                                != CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED) {
+                            mPhone.getDefaultPhone().setCallWaiting(isActivate(), serviceClass,
+                                    obtainMessage(EVENT_SET_COMPLETE, this));
+                            return;
+                        }
+                    }
                     mPhone.setCallWaiting(isActivate(), serviceClass,
                             obtainMessage(EVENT_SET_COMPLETE, this));
                 } else if (isInterrogate()) {
-                    mPhone.getCallWaiting(obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    if (mPhone.getTerminalBasedCallWaitingState(false)
+                            != CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED) {
+                        mPhone.getDefaultPhone()
+                                .getCallWaiting(obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    } else {
+                        mPhone.getCallWaiting(obtainMessage(EVENT_QUERY_COMPLETE, this));
+                    }
                 } else {
                     throw new RuntimeException ("Invalid or Unsupported MMI Code");
                 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java b/src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java
index 115f6fe..9452e2a 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelper.java
@@ -20,8 +20,10 @@
 import android.annotation.NonNull;
 import android.net.Uri;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
 import java.util.concurrent.Executor;
@@ -40,7 +42,7 @@
         /**
          * Handle the callback when IMS is registered.
          */
-        void handleImsRegistered(int imsRadioTech);
+        void handleImsRegistered(@NonNull ImsRegistrationAttributes attributes);
 
         /**
          * Handle the callback when IMS is registering.
@@ -50,7 +52,9 @@
         /**
          * Handle the callback when IMS is unregistered.
          */
-        void handleImsUnregistered(ImsReasonInfo imsReasonInfo);
+        void handleImsUnregistered(ImsReasonInfo imsReasonInfo,
+                @RegistrationManager.SuggestedAction int suggestedAction,
+                @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech);
 
         /**
          * Handle the callback when the list of subscriber {@link Uri}s associated with this IMS
@@ -66,9 +70,9 @@
     private final RegistrationManager.RegistrationCallback mImsRegistrationCallback =
             new RegistrationManager.RegistrationCallback() {
                 @Override
-                public void onRegistered(int imsRadioTech) {
+                public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
                     updateRegistrationState(RegistrationManager.REGISTRATION_STATE_REGISTERED);
-                    mImsRegistrationUpdate.handleImsRegistered(imsRadioTech);
+                    mImsRegistrationUpdate.handleImsRegistered(attributes);
                 }
 
                 @Override
@@ -79,8 +83,17 @@
 
                 @Override
                 public void onUnregistered(ImsReasonInfo imsReasonInfo) {
+                    onUnregistered(imsReasonInfo, RegistrationManager.SUGGESTED_ACTION_NONE,
+                            ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
+                }
+
+                @Override
+                public void onUnregistered(ImsReasonInfo imsReasonInfo,
+                        @RegistrationManager.SuggestedAction int suggestedAction,
+                        @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
                     updateRegistrationState(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
-                    mImsRegistrationUpdate.handleImsUnregistered(imsReasonInfo);
+                    mImsRegistrationUpdate.handleImsUnregistered(imsReasonInfo, suggestedAction,
+                            imsRadioTech);
                 }
 
                 @Override
diff --git a/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
index 56db0c7..cfa16d0 100644
--- a/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
@@ -16,10 +16,6 @@
 
 package com.android.internal.telephony.metrics;
 
-import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_HANDOVER;
-import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_NORMAL;
-import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_RADIO_OFF;
-import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
 import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION__IP_TYPE__APN_PROTOCOL_IPV4;
 
 import android.annotation.Nullable;
@@ -30,18 +26,18 @@
 import android.telephony.DataFailCause;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.ProtocolType;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataService;
-import android.telephony.data.DataService.DeactivateDataReason;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.data.DataNetwork;
 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -127,33 +123,17 @@
     /**
      * Updates the dataCall atom when data call is deactivated.
      *
-     * @param reason Deactivate reason
+     * @param reason Tear down reason
      */
-    public synchronized void setDeactivateDataCallReason(@DeactivateDataReason int reason) {
+    public synchronized void setDeactivateDataCallReason(@DataNetwork.TearDownReason int reason) {
         // there should've been another call to initiate the atom,
         // so this method is being called out of order -> no metric will be logged
         if (mDataCallSession == null) {
             loge("setDeactivateDataCallReason: no DataCallSession atom has been initiated.");
             return;
         }
-        switch (reason) {
-            case DataService.REQUEST_REASON_NORMAL:
-                mDataCallSession.deactivateReason =
-                        DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_NORMAL;
-                break;
-            case DataService.REQUEST_REASON_SHUTDOWN:
-                mDataCallSession.deactivateReason =
-                        DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_RADIO_OFF;
-                break;
-            case DataService.REQUEST_REASON_HANDOVER:
-                mDataCallSession.deactivateReason =
-                        DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_HANDOVER;
-                break;
-            default:
-                mDataCallSession.deactivateReason =
-                        DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
-                break;
-        }
+        // Skip the pre-U enum. See enum DataDeactivateReasonEnum in enums.proto
+        mDataCallSession.deactivateReason = reason + DataService.REQUEST_REASON_HANDOVER + 1;
     }
 
     /**
@@ -262,9 +242,9 @@
         mDataCallSession.oosAtEnd = getIsOos();
         mDataCallSession.ongoing = false;
         // set if this data call is established for internet on the non-Dds
-        SubscriptionInfo subInfo = SubscriptionController.getInstance()
+        SubscriptionInfo subInfo = SubscriptionManagerService.getInstance()
                 .getSubscriptionInfo(mPhone.getSubId());
-        if (mPhone.getSubId() != SubscriptionController.getInstance().getDefaultDataSubId()
+        if (mPhone.getSubId() != SubscriptionManager.getDefaultDataSubscriptionId()
                 && ((mDataCallSession.apnTypeBitmask & ApnSetting.TYPE_DEFAULT)
                 == ApnSetting.TYPE_DEFAULT)
                 && subInfo != null && !subInfo.isOpportunistic()) {
@@ -326,7 +306,7 @@
         proto.setupFailed = false;
         proto.failureCause = DataFailCause.NONE;
         proto.suggestedRetryMillis = 0;
-        proto.deactivateReason = DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
+        proto.deactivateReason = DataNetwork.TEAR_DOWN_REASON_NONE;
         proto.durationMinutes = 0;
         proto.ongoing = true;
         proto.handoverFailureCauses = new int[0];
@@ -343,13 +323,9 @@
     }
 
     private boolean getIsOpportunistic() {
-        if (mPhone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(mPhone.getSubId());
-            return subInfo != null && subInfo.isOpportunistic();
-        }
-        SubscriptionController subController = SubscriptionController.getInstance();
-        return subController != null && subController.isOpportunistic(mPhone.getSubId());
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(mPhone.getSubId());
+        return subInfo != null && subInfo.isOpportunistic();
     }
 
     private boolean getIsOos() {
diff --git a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
index 9ad775f..2f22196 100644
--- a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
@@ -27,7 +27,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 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.subscription.SubscriptionInfoInternal;
@@ -147,12 +146,8 @@
     }
 
     private static boolean getIsOpportunistic(Phone phone) {
-        if (phone.isSubscriptionManagerServiceEnabled()) {
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(phone.getSubId());
-            return subInfo != null && subInfo.isOpportunistic();
-        }
-        SubscriptionController subController = SubscriptionController.getInstance();
-        return subController != null && subController.isOpportunistic(phone.getSubId());
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(phone.getSubId());
+        return subInfo != null && subInfo.isOpportunistic();
     }
 }
diff --git a/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java b/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java
new file mode 100644
index 0000000..29729c8
--- /dev/null
+++ b/src/java/com/android/internal/telephony/metrics/DeviceStateHelper.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 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 com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_FLIPPED;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_HALF_OPENED;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_OPENED;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN;
+
+import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+
+import com.android.internal.telephony.Phone;
+
+/** Device state information like the fold state. */
+public class DeviceStateHelper {
+    private int mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN;
+
+    public DeviceStateHelper(Context context) {
+        HandlerThread mHandlerThread = new HandlerThread("DeviceStateHelperThread");
+        mHandlerThread.start();
+        context.getSystemService(DeviceStateManager.class)
+                .registerCallback(
+                        new HandlerExecutor(new Handler(mHandlerThread.getLooper())),
+                        state -> {
+                            updateFoldState(state);
+                        });
+    }
+
+    private void updateFoldState(int posture) {
+        switch (posture) {
+            case 0:
+                mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED;
+                break;
+            case 1:
+                mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_HALF_OPENED;
+                break;
+            case 2:
+                mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_OPENED;
+                break;
+            case 4:
+                mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_FLIPPED;
+                break;
+            default:
+                mFoldState = CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN;
+        }
+        updateServiceStateStats();
+    }
+
+    private void updateServiceStateStats() {
+        for (Phone phone : MetricsCollector.getPhonesIfAny()) {
+            phone.getServiceStateTracker().getServiceStateStats().onFoldStateChanged(mFoldState);
+        }
+    }
+
+    public int getFoldState() {
+        return mFoldState;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/metrics/DeviceTelephonyPropertiesStats.java b/src/java/com/android/internal/telephony/metrics/DeviceTelephonyPropertiesStats.java
new file mode 100644
index 0000000..51fe20c
--- /dev/null
+++ b/src/java/com/android/internal/telephony/metrics/DeviceTelephonyPropertiesStats.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.internal.telephony.PhoneFactory;
+
+/** Metrics for the telephony related properties on the device. */
+public class DeviceTelephonyPropertiesStats {
+    private static final String TAG = DeviceTelephonyPropertiesStats.class.getSimpleName();
+
+    /**
+     * Record whenever the auto data switch feature is toggled.
+     */
+    public static void recordAutoDataSwitchFeatureToggle() {
+        PersistAtomsStorage storage = PhoneFactory.getMetricsCollector().getAtomsStorage();
+        storage.recordToggledAutoDataSwitch();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/metrics/EmergencyNumberStats.java b/src/java/com/android/internal/telephony/metrics/EmergencyNumberStats.java
new file mode 100644
index 0000000..2867b46
--- /dev/null
+++ b/src/java/com/android/internal/telephony/metrics/EmergencyNumberStats.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 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 com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_EMERGENCY;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_NORMAL;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_UNKNOWN;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_AIEC;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_AMBULANCE;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MIEC;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_POLICE;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_DATABASE;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_DEFAULT;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING;
+import static com.android.internal.telephony.TelephonyStatsLog.EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_SIM;
+
+import android.telephony.emergency.EmergencyNumber;
+import android.util.SparseIntArray;
+
+import com.android.internal.telephony.nano.PersistAtomsProto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * EmergencyStats logs the atoms for consolidated emergency number list in framework. It also logs
+ * the details of a dialed emergency number. To avoid repeated information this class stores the
+ * emergency numbers list in map and verifies the information for duplicacy before logging it. Note:
+ * This locally stored information will erase on process restart scenarios (like reboot, crash,
+ * etc.).
+ */
+public class EmergencyNumberStats {
+
+    private static final String TAG = EmergencyNumberStats.class.getSimpleName();
+    private static final SparseIntArray sRoutesMap;
+    private static final SparseIntArray sServiceCategoriesMap;
+    private static final SparseIntArray sSourcesMap;
+    private static EmergencyNumberStats sInstance;
+
+    static {
+        sRoutesMap = new SparseIntArray() {
+            {
+                put(EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
+                        EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_EMERGENCY);
+                put(EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL,
+                        EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_NORMAL);
+                put(EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
+                        EMERGENCY_NUMBERS_INFO__ROUTE__EMERGENCY_CALL_ROUTE_UNKNOWN);
+            }
+        };
+
+        sServiceCategoriesMap = new SparseIntArray() {
+            {
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_POLICE);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_MIEC);
+                put(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AIEC,
+                        EMERGENCY_NUMBERS_INFO__SERVICE_CATEGORIES__EMERGENCY_SERVICE_CATEGORY_AIEC);
+            }
+        };
+
+        sSourcesMap = new SparseIntArray() {
+            {
+                put(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                        EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
+                put(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                        EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_SIM);
+                put(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                        EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_DATABASE);
+                put(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+                        EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
+                put(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DEFAULT,
+                        EMERGENCY_NUMBERS_INFO__SOURCES__EMERGENCY_NUMBER_SOURCE_DEFAULT);
+            }
+        };
+    }
+
+    private EmergencyNumberStats() {
+    }
+
+    /** Static method to provide singleton instance for EmergencyNumberStats. */
+    public static EmergencyNumberStats getInstance() {
+        if (sInstance == null) {
+            sInstance = new EmergencyNumberStats();
+        }
+        return sInstance;
+    }
+
+    /**
+     * It converts the {@link android.telephony.emergency.EmergencyNumber} to
+     * {@link PersistAtomsProto.EmergencyNumber} for
+     * logging the EmergencyNumber atoms with pulled event.
+     *
+     * @param emergencyNumberList android.telephony.EmergencyNumber list
+     * @param assetVersion        assert version
+     * @param otaVersion          ota version
+     * @param isDbRoutingIgnored  flag that defines if routing is ignored through database.
+     */
+    public PersistAtomsProto.EmergencyNumbersInfo[] convertEmergencyNumbersListToProto(
+            List<EmergencyNumber> emergencyNumberList, int assetVersion, int otaVersion,
+            boolean isDbRoutingIgnored) {
+        List<PersistAtomsProto.EmergencyNumbersInfo> numberProtoList = new ArrayList<>();
+        for (EmergencyNumber number : emergencyNumberList) {
+            numberProtoList.add(convertEmergencyNumberToProto(number, assetVersion, otaVersion,
+                    isDbRoutingIgnored));
+        }
+        return numberProtoList.toArray(new PersistAtomsProto.EmergencyNumbersInfo[0]);
+    }
+
+    private PersistAtomsProto.EmergencyNumbersInfo convertEmergencyNumberToProto(
+            EmergencyNumber number, int assetVer, int otaVer, boolean isDbRoutingIgnored) {
+        String dialNumber = number.getNumber();
+        PersistAtomsProto.EmergencyNumbersInfo emergencyNumber =
+                new PersistAtomsProto.EmergencyNumbersInfo();
+        emergencyNumber.isDbVersionIgnored = isDbRoutingIgnored;
+        emergencyNumber.assetVersion = assetVer;
+        emergencyNumber.otaVersion = otaVer;
+        emergencyNumber.number = dialNumber;
+        emergencyNumber.countryIso = number.getCountryIso();
+        emergencyNumber.mnc = number.getMnc();
+        emergencyNumber.route = sRoutesMap.get(number.getEmergencyCallRouting());
+        emergencyNumber.urns = number.getEmergencyUrns().toArray(new String[0]);
+        emergencyNumber.serviceCategories = getMappedServiceCategories(
+                number.getEmergencyServiceCategories());
+        emergencyNumber.sources = getMappedSources(number.getEmergencyNumberSources());
+        return emergencyNumber;
+    }
+
+    private int[] getMappedServiceCategories(List<Integer> serviceCategories) {
+        if (serviceCategories == null || serviceCategories.isEmpty()) {
+            return null;
+        }
+        return serviceCategories.stream().map(sServiceCategoriesMap::get).mapToInt(
+                Integer::intValue).toArray();
+    }
+
+    private int[] getMappedSources(List<Integer> sources) {
+        if (sources == null || sources.isEmpty()) {
+            return null;
+        }
+        return sources.stream().map(sSourcesMap::get).mapToInt(Integer::intValue).toArray();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 412930f..5e00987 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -16,15 +16,12 @@
 
 package com.android.internal.telephony.metrics;
 
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
 import static com.android.internal.telephony.TelephonyStatsLog.CARRIER_ID_TABLE_VERSION;
 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.EMERGENCY_NUMBERS_INFO;
 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;
@@ -33,11 +30,18 @@
 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_SHORT_CODE_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.SATELLITE_CONTROLLER;
+import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_INCOMING_DATAGRAM;
+import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_OUTGOING_DATAGRAM;
+import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_PROVISION;
+import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_SESSION;
+import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_SOS_MESSAGE_RECOMMENDER;
 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;
@@ -52,16 +56,20 @@
 
 import android.app.StatsManager;
 import android.content.Context;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.util.StatsEvent;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyStatsLog;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 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.internal.telephony.nano.PersistAtomsProto.DataCallSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.EmergencyNumbersInfo;
 import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
@@ -71,10 +79,17 @@
 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.OutgoingShortCodeSms;
 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.SatelliteController;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
@@ -85,6 +100,7 @@
 import com.android.internal.util.ConcurrentUtils;
 import com.android.telephony.Rlog;
 
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
@@ -104,6 +120,10 @@
     /** Disables various restrictions to ease debugging during development. */
     private static final boolean DBG = false; // STOPSHIP if true
 
+    private static final long MILLIS_PER_HOUR = Duration.ofHours(1).toMillis();
+    private static final long MILLIS_PER_MINUTE = Duration.ofMinutes(1).toMillis();
+    private static final long MILLIS_PER_SECOND = Duration.ofSeconds(1).toMillis();
+
     /**
      * Sets atom pull cool down to 23 hours to help enforcing privacy requirement.
      *
@@ -111,7 +131,7 @@
      * that occur once a day.
      */
     private static final long MIN_COOLDOWN_MILLIS =
-            DBG ? 10L * SECOND_IN_MILLIS : 23L * HOUR_IN_MILLIS;
+            DBG ? 10L * MILLIS_PER_SECOND : 23L * MILLIS_PER_HOUR;
 
     /**
      * Buckets with less than these many calls will be dropped.
@@ -122,25 +142,28 @@
 
     /** Bucket size in milliseconds to round call durations into. */
     private static final long DURATION_BUCKET_MILLIS =
-            DBG ? 2L * SECOND_IN_MILLIS : 5L * MINUTE_IN_MILLIS;
+            DBG ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
 
     private final PersistAtomsStorage mStorage;
+    private final DeviceStateHelper mDeviceStateHelper;
     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));
+        this(context, new PersistAtomsStorage(context), new DeviceStateHelper(context));
     }
 
     /** Allows dependency injection. Used during unit tests. */
     @VisibleForTesting
-    public MetricsCollector(Context context,
-                            PersistAtomsStorage storage) {
+    public MetricsCollector(
+            Context context, PersistAtomsStorage storage, DeviceStateHelper deviceStateHelper) {
         mStorage = storage;
+        mDeviceStateHelper = deviceStateHelper;
         mStatsManager = (StatsManager) context.getSystemService(Context.STATS_MANAGER);
         if (mStatsManager != null) {
+            // Most (but not all) of these are subject to cooldown specified by MIN_COOLDOWN_MILLIS.
             registerAtom(CELLULAR_DATA_SERVICE_SWITCH);
             registerAtom(CELLULAR_SERVICE_STATE);
             registerAtom(SIM_SLOT_STATE);
@@ -169,6 +192,14 @@
             registerAtom(PRESENCE_NOTIFY_EVENT);
             registerAtom(GBA_EVENT);
             registerAtom(PER_SIM_STATUS);
+            registerAtom(OUTGOING_SHORT_CODE_SMS);
+            registerAtom(SATELLITE_CONTROLLER);
+            registerAtom(SATELLITE_SESSION);
+            registerAtom(SATELLITE_INCOMING_DATAGRAM);
+            registerAtom(SATELLITE_OUTGOING_DATAGRAM);
+            registerAtom(SATELLITE_PROVISION);
+            registerAtom(SATELLITE_SOS_MESSAGE_RECOMMENDER);
+            registerAtom(EMERGENCY_NUMBERS_INFO);
             Rlog.d(TAG, "registered");
         } else {
             Rlog.e(TAG, "could not get StatsManager, atoms not registered");
@@ -243,6 +274,22 @@
                 return pullGbaEvent(data);
             case PER_SIM_STATUS:
                 return pullPerSimStatus(data);
+            case OUTGOING_SHORT_CODE_SMS:
+                return pullOutgoingShortCodeSms(data);
+            case SATELLITE_CONTROLLER:
+                return pullSatelliteController(data);
+            case SATELLITE_SESSION:
+                return pullSatelliteSession(data);
+            case SATELLITE_INCOMING_DATAGRAM:
+                return pullSatelliteIncomingDatagram(data);
+            case SATELLITE_OUTGOING_DATAGRAM:
+                return pullSatelliteOutgoingDatagram(data);
+            case SATELLITE_PROVISION:
+                return pullSatelliteProvision(data);
+            case SATELLITE_SOS_MESSAGE_RECOMMENDER:
+                return pullSatelliteSosMessageRecommender(data);
+            case EMERGENCY_NUMBERS_INFO:
+                return pullEmergencyNumbersInfo(data);
             default:
                 Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag));
                 return StatsManager.PULL_SKIP;
@@ -254,6 +301,23 @@
         return mStorage;
     }
 
+    /** Returns the {@link DeviceStateHelper}. */
+    public DeviceStateHelper getDeviceStateHelper() {
+        return mDeviceStateHelper;
+    }
+
+    /** Updates duration segments and calls {@link PersistAtomsStorage#flushAtoms()}. */
+    public void flushAtomsStorage() {
+        concludeAll();
+        mStorage.flushAtoms();
+    }
+
+    /** Updates duration segments and calls {@link PersistAtomsStorage#clearAtoms()}. */
+    public void clearAtomsStorage() {
+        concludeAll();
+        mStorage.clearAtoms();
+    }
+
     /**
      * Registers a {@link DataCallSessionStats} which will be pinged for on-going data calls when
      * data call atoms are pulled.
@@ -267,6 +331,44 @@
         mOngoingDataCallStats.remove(call);
     }
 
+    private void concludeDataCallSessionStats() {
+        for (DataCallSessionStats stats : mOngoingDataCallStats) {
+            stats.conclude();
+        }
+    }
+
+    private void concludeImsStats() {
+        for (Phone phone : getPhonesIfAny()) {
+            ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
+            if (imsPhone != null) {
+                imsPhone.getImsStats().conclude();
+            }
+        }
+    }
+
+    private void concludeServiceStateStats() {
+        for (Phone phone : getPhonesIfAny()) {
+            phone.getServiceStateTracker().getServiceStateStats().conclude();
+        }
+    }
+
+    private void concludeRcsStats() {
+        RcsStats rcsStats = RcsStats.getInstance();
+        if (rcsStats != null) {
+            rcsStats.concludeSipTransportFeatureTagsStat();
+            rcsStats.onFlushIncompleteRcsAcsProvisioningStats();
+            rcsStats.onFlushIncompleteImsRegistrationServiceDescStats();
+            rcsStats.onFlushIncompleteImsRegistrationFeatureTagStats();
+        }
+    }
+
+    private void concludeAll() {
+        concludeDataCallSessionStats();
+        concludeImsStats();
+        concludeServiceStateStats();
+        concludeRcsStats();
+    }
+
     private static int pullSimSlotState(List<StatsEvent> data) {
         SimSlotState state;
         try {
@@ -374,10 +476,7 @@
 
     private int pullDataCallSession(List<StatsEvent> data) {
         // Include ongoing data call segments
-        for (DataCallSessionStats stats : mOngoingDataCallStats) {
-            stats.conclude();
-        }
-
+        concludeDataCallSessionStats();
         DataCallSession[] dataCallSessions = mStorage.getDataCallSessions(MIN_COOLDOWN_MILLIS);
         if (dataCallSessions != null) {
             Arrays.stream(dataCallSessions)
@@ -405,10 +504,7 @@
 
     private int pullCellularServiceState(List<StatsEvent> data) {
         // Include the latest durations
-        for (Phone phone : getPhonesIfAny()) {
-            phone.getServiceStateTracker().getServiceStateStats().conclude();
-        }
-
+        concludeServiceStateStats();
         CellularServiceState[] persistAtoms =
                 mStorage.getCellularServiceStates(MIN_COOLDOWN_MILLIS);
         if (persistAtoms != null) {
@@ -424,13 +520,7 @@
 
     private int pullImsRegistrationStats(List<StatsEvent> data) {
         // Include the latest durations
-        for (Phone phone : getPhonesIfAny()) {
-            ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
-            if (imsPhone != null) {
-                imsPhone.getImsStats().conclude();
-            }
-        }
-
+        concludeImsStats();
         ImsRegistrationStats[] persistAtoms = mStorage.getImsRegistrationStats(MIN_COOLDOWN_MILLIS);
         if (persistAtoms != null) {
             // list is already shuffled when instances were inserted
@@ -469,13 +559,22 @@
         }
     }
 
-    private static int pullDeviceTelephonyProperties(List<StatsEvent> data) {
+    private int pullDeviceTelephonyProperties(List<StatsEvent> data) {
         Phone[] phones = getPhonesIfAny();
         if (phones.length == 0) {
             return StatsManager.PULL_SKIP;
         }
+        boolean isAutoDataSwitchOn = Arrays.stream(phones)
+                .anyMatch(phone ->
+                        phone.getSubId() != SubscriptionManager.getDefaultDataSubscriptionId()
+                                && phone.getDataSettingsManager().isMobileDataPolicyEnabled(
+                        TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH));
+        boolean hasDedicatedManagedProfileSub = Arrays.stream(phones)
+                .anyMatch(Phone::isManagedProfile);
 
-        data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES, true));
+        data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES, true,
+                isAutoDataSwitchOn, mStorage.getAutoDataSwitchToggleCount(),
+                hasDedicatedManagedProfileSub));
         return StatsManager.PULL_SUCCESS;
     }
 
@@ -677,13 +776,122 @@
                     perSimStatus.pin1Enabled, // isPin1Enabled
                     perSimStatus.minimumVoltageClass, // simVoltageClass
                     perSimStatus.userModifiedApnTypes, // userModifiedApnTypeBitmask
-                    perSimStatus.unmeteredNetworks); // unmeteredNetworks
+                    perSimStatus.unmeteredNetworks, // unmeteredNetworks
+                    perSimStatus.vonrEnabled); // vonrEnabled
             data.add(statsEvent);
             result = StatsManager.PULL_SUCCESS;
         }
         return result;
     }
 
+    private int pullOutgoingShortCodeSms(List<StatsEvent> data) {
+        OutgoingShortCodeSms[] outgoingShortCodeSmsList = mStorage
+                .getOutgoingShortCodeSms(MIN_COOLDOWN_MILLIS);
+        if (outgoingShortCodeSmsList != null) {
+            // Outgoing short code SMS list is already shuffled when SMS were inserted
+            Arrays.stream(outgoingShortCodeSmsList).forEach(sms -> data.add(buildStatsEvent(sms)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "OUTGOING_SHORT_CODE_SMS pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullSatelliteController(List<StatsEvent> data) {
+        SatelliteController[] controllerAtoms =
+                mStorage.getSatelliteControllerStats(MIN_COOLDOWN_MILLIS);
+        if (controllerAtoms != null) {
+            Arrays.stream(controllerAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_CONTROLLER pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullSatelliteSession(List<StatsEvent> data) {
+        SatelliteSession[] sessionAtoms =
+                mStorage.getSatelliteSessionStats(MIN_COOLDOWN_MILLIS);
+        if (sessionAtoms != null) {
+            Arrays.stream(sessionAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_SESSION pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullSatelliteIncomingDatagram(List<StatsEvent> data) {
+        SatelliteIncomingDatagram[] incomingDatagramAtoms =
+                mStorage.getSatelliteIncomingDatagramStats(MIN_COOLDOWN_MILLIS);
+        if (incomingDatagramAtoms != null) {
+            Arrays.stream(incomingDatagramAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_INCOMING_DATAGRAM pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+
+    private int pullSatelliteOutgoingDatagram(List<StatsEvent> data) {
+        SatelliteOutgoingDatagram[] outgoingDatagramAtoms =
+                mStorage.getSatelliteOutgoingDatagramStats(MIN_COOLDOWN_MILLIS);
+        if (outgoingDatagramAtoms != null) {
+            Arrays.stream(outgoingDatagramAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_OUTGOING_DATAGRAM pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+
+    private int pullSatelliteProvision(List<StatsEvent> data) {
+        SatelliteProvision[] provisionAtoms =
+                mStorage.getSatelliteProvisionStats(MIN_COOLDOWN_MILLIS);
+        if (provisionAtoms != null) {
+            Arrays.stream(provisionAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_PROVISION pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullSatelliteSosMessageRecommender(List<StatsEvent> data) {
+        SatelliteSosMessageRecommender[] sosMessageRecommenderAtoms =
+                mStorage.getSatelliteSosMessageRecommenderStats(MIN_COOLDOWN_MILLIS);
+        if (sosMessageRecommenderAtoms != null) {
+            Arrays.stream(sosMessageRecommenderAtoms)
+                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Rlog.w(TAG, "SATELLITE_SOS_MESSAGE_RECOMMENDER pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullEmergencyNumbersInfo(List<StatsEvent> data) {
+        boolean isDataLogged = false;
+        for (Phone phone : getPhonesIfAny()) {
+            if (phone != null) {
+                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+                if (tracker != null) {
+                    EmergencyNumbersInfo[] numList = tracker.getEmergencyNumbersProtoArray();
+                    Arrays.stream(numList).forEach(number -> data.add(buildStatsEvent(number)));
+                    isDataLogged = true;
+                }
+            }
+        }
+        return isDataLogged ? StatsManager.PULL_SUCCESS : StatsManager.PULL_SKIP;
+    }
+
     /** Registers a pulled atom ID {@code atomId}. */
     private void registerAtom(int atomId) {
         mStatsManager.setPullAtomCallback(atomId, /* metadata= */ null,
@@ -712,8 +920,10 @@
                 state.simSlotIndex,
                 state.isMultiSim,
                 state.carrierId,
-                (int) (round(state.totalTimeMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                state.isEmergencyOnly);
+                roundAndConvertMillisToSeconds(state.totalTimeMillis),
+                state.isEmergencyOnly,
+                state.isInternetPdnUp,
+                state.foldState);
     }
 
     private static StatsEvent buildStatsEvent(VoiceCallRatUsage usage) {
@@ -721,7 +931,7 @@
                 VOICE_CALL_RAT_USAGE,
                 usage.carrierId,
                 usage.rat,
-                round(usage.totalDurationMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS,
+                roundAndConvertMillisToSeconds(usage.totalDurationMillis),
                 usage.callCount);
     }
 
@@ -764,7 +974,8 @@
                 session.ratAtConnected,
                 session.isMultiparty,
                 session.callDuration,
-                session.lastKnownRat);
+                session.lastKnownRat,
+                session.foldState);
     }
 
     private static StatsEvent buildStatsEvent(IncomingSms sms) {
@@ -784,7 +995,8 @@
                 sms.isEsim,
                 sms.carrierId,
                 sms.messageId,
-                sms.count);
+                sms.count,
+                sms.isManagedProfile);
     }
 
     private static StatsEvent buildStatsEvent(OutgoingSms sms) {
@@ -804,7 +1016,10 @@
                 sms.messageId,
                 sms.retryId,
                 sms.intervalMillis,
-                sms.count);
+                sms.count,
+                sms.sendErrorCode,
+                sms.networkErrorCode,
+                sms.isManagedProfile);
     }
 
     private static StatsEvent buildStatsEvent(DataCallSession dataCallSession) {
@@ -826,7 +1041,8 @@
                 dataCallSession.failureCause,
                 dataCallSession.suggestedRetryMillis,
                 dataCallSession.deactivateReason,
-                round(dataCallSession.durationMinutes, DURATION_BUCKET_MILLIS / MINUTE_IN_MILLIS),
+                roundAndConvertMillisToMinutes(
+                        dataCallSession.durationMinutes * MILLIS_PER_MINUTE),
                 dataCallSession.ongoing,
                 dataCallSession.bandAtEnd,
                 dataCallSession.handoverFailureCauses,
@@ -840,19 +1056,15 @@
                 stats.carrierId,
                 stats.simSlotIndex,
                 stats.rat,
-                (int) (round(stats.registeredMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int) (round(stats.voiceCapableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int)
-                        (round(stats.voiceAvailableMillis, DURATION_BUCKET_MILLIS)
-                                / SECOND_IN_MILLIS),
-                (int) (round(stats.smsCapableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int) (round(stats.smsAvailableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int) (round(stats.videoCapableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int)
-                        (round(stats.videoAvailableMillis, DURATION_BUCKET_MILLIS)
-                                / SECOND_IN_MILLIS),
-                (int) (round(stats.utCapableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                (int) (round(stats.utAvailableMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
+                roundAndConvertMillisToSeconds(stats.registeredMillis),
+                roundAndConvertMillisToSeconds(stats.voiceCapableMillis),
+                roundAndConvertMillisToSeconds(stats.voiceAvailableMillis),
+                roundAndConvertMillisToSeconds(stats.smsCapableMillis),
+                roundAndConvertMillisToSeconds(stats.smsAvailableMillis),
+                roundAndConvertMillisToSeconds(stats.videoCapableMillis),
+                roundAndConvertMillisToSeconds(stats.videoAvailableMillis),
+                roundAndConvertMillisToSeconds(stats.utCapableMillis),
+                roundAndConvertMillisToSeconds(stats.utAvailableMillis));
     }
 
     private static StatsEvent buildStatsEvent(ImsRegistrationTermination termination) {
@@ -883,7 +1095,7 @@
                 stats.slotId,
                 stats.featureTagName,
                 stats.registrationTech,
-                (int) (round(stats.registeredMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
+                roundAndConvertMillisToSeconds(stats.registeredMillis));
     }
 
     private static StatsEvent buildStatsEvent(RcsClientProvisioningStats stats) {
@@ -904,7 +1116,7 @@
                 stats.responseType,
                 stats.isSingleRegistrationEnabled,
                 stats.count,
-                (int) (round(stats.stateTimerMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
+                roundAndConvertMillisToSeconds(stats.stateTimerMillis));
     }
 
     private static StatsEvent buildStatsEvent(SipDelegateStats stats) {
@@ -913,7 +1125,7 @@
                 stats.dimension,
                 stats.carrierId,
                 stats.slotId,
-                (int) (round(stats.uptimeMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
+                roundAndConvertMillisToSeconds(stats.uptimeMillis),
                 stats.destroyReason);
     }
 
@@ -925,7 +1137,7 @@
                 stats.featureTagName,
                 stats.sipTransportDeniedReason,
                 stats.sipTransportDeregisteredReason,
-                (int) (round(stats.associatedMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
+                roundAndConvertMillisToSeconds(stats.associatedMillis));
     }
 
     private static StatsEvent buildStatsEvent(SipMessageResponse stats) {
@@ -985,7 +1197,7 @@
                 stats.serviceIdName,
                 stats.serviceIdVersion,
                 stats.registrationTech,
-                (int) (round(stats.publishedMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
+                roundAndConvertMillisToSeconds(stats.publishedMillis));
     }
 
     private static StatsEvent buildStatsEvent(UceEventStats stats) {
@@ -1023,8 +1235,97 @@
                 stats.count);
     }
 
+    private static StatsEvent buildStatsEvent(OutgoingShortCodeSms shortCodeSms) {
+        return TelephonyStatsLog.buildStatsEvent(
+                OUTGOING_SHORT_CODE_SMS,
+                shortCodeSms.category,
+                shortCodeSms.xmlVersion,
+                shortCodeSms.shortCodeSmsCount);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteController satelliteController) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_CONTROLLER,
+                satelliteController.countOfSatelliteServiceEnablementsSuccess,
+                satelliteController.countOfSatelliteServiceEnablementsFail,
+                satelliteController.countOfOutgoingDatagramSuccess,
+                satelliteController.countOfOutgoingDatagramFail,
+                satelliteController.countOfIncomingDatagramSuccess,
+                satelliteController.countOfIncomingDatagramFail,
+                satelliteController.countOfDatagramTypeSosSmsSuccess,
+                satelliteController.countOfDatagramTypeSosSmsFail,
+                satelliteController.countOfDatagramTypeLocationSharingSuccess,
+                satelliteController.countOfDatagramTypeLocationSharingFail,
+                satelliteController.countOfProvisionSuccess,
+                satelliteController.countOfProvisionFail,
+                satelliteController.countOfDeprovisionSuccess,
+                satelliteController.countOfDeprovisionFail,
+                satelliteController.totalServiceUptimeSec,
+                satelliteController.totalBatteryConsumptionPercent,
+                satelliteController.totalBatteryChargedTimeSec);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteSession satelliteSession) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_SESSION,
+                satelliteSession.satelliteServiceInitializationResult,
+                satelliteSession.satelliteTechnology,
+                satelliteSession.count);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteIncomingDatagram stats) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_INCOMING_DATAGRAM,
+                stats.resultCode,
+                stats.datagramSizeBytes,
+                stats.datagramTransferTimeMillis);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteOutgoingDatagram stats) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_OUTGOING_DATAGRAM,
+                stats.datagramType,
+                stats.resultCode,
+                stats.datagramSizeBytes,
+                stats.datagramTransferTimeMillis);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteProvision stats) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_PROVISION,
+                stats.resultCode,
+                stats.provisioningTimeSec,
+                stats.isProvisionRequest,
+                stats.isCanceled);
+    }
+
+    private static StatsEvent buildStatsEvent(SatelliteSosMessageRecommender stats) {
+        return TelephonyStatsLog.buildStatsEvent(
+                SATELLITE_SOS_MESSAGE_RECOMMENDER,
+                stats.isDisplaySosMessageSent,
+                stats.countOfTimerStarted,
+                stats.isImsRegistered,
+                stats.cellularServiceState,
+                stats.count);
+    }
+
+    private static StatsEvent buildStatsEvent(EmergencyNumbersInfo emergencyNumber) {
+        return TelephonyStatsLog.buildStatsEvent(
+                EMERGENCY_NUMBERS_INFO,
+                emergencyNumber.isDbVersionIgnored,
+                emergencyNumber.assetVersion,
+                emergencyNumber.otaVersion,
+                emergencyNumber.number,
+                emergencyNumber.countryIso,
+                emergencyNumber.mnc,
+                emergencyNumber.route,
+                emergencyNumber.urns,
+                emergencyNumber.serviceCategories,
+                emergencyNumber.sources);
+    }
+
     /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
-    private static Phone[] getPhonesIfAny() {
+    static Phone[] getPhonesIfAny() {
         try {
             return PhoneFactory.getPhones();
         } catch (IllegalStateException e) {
@@ -1033,8 +1334,21 @@
         }
     }
 
-    /** Returns the value rounded to the bucket. */
-    private static long round(long value, long bucket) {
-        return bucket == 0 ? value : ((value + bucket / 2) / bucket) * bucket;
+    /**
+     * Rounds the duration and converts it from milliseconds to seconds.
+     */
+    private static int roundAndConvertMillisToSeconds(long valueMillis) {
+        long roundedValueMillis = Math.round((double) valueMillis / DURATION_BUCKET_MILLIS)
+                * DURATION_BUCKET_MILLIS;
+        return (int) (roundedValueMillis / MILLIS_PER_SECOND);
+    }
+
+    /**
+     * Rounds the duration and converts it from milliseconds to minutes.
+     */
+    private static int roundAndConvertMillisToMinutes(long valueMillis) {
+        long roundedValueMillis = Math.round((double) valueMillis / DURATION_BUCKET_MILLIS)
+                * DURATION_BUCKET_MILLIS;
+        return (int) (roundedValueMillis / MILLIS_PER_MINUTE);
     }
 }
diff --git a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java b/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
index 0b55815..bc1edc3 100644
--- a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
+++ b/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
@@ -32,7 +32,6 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.provider.Telephony;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
@@ -43,14 +42,11 @@
 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.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 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 =
@@ -76,6 +72,7 @@
     public final int minimumVoltageClass;
     public final int userModifiedApnTypes;
     public final long unmeteredNetworks;
+    public final boolean vonrEnabled;
 
     /** Returns the current sim status of the given {@link Phone}. */
     @Nullable
@@ -107,7 +104,8 @@
                 iccCard == null ? false : iccCard.getIccLockEnabled(),
                 getMinimumVoltageClass(phone),
                 getUserModifiedApnTypes(phone),
-                persistAtomsStorage.getUnmeteredNetworks(phone.getPhoneId(), carrierId));
+                persistAtomsStorage.getUnmeteredNetworks(phone.getPhoneId(), carrierId),
+                isVonrEnabled(phone));
     }
 
     private PerSimStatus(
@@ -126,7 +124,8 @@
             boolean pin1Enabled,
             int minimumVoltageClass,
             int userModifiedApnTypes,
-            long unmeteredNetworks) {
+            long unmeteredNetworks,
+            boolean vonrEnabled) {
         this.carrierId = carrierId;
         this.phoneNumberSourceUicc = phoneNumberSourceUicc;
         this.phoneNumberSourceCarrier = phoneNumberSourceCarrier;
@@ -143,6 +142,7 @@
         this.minimumVoltageClass = minimumVoltageClass;
         this.userModifiedApnTypes = userModifiedApnTypes;
         this.unmeteredNetworks = unmeteredNetworks;
+        this.vonrEnabled = vonrEnabled;
     }
 
     @Nullable
@@ -175,40 +175,21 @@
         String countryIso = "";
         String[] numbersFromAllSources;
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            if (SubscriptionManagerService.getInstance() == null) return null;
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(phone.getSubId());
-            if (subInfo != null) {
-                countryIso = subInfo.getCountryIso();
-            }
-            numbersFromAllSources = new String[]{
-                    SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_UICC, null, null),
-                    SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER, null, null),
-                    SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_IMS, null, null)
-            };
-        } else {
-            SubscriptionController subscriptionController = SubscriptionController.getInstance();
-            if (subscriptionController == null) {
-                return null;
-            }
-            int subId = phone.getSubId();
-            countryIso = Optional.ofNullable(subscriptionController.getSubscriptionInfo(subId))
-                    .map(SubscriptionInfo::getCountryIso)
-                    .orElse("");
-            // numbersFromAllSources[] - phone numbers from each sources:
-            numbersFromAllSources = new String[]{
-                    subscriptionController.getPhoneNumber(subId,
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_UICC, null, null), // 0
-                    subscriptionController.getPhoneNumber(subId,
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER, null, null), // 1
-                    subscriptionController.getPhoneNumber(subId,
-                            SubscriptionManager.PHONE_NUMBER_SOURCE_IMS, null, null), // 2
-            };
+        if (SubscriptionManagerService.getInstance() == null) return null;
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(phone.getSubId());
+        if (subInfo != null) {
+            countryIso = subInfo.getCountryIso();
         }
+        numbersFromAllSources = new String[]{
+                SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
+                        SubscriptionManager.PHONE_NUMBER_SOURCE_UICC, null, null),
+                SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
+                        SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER, null, null),
+                SubscriptionManagerService.getInstance().getPhoneNumber(phone.getSubId(),
+                        SubscriptionManager.PHONE_NUMBER_SOURCE_IMS, null, null)
+        };
+
         int[] numberIds = new int[numbersFromAllSources.length]; // default value 0
         for (int i = 0, idForNextUniqueNumber = 1; i < numberIds.length; i++) {
             if (TextUtils.isEmpty(numbersFromAllSources[i])) {
@@ -295,4 +276,16 @@
             return bitmask;
         }
     }
+
+    /** Returns true if VoNR is enabled */
+    private static boolean isVonrEnabled(Phone phone) {
+        TelephonyManager telephonyManager =
+                phone.getContext()
+                        .getSystemService(TelephonyManager.class);
+        if (telephonyManager == null) {
+            return false;
+        }
+        telephonyManager = telephonyManager.createForSubscriptionId(phone.getSubId());
+        return telephonyManager.isVoNrEnabled();
+    }
 }
diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
index eef88d2..5a21baf 100644
--- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
+++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
@@ -42,11 +42,18 @@
 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.OutgoingShortCodeSms;
 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.SatelliteController;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
@@ -159,6 +166,13 @@
     /** Maximum number of GBA Event to store between pulls. */
     private final int mMaxNumGbaEventStats;
 
+    /** Maximum number of outgoing short code sms to store between pulls. */
+    private final int mMaxOutgoingShortCodeSms;
+
+    /** Maximum number of Satellite relevant stats to store between pulls. */
+    private final int mMaxNumSatelliteStats;
+    private final int mMaxNumSatelliteControllerStats = 1;
+
     /** Stores persist atoms and persist states of the puller. */
     @VisibleForTesting protected PersistAtoms mAtoms;
 
@@ -207,6 +221,8 @@
             mMaxNumUceEventStats = 5;
             mMaxNumPresenceNotifyEventStats = 10;
             mMaxNumGbaEventStats = 5;
+            mMaxOutgoingShortCodeSms = 5;
+            mMaxNumSatelliteStats = 5;
         } else {
             mMaxNumVoiceCallSessions = 50;
             mMaxNumSms = 25;
@@ -229,6 +245,8 @@
             mMaxNumUceEventStats = 25;
             mMaxNumPresenceNotifyEventStats = 50;
             mMaxNumGbaEventStats = 10;
+            mMaxOutgoingShortCodeSms = 10;
+            mMaxNumSatelliteStats = 15;
         }
 
         mAtoms = loadAtomsFromFile();
@@ -431,6 +449,14 @@
         }
     }
 
+    /**
+     * Store the number of times auto data switch feature is toggled.
+     */
+    public synchronized void recordToggledAutoDataSwitch() {
+        mAtoms.autoDataSwitchToggleCount++;
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
     /** Adds a new {@link NetworkRequestsV2} to the storage. */
     public synchronized void addNetworkRequestsV2(NetworkRequestsV2 networkRequests) {
         NetworkRequestsV2 existingMetrics = find(networkRequests);
@@ -655,6 +681,113 @@
         }
     }
 
+    /** Adds an outgoing short code sms to the storage. */
+    public synchronized void addOutgoingShortCodeSms(OutgoingShortCodeSms shortCodeSms) {
+        OutgoingShortCodeSms existingOutgoingShortCodeSms = find(shortCodeSms);
+        if (existingOutgoingShortCodeSms != null) {
+            existingOutgoingShortCodeSms.shortCodeSmsCount += 1;
+        } else {
+            mAtoms.outgoingShortCodeSms = insertAtRandomPlace(mAtoms.outgoingShortCodeSms,
+                    shortCodeSms, mMaxOutgoingShortCodeSms);
+        }
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteController} to the storage. */
+    public synchronized void addSatelliteControllerStats(SatelliteController stats) {
+        // SatelliteController is a single data point
+        SatelliteController[] atomArray = mAtoms.satelliteController;
+        if (atomArray == null || atomArray.length == 0) {
+            atomArray = new SatelliteController[] {new SatelliteController()};
+        }
+
+        SatelliteController atom = atomArray[0];
+        atom.countOfSatelliteServiceEnablementsSuccess
+                += stats.countOfSatelliteServiceEnablementsSuccess;
+        atom.countOfSatelliteServiceEnablementsFail
+                += stats.countOfSatelliteServiceEnablementsFail;
+        atom.countOfOutgoingDatagramSuccess
+                += stats.countOfOutgoingDatagramSuccess;
+        atom.countOfOutgoingDatagramFail
+                += stats.countOfOutgoingDatagramFail;
+        atom.countOfIncomingDatagramSuccess
+                += stats.countOfIncomingDatagramSuccess;
+        atom.countOfIncomingDatagramFail
+                += stats.countOfIncomingDatagramFail;
+        atom.countOfDatagramTypeSosSmsSuccess
+                += stats.countOfDatagramTypeSosSmsSuccess;
+        atom.countOfDatagramTypeSosSmsFail
+                += stats.countOfDatagramTypeSosSmsFail;
+        atom.countOfDatagramTypeLocationSharingSuccess
+                += stats.countOfDatagramTypeLocationSharingSuccess;
+        atom.countOfDatagramTypeLocationSharingFail
+                += stats.countOfDatagramTypeLocationSharingFail;
+        atom.countOfProvisionSuccess
+                += stats.countOfProvisionSuccess;
+        atom.countOfProvisionFail
+                += stats.countOfProvisionFail;
+        atom.countOfDeprovisionSuccess
+                += stats.countOfDeprovisionSuccess;
+        atom.countOfDeprovisionFail
+                += stats.countOfDeprovisionFail;
+        atom.totalServiceUptimeSec
+                += stats.totalServiceUptimeSec;
+        atom.totalBatteryConsumptionPercent
+                += stats.totalBatteryConsumptionPercent;
+        atom.totalBatteryChargedTimeSec
+                += stats.totalBatteryChargedTimeSec;
+
+        mAtoms.satelliteController = atomArray;
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteSession} to the storage. */
+    public synchronized void addSatelliteSessionStats(SatelliteSession stats) {
+        SatelliteSession existingStats = find(stats);
+        if (existingStats != null) {
+            existingStats.count += 1;
+        } else {
+            mAtoms.satelliteSession =
+                    insertAtRandomPlace(mAtoms.satelliteSession, stats, mMaxNumSatelliteStats);
+        }
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteIncomingDatagram} to the storage. */
+    public synchronized void addSatelliteIncomingDatagramStats(SatelliteIncomingDatagram stats) {
+        mAtoms.satelliteIncomingDatagram =
+                insertAtRandomPlace(mAtoms.satelliteIncomingDatagram, stats, mMaxNumSatelliteStats);
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteOutgoingDatagram} to the storage. */
+    public synchronized void addSatelliteOutgoingDatagramStats(SatelliteOutgoingDatagram stats) {
+        mAtoms.satelliteOutgoingDatagram =
+                insertAtRandomPlace(mAtoms.satelliteOutgoingDatagram, stats, mMaxNumSatelliteStats);
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteProvision} to the storage. */
+    public synchronized void addSatelliteProvisionStats(SatelliteProvision stats) {
+        mAtoms.satelliteProvision =
+                insertAtRandomPlace(mAtoms.satelliteProvision, stats, mMaxNumSatelliteStats);
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds a new {@link SatelliteSosMessageRecommender} to the storage. */
+    public synchronized void addSatelliteSosMessageRecommenderStats(
+            SatelliteSosMessageRecommender stats) {
+        SatelliteSosMessageRecommender existingStats = find(stats);
+        if (existingStats != null) {
+            existingStats.count += 1;
+        } else {
+            mAtoms.satelliteSosMessageRecommender =
+                    insertAtRandomPlace(mAtoms.satelliteSosMessageRecommender, stats,
+                            mMaxNumSatelliteStats);
+        }
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
     /**
      * Returns and clears the voice call sessions if last pulled longer than {@code
      * minIntervalMillis} ago, otherwise returns {@code null}.
@@ -865,6 +998,16 @@
         }
     }
 
+    /** @return the number of times auto data switch mobile data policy is toggled. */
+    public synchronized int getAutoDataSwitchToggleCount() {
+        int count = mAtoms.autoDataSwitchToggleCount;
+        if (count > 0) {
+            mAtoms.autoDataSwitchToggleCount = 0;
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+        }
+        return count;
+    }
+
     /**
      * Returns and clears the ImsRegistrationFeatureTagStats if last pulled longer than
      * {@code minIntervalMillis} ago, otherwise returns {@code null}.
@@ -1174,6 +1317,135 @@
         return bitmask;
     }
 
+    /**
+     * Returns and clears the OutgoingShortCodeSms if last pulled longer than {@code
+     * minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized OutgoingShortCodeSms[] getOutgoingShortCodeSms(long minIntervalMillis) {
+        if ((getWallTimeMillis() - mAtoms.outgoingShortCodeSmsPullTimestampMillis)
+                > minIntervalMillis) {
+            mAtoms.outgoingShortCodeSmsPullTimestampMillis = getWallTimeMillis();
+            OutgoingShortCodeSms[] previousOutgoingShortCodeSms = mAtoms.outgoingShortCodeSms;
+            mAtoms.outgoingShortCodeSms = new OutgoingShortCodeSms[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return previousOutgoingShortCodeSms;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteController} stats if last pulled longer than {@code
+     * minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteController[] getSatelliteControllerStats(long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteControllerPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteControllerPullTimestampMillis = getWallTimeMillis();
+            SatelliteController[] statsArray = mAtoms.satelliteController;
+            mAtoms.satelliteController = new SatelliteController[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteSession} stats if last pulled longer than {@code
+     * minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteSession[] getSatelliteSessionStats(long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteSessionPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteSessionPullTimestampMillis = getWallTimeMillis();
+            SatelliteSession[] statsArray = mAtoms.satelliteSession;
+            mAtoms.satelliteSession = new SatelliteSession[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteIncomingDatagram} stats if last pulled longer than
+     * {@code minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteIncomingDatagram[] getSatelliteIncomingDatagramStats(
+            long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteIncomingDatagramPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteIncomingDatagramPullTimestampMillis = getWallTimeMillis();
+            SatelliteIncomingDatagram[] statsArray = mAtoms.satelliteIncomingDatagram;
+            mAtoms.satelliteIncomingDatagram = new SatelliteIncomingDatagram[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteOutgoingDatagram} stats if last pulled longer than
+     * {@code minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteOutgoingDatagram[] getSatelliteOutgoingDatagramStats(
+            long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteOutgoingDatagramPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteOutgoingDatagramPullTimestampMillis = getWallTimeMillis();
+            SatelliteOutgoingDatagram[] statsArray = mAtoms.satelliteOutgoingDatagram;
+            mAtoms.satelliteOutgoingDatagram = new SatelliteOutgoingDatagram[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteProvision} stats if last pulled longer than {@code
+     * minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteProvision[] getSatelliteProvisionStats(long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteProvisionPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteProvisionPullTimestampMillis = getWallTimeMillis();
+            SatelliteProvision[] statsArray = mAtoms.satelliteProvision;
+            mAtoms.satelliteProvision = new SatelliteProvision[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the {@link SatelliteSosMessageRecommender} stats if last pulled longer
+     * than {@code minIntervalMillis} ago, otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized SatelliteSosMessageRecommender[] getSatelliteSosMessageRecommenderStats(
+            long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.satelliteSosMessageRecommenderPullTimestampMillis
+                > minIntervalMillis) {
+            mAtoms.satelliteProvisionPullTimestampMillis = getWallTimeMillis();
+            SatelliteSosMessageRecommender[] statsArray = mAtoms.satelliteSosMessageRecommender;
+            mAtoms.satelliteSosMessageRecommender = new SatelliteSosMessageRecommender[0];
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return statsArray;
+        } else {
+            return null;
+        }
+    }
+
     /** Saves {@link PersistAtoms} to a file in private storage immediately. */
     public synchronized void flushAtoms() {
         saveAtomsToFile(0);
@@ -1309,6 +1581,21 @@
                             atoms.unmeteredNetworks,
                             UnmeteredNetworks.class
                     );
+            atoms.outgoingShortCodeSms = sanitizeAtoms(atoms.outgoingShortCodeSms,
+                    OutgoingShortCodeSms.class, mMaxOutgoingShortCodeSms);
+            atoms.satelliteController = sanitizeAtoms(atoms.satelliteController,
+                            SatelliteController.class, mMaxNumSatelliteControllerStats);
+            atoms.satelliteSession = sanitizeAtoms(atoms.satelliteSession,
+                    SatelliteSession.class, mMaxNumSatelliteStats);
+            atoms.satelliteIncomingDatagram = sanitizeAtoms(atoms.satelliteIncomingDatagram,
+                            SatelliteIncomingDatagram.class, mMaxNumSatelliteStats);
+            atoms.satelliteOutgoingDatagram = sanitizeAtoms(atoms.satelliteOutgoingDatagram,
+                            SatelliteOutgoingDatagram.class, mMaxNumSatelliteStats);
+            atoms.satelliteProvision = sanitizeAtoms(atoms.satelliteProvision,
+                            SatelliteProvision.class, mMaxNumSatelliteStats);
+            atoms.satelliteSosMessageRecommender = sanitizeAtoms(
+                    atoms.satelliteSosMessageRecommender, SatelliteSosMessageRecommender.class,
+                    mMaxNumSatelliteStats);
 
             // out of caution, sanitize also the timestamps
             atoms.voiceCallRatUsagePullTimestampMillis =
@@ -1357,7 +1644,20 @@
                     sanitizeTimestamp(atoms.presenceNotifyEventPullTimestampMillis);
             atoms.gbaEventPullTimestampMillis =
                     sanitizeTimestamp(atoms.gbaEventPullTimestampMillis);
-
+            atoms.outgoingShortCodeSmsPullTimestampMillis =
+                    sanitizeTimestamp(atoms.outgoingShortCodeSmsPullTimestampMillis);
+            atoms.satelliteControllerPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteControllerPullTimestampMillis);
+            atoms.satelliteSessionPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteSessionPullTimestampMillis);
+            atoms.satelliteIncomingDatagramPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteIncomingDatagramPullTimestampMillis);
+            atoms.satelliteOutgoingDatagramPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteOutgoingDatagramPullTimestampMillis);
+            atoms.satelliteProvisionPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteProvisionPullTimestampMillis);
+            atoms.satelliteSosMessageRecommenderPullTimestampMillis =
+                    sanitizeTimestamp(atoms.satelliteSosMessageRecommenderPullTimestampMillis);
             return atoms;
         } catch (NoSuchFileException e) {
             Rlog.d(TAG, "PersistAtoms file not found");
@@ -1407,7 +1707,9 @@
                     && state.simSlotIndex == key.simSlotIndex
                     && state.isMultiSim == key.isMultiSim
                     && state.carrierId == key.carrierId
-                    && state.isEmergencyOnly == key.isEmergencyOnly) {
+                    && state.isEmergencyOnly == key.isEmergencyOnly
+                    && state.isInternetPdnUp == key.isInternetPdnUp
+                    && state.foldState == key.foldState) {
                 return state;
             }
         }
@@ -1725,6 +2027,53 @@
     }
 
     /**
+     * Returns OutgoingShortCodeSms atom that has same category, xmlVersion as the given one,
+     * or {@code null} if it does not exist.
+     */
+    private @Nullable OutgoingShortCodeSms find(OutgoingShortCodeSms key) {
+        for (OutgoingShortCodeSms shortCodeSms : mAtoms.outgoingShortCodeSms) {
+            if (shortCodeSms.category == key.category
+                    && shortCodeSms.xmlVersion == key.xmlVersion) {
+                return shortCodeSms;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns SatelliteOutgoingDatagram atom that has same values or {@code null}
+     * if it does not exist.
+     */
+    private @Nullable SatelliteSession find(
+            SatelliteSession key) {
+        for (SatelliteSession stats : mAtoms.satelliteSession) {
+            if (stats.satelliteServiceInitializationResult
+                    == key.satelliteServiceInitializationResult
+                    && stats.satelliteTechnology == key.satelliteTechnology) {
+                return stats;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns SatelliteOutgoingDatagram atom that has same values or {@code null}
+     * if it does not exist.
+     */
+    private @Nullable SatelliteSosMessageRecommender find(
+            SatelliteSosMessageRecommender key) {
+        for (SatelliteSosMessageRecommender stats : mAtoms.satelliteSosMessageRecommender) {
+            if (stats.isDisplaySosMessageSent == key.isDisplaySosMessageSent
+                    && stats.countOfTimerStarted == key.countOfTimerStarted
+                    && stats.isImsRegistered == key.isImsRegistered
+                    && stats.cellularServiceState == key.cellularServiceState) {
+                return stats;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Inserts a new element in a random position in an array with a maximum size.
      *
      * <p>If the array is full, merge with existing item if possible or replace one item randomly.
@@ -1969,6 +2318,13 @@
         atoms.uceEventStatsPullTimestampMillis = currentTime;
         atoms.presenceNotifyEventPullTimestampMillis = currentTime;
         atoms.gbaEventPullTimestampMillis = currentTime;
+        atoms.outgoingShortCodeSmsPullTimestampMillis = currentTime;
+        atoms.satelliteControllerPullTimestampMillis = currentTime;
+        atoms.satelliteSessionPullTimestampMillis = currentTime;
+        atoms.satelliteIncomingDatagramPullTimestampMillis = currentTime;
+        atoms.satelliteOutgoingDatagramPullTimestampMillis = currentTime;
+        atoms.satelliteProvisionPullTimestampMillis = currentTime;
+        atoms.satelliteSosMessageRecommenderPullTimestampMillis = 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
index a9191b6..8d24def 100644
--- a/src/java/com/android/internal/telephony/metrics/RcsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/RcsStats.java
@@ -85,6 +85,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
@@ -129,48 +130,51 @@
     private static final Map<String, Integer> FEATURE_TAGS = new HashMap<>();
 
     static {
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_STANDALONE_MSG.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_STANDALONE_MSG.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_IM.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_IM.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_IM);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_SESSION.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_SESSION.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_SESSION);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS.trim()
+                        .toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER_VIA_SMS);
         FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING.trim().toLowerCase(),
+                FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING.trim()
+                        .toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING);
         FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY.trim().toLowerCase(),
+                FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_POST_CALL.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_POST_CALL.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_POST_CALL);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_MAP.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_MAP.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_SHARED_MAP);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_SKETCH.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_SKETCH.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_SHARED_SKETCH);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_GEO_PUSH);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_GEO_PUSH_VIA_SMS);
         FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION.trim().toLowerCase(),
+                FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION.trim()
+                        .toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION);
         String FeatureTag = FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG;
-        FEATURE_TAGS.put(FeatureTag.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTag.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG);
         FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED.trim().toLowerCase(),
+                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_VERSION_SUPPORTED);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHATBOT_ROLE.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHATBOT_ROLE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_ROLE);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_MMTEL.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_MMTEL.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_MMTEL);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_VIDEO.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_VIDEO.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_VIDEO);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_PRESENCE.trim().toLowerCase(),
+        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_PRESENCE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.IMS_FEATURE_TAG_PRESENCE);
     }
 
@@ -183,34 +187,42 @@
     private static final Map<String, Integer> SERVICE_IDS = new HashMap<>();
 
     static {
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_MMTEL.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_MMTEL.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_MMTEL);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V1.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V1.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V1);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V2.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V2.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V2);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT_OVER_SMS.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT_OVER_SMS.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT_OVER_SMS);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH_VIA_SMS.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH_VIA_SMS.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH_VIA_SMS);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CALL_COMPOSER);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_POST_CALL.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_POST_CALL.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_POST_CALL);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_MAP.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_MAP.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_MAP);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_SKETCH.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_SKETCH.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_SKETCH);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT.trim().toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_STANDALONE.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_STANDALONE.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_STANDALONE
         );
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_ROLE.trim().toLowerCase(),
+        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_ROLE.trim()
+                        .toLowerCase(Locale.ROOT),
                 IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_ROLE);
     }
 
@@ -221,33 +233,33 @@
     private static final Map<String, Integer> MESSAGE_TYPE = new HashMap<>();
 
     static {
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INVITE.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INVITE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_INVITE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_ACK.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_ACK.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_ACK);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_OPTIONS.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_OPTIONS.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_OPTIONS);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_BYE.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_BYE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_BYE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_CANCEL.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_CANCEL.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_CANCEL);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REGISTER.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REGISTER.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_REGISTER);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PRACK.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PRACK.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_PRACK);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_SUBSCRIBE.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_SUBSCRIBE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_SUBSCRIBE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_NOTIFY.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_NOTIFY.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_NOTIFY);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PUBLISH.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PUBLISH.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_PUBLISH);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INFO.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INFO.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_INFO);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REFER.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REFER.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_REFER);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_MESSAGE.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_MESSAGE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_MESSAGE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_UPDATE.trim().toLowerCase(),
+        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_UPDATE.trim().toLowerCase(Locale.ROOT),
                 TelephonyProtoEnums.SIP_REQUEST_UPDATE);
     }
 
@@ -1570,28 +1582,28 @@
     /** 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(),
+        return FEATURE_TAGS.getOrDefault(tagName.trim().toLowerCase(Locale.ROOT),
                 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(),
+        return SERVICE_IDS.getOrDefault(serviceId.trim().toLowerCase(Locale.ROOT),
                 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(),
+        return MESSAGE_TYPE.getOrDefault(messageType.trim().toLowerCase(Locale.ROOT),
                 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(),
+        return NOTIFY_REASONS.getOrDefault(reason.trim().toLowerCase(Locale.ROOT),
                 PRESENCE_NOTIFY_EVENT__REASON__REASON_CUSTOM);
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
new file mode 100644
index 0000000..7ff370c
--- /dev/null
+++ b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
@@ -0,0 +1,905 @@
+/*
+ * Copyright (C) 2023 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 com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
+import com.android.telephony.Rlog;
+
+/** Tracks Satellite metrics for each phone */
+public class SatelliteStats {
+    private static final String TAG = SatelliteStats.class.getSimpleName();
+
+    private final PersistAtomsStorage mAtomsStorage =
+            PhoneFactory.getMetricsCollector().getAtomsStorage();
+
+    private static SatelliteStats sInstance = null;
+
+    /** Gets the instance of SatelliteStats */
+    public static SatelliteStats getInstance() {
+        if (sInstance == null) {
+            Rlog.d(TAG, "SatelliteStats created.");
+            synchronized (SatelliteStats.class) {
+                sInstance = new SatelliteStats();
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteController) atom.
+     * Refer to {@link #onSatelliteControllerMetrics(SatelliteControllerParams)}.
+     */
+    public class SatelliteControllerParams {
+        private final int mCountOfSatelliteServiceEnablementsSuccess;
+        private final int mCountOfSatelliteServiceEnablementsFail;
+        private final int mCountOfOutgoingDatagramSuccess;
+        private final int mCountOfOutgoingDatagramFail;
+        private final int mCountOfIncomingDatagramSuccess;
+        private final int mCountOfIncomingDatagramFail;
+        private final int mCountOfDatagramTypeSosSmsSuccess;
+        private final int mCountOfDatagramTypeSosSmsFail;
+        private final int mCountOfDatagramTypeLocationSharingSuccess;
+        private final int mCountOfDatagramTypeLocationSharingFail;
+        private final int mCountOfProvisionSuccess;
+        private final int mCountOfProvisionFail;
+        private final int mCountOfDeprovisionSuccess;
+        private final int mCountOfDeprovisionFail;
+        private final int mTotalServiceUptimeSec;
+        private final int mTotalBatteryConsumptionPercent;
+        private final int mTotalBatteryChargedTimeSec;
+
+        private SatelliteControllerParams(Builder builder) {
+            this.mCountOfSatelliteServiceEnablementsSuccess =
+                    builder.mCountOfSatelliteServiceEnablementsSuccess;
+            this.mCountOfSatelliteServiceEnablementsFail =
+                    builder.mCountOfSatelliteServiceEnablementsFail;
+            this.mCountOfOutgoingDatagramSuccess = builder.mCountOfOutgoingDatagramSuccess;
+            this.mCountOfOutgoingDatagramFail = builder.mCountOfOutgoingDatagramFail;
+            this.mCountOfIncomingDatagramSuccess = builder.mCountOfIncomingDatagramSuccess;
+            this.mCountOfIncomingDatagramFail = builder.mCountOfIncomingDatagramFail;
+            this.mCountOfDatagramTypeSosSmsSuccess = builder.mCountOfDatagramTypeSosSmsSuccess;
+            this.mCountOfDatagramTypeSosSmsFail = builder.mCountOfDatagramTypeSosSmsFail;
+            this.mCountOfDatagramTypeLocationSharingSuccess =
+                    builder.mCountOfDatagramTypeLocationSharingSuccess;
+            this.mCountOfDatagramTypeLocationSharingFail =
+                    builder.mCountOfDatagramTypeLocationSharingFail;
+            this.mCountOfProvisionSuccess = builder.mCountOfProvisionSuccess;
+            this.mCountOfProvisionFail = builder.mCountOfProvisionFail;
+            this.mCountOfDeprovisionSuccess = builder.mCountOfDeprovisionSuccess;
+            this.mCountOfDeprovisionFail = builder.mCountOfDeprovisionFail;
+            this.mTotalServiceUptimeSec = builder.mTotalServiceUptimeSec;
+            this.mTotalBatteryConsumptionPercent = builder.mTotalBatteryConsumptionPercent;
+            this.mTotalBatteryChargedTimeSec = builder.mTotalBatteryChargedTimeSec;
+        }
+
+        public int getCountOfSatelliteServiceEnablementsSuccess() {
+            return mCountOfSatelliteServiceEnablementsSuccess;
+        }
+
+        public int getCountOfSatelliteServiceEnablementsFail() {
+            return mCountOfSatelliteServiceEnablementsFail;
+        }
+
+        public int getCountOfOutgoingDatagramSuccess() {
+            return mCountOfOutgoingDatagramSuccess;
+        }
+
+        public int getCountOfOutgoingDatagramFail() {
+            return mCountOfOutgoingDatagramFail;
+        }
+
+        public int getCountOfIncomingDatagramSuccess() {
+            return mCountOfIncomingDatagramSuccess;
+        }
+
+        public int getCountOfIncomingDatagramFail() {
+            return mCountOfIncomingDatagramFail;
+        }
+
+        public int getCountOfDatagramTypeSosSmsSuccess() {
+            return mCountOfDatagramTypeSosSmsSuccess;
+        }
+
+        public int getCountOfDatagramTypeSosSmsFail() {
+            return mCountOfDatagramTypeSosSmsFail;
+        }
+
+        public int getCountOfDatagramTypeLocationSharingSuccess() {
+            return mCountOfDatagramTypeLocationSharingSuccess;
+        }
+
+        public int getCountOfDatagramTypeLocationSharingFail() {
+            return mCountOfDatagramTypeLocationSharingFail;
+        }
+
+        public int getCountOfProvisionSuccess() {
+            return mCountOfProvisionSuccess;
+        }
+
+        public int getCountOfProvisionFail() {
+            return mCountOfProvisionFail;
+        }
+
+        public int getCountOfDeprovisionSuccess() {
+            return mCountOfDeprovisionSuccess;
+        }
+
+        public int getCountOfDeprovisionFail() {
+            return mCountOfDeprovisionFail;
+        }
+
+        public int getTotalServiceUptimeSec() {
+            return mTotalServiceUptimeSec;
+        }
+
+        public int getTotalBatteryConsumptionPercent() {
+            return mTotalBatteryConsumptionPercent;
+        }
+
+        public int getTotalBatteryChargedTimeSec() {
+            return mTotalBatteryChargedTimeSec;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteControllerParams} data structure class
+         */
+        public static class Builder {
+            private int mCountOfSatelliteServiceEnablementsSuccess = 0;
+            private int mCountOfSatelliteServiceEnablementsFail = 0;
+            private int mCountOfOutgoingDatagramSuccess = 0;
+            private int mCountOfOutgoingDatagramFail = 0;
+            private int mCountOfIncomingDatagramSuccess = 0;
+            private int mCountOfIncomingDatagramFail = 0;
+            private int mCountOfDatagramTypeSosSmsSuccess = 0;
+            private int mCountOfDatagramTypeSosSmsFail = 0;
+            private int mCountOfDatagramTypeLocationSharingSuccess = 0;
+            private int mCountOfDatagramTypeLocationSharingFail = 0;
+            private int mCountOfProvisionSuccess;
+            private int mCountOfProvisionFail;
+            private int mCountOfDeprovisionSuccess;
+            private int mCountOfDeprovisionFail;
+            private int mTotalServiceUptimeSec = 0;
+            private int mTotalBatteryConsumptionPercent = 0;
+            private int mTotalBatteryChargedTimeSec = 0;
+
+            /**
+             * Sets countOfSatelliteServiceEnablementsSuccess value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfSatelliteServiceEnablementsSuccess(
+                    int countOfSatelliteServiceEnablementsSuccess) {
+                this.mCountOfSatelliteServiceEnablementsSuccess =
+                        countOfSatelliteServiceEnablementsSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfSatelliteServiceEnablementsFail value of {@link SatelliteController} atom
+             * then returns Builder class
+             */
+            public Builder setCountOfSatelliteServiceEnablementsFail(
+                    int countOfSatelliteServiceEnablementsFail) {
+                this.mCountOfSatelliteServiceEnablementsFail =
+                        countOfSatelliteServiceEnablementsFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfOutgoingDatagramSuccess value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfOutgoingDatagramSuccess(int countOfOutgoingDatagramSuccess) {
+                this.mCountOfOutgoingDatagramSuccess = countOfOutgoingDatagramSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfOutgoingDatagramFail value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfOutgoingDatagramFail(int countOfOutgoingDatagramFail) {
+                this.mCountOfOutgoingDatagramFail = countOfOutgoingDatagramFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfIncomingDatagramSuccess value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfIncomingDatagramSuccess(int countOfIncomingDatagramSuccess) {
+                this.mCountOfIncomingDatagramSuccess = countOfIncomingDatagramSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfIncomingDatagramFail value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfIncomingDatagramFail(int countOfIncomingDatagramFail) {
+                this.mCountOfIncomingDatagramFail = countOfIncomingDatagramFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfDatagramTypeSosSmsSuccess value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfDatagramTypeSosSmsSuccess(
+                    int countOfDatagramTypeSosSmsSuccess) {
+                this.mCountOfDatagramTypeSosSmsSuccess = countOfDatagramTypeSosSmsSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfDatagramTypeSosSmsFail value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setCountOfDatagramTypeSosSmsFail(int countOfDatagramTypeSosSmsFail) {
+                this.mCountOfDatagramTypeSosSmsFail = countOfDatagramTypeSosSmsFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfDatagramTypeLocationSharingSuccess value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfDatagramTypeLocationSharingSuccess(
+                    int countOfDatagramTypeLocationSharingSuccess) {
+                this.mCountOfDatagramTypeLocationSharingSuccess =
+                        countOfDatagramTypeLocationSharingSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfDatagramTypeLocationSharingFail value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfDatagramTypeLocationSharingFail(
+                    int countOfDatagramTypeLocationSharingFail) {
+                this.mCountOfDatagramTypeLocationSharingFail =
+                        countOfDatagramTypeLocationSharingFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfProvisionSuccess value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfProvisionSuccess(int countOfProvisionSuccess) {
+                this.mCountOfProvisionSuccess = countOfProvisionSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfProvisionFail value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfProvisionFail(int countOfProvisionFail) {
+                this.mCountOfProvisionFail = countOfProvisionFail;
+                return this;
+            }
+
+            /**
+             * Sets countOfDeprovisionSuccess value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfDeprovisionSuccess(int countOfDeprovisionSuccess) {
+                this.mCountOfDeprovisionSuccess = countOfDeprovisionSuccess;
+                return this;
+            }
+
+            /**
+             * Sets countOfDeprovisionSuccess value of {@link SatelliteController}
+             * atom then returns Builder class
+             */
+            public Builder setCountOfDeprovisionFail(int countOfDeprovisionFail) {
+                this.mCountOfDeprovisionFail = countOfDeprovisionFail;
+                return this;
+            }
+
+            /**
+             * Sets totalServiceUptimeSec value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setTotalServiceUptimeSec(int totalServiceUptimeSec) {
+                this.mTotalServiceUptimeSec = totalServiceUptimeSec;
+                return this;
+            }
+
+            /**
+             * Sets totalBatteryConsumptionPercent value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setTotalBatteryConsumptionPercent(int totalBatteryConsumptionPercent) {
+                this.mTotalBatteryConsumptionPercent = totalBatteryConsumptionPercent;
+                return this;
+            }
+
+            /**
+             * Sets totalBatteryChargedTimeSec value of {@link SatelliteController} atom then
+             * returns Builder class
+             */
+            public Builder setTotalBatteryChargedTimeSec(int totalBatteryChargedTimeSec) {
+                this.mTotalBatteryChargedTimeSec = totalBatteryChargedTimeSec;
+                return this;
+            }
+
+            /**
+             * Returns ControllerParams, which contains whole component of
+             * {@link SatelliteController} atom
+             */
+            public SatelliteControllerParams build() {
+                return new SatelliteStats()
+                        .new SatelliteControllerParams(this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "ControllerParams("
+                    + ", countOfSatelliteServiceEnablementsSuccess="
+                    + mCountOfSatelliteServiceEnablementsSuccess
+                    + ", countOfSatelliteServiceEnablementsFail="
+                    + mCountOfSatelliteServiceEnablementsFail
+                    + ", countOfOutgoingDatagramSuccess=" + mCountOfOutgoingDatagramSuccess
+                    + ", countOfOutgoingDatagramFail=" + mCountOfOutgoingDatagramFail
+                    + ", countOfIncomingDatagramSuccess=" + mCountOfIncomingDatagramSuccess
+                    + ", countOfIncomingDatagramFail=" + mCountOfIncomingDatagramFail
+                    + ", countOfDatagramTypeSosSms=" + mCountOfDatagramTypeSosSmsSuccess
+                    + ", countOfDatagramTypeSosSms=" + mCountOfDatagramTypeSosSmsFail
+                    + ", countOfDatagramTypeLocationSharing="
+                    + mCountOfDatagramTypeLocationSharingSuccess
+                    + ", countOfDatagramTypeLocationSharing="
+                    + mCountOfDatagramTypeLocationSharingFail
+                    + ", serviceUptimeSec=" + mTotalServiceUptimeSec
+                    + ", batteryConsumptionPercent=" + mTotalBatteryConsumptionPercent
+                    + ", batteryChargedTimeSec=" + mTotalBatteryChargedTimeSec
+                    + ")";
+        }
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteSession) atom.
+     * Refer to {@link #onSatelliteSessionMetrics(SatelliteSessionParams)}.
+     */
+    public class SatelliteSessionParams {
+        private final int mSatelliteServiceInitializationResult;
+        private final int mSatelliteTechnology;
+
+        private SatelliteSessionParams(Builder builder) {
+            this.mSatelliteServiceInitializationResult =
+                    builder.mSatelliteServiceInitializationResult;
+            this.mSatelliteTechnology = builder.mSatelliteTechnology;
+        }
+
+        public int getSatelliteServiceInitializationResult() {
+            return mSatelliteServiceInitializationResult;
+        }
+
+        public int getSatelliteTechnology() {
+            return mSatelliteTechnology;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteSessionParams} data structure class
+         */
+        public static class Builder {
+            private int mSatelliteServiceInitializationResult = -1;
+            private int mSatelliteTechnology = -1;
+
+            /**
+             * Sets satelliteServiceInitializationResult value of {@link SatelliteSession}
+             * atom then returns Builder class
+             */
+            public Builder setSatelliteServiceInitializationResult(
+                    int satelliteServiceInitializationResult) {
+                this.mSatelliteServiceInitializationResult = satelliteServiceInitializationResult;
+                return this;
+            }
+
+            /**
+             * Sets satelliteTechnology value of {@link SatelliteSession} atoms then
+             * returns Builder class
+             */
+            public Builder setSatelliteTechnology(int satelliteTechnology) {
+                this.mSatelliteTechnology = satelliteTechnology;
+                return this;
+            }
+
+            /**
+             * Returns SessionParams, which contains whole component of
+             * {@link SatelliteSession} atom
+             */
+            public SatelliteSessionParams build() {
+                return new SatelliteStats()
+                        .new SatelliteSessionParams(this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SessionParams("
+                    + ", satelliteServiceInitializationResult="
+                    + mSatelliteServiceInitializationResult
+                    + ", satelliteTechnology=" + mSatelliteTechnology
+                    + ")";
+        }
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteIncomingDatagram} atom.
+     * Refer to {@link #onSatelliteIncomingDatagramMetrics(SatelliteIncomingDatagramParams)}.
+     */
+    public class SatelliteIncomingDatagramParams {
+        private final int mResultCode;
+        private final int mDatagramSizeBytes;
+        private final long mDatagramTransferTimeMillis;
+
+        private SatelliteIncomingDatagramParams(Builder builder) {
+            this.mResultCode = builder.mResultCode;
+            this.mDatagramSizeBytes = builder.mDatagramSizeBytes;
+            this.mDatagramTransferTimeMillis = builder.mDatagramTransferTimeMillis;
+        }
+
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        public int getDatagramSizeBytes() {
+            return mDatagramSizeBytes;
+        }
+
+        public long getDatagramTransferTimeMillis() {
+            return mDatagramTransferTimeMillis;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteIncomingDatagramParams} data structure class
+         */
+        public static class Builder {
+            private int mResultCode = -1;
+            private int mDatagramSizeBytes = -1;
+            private long mDatagramTransferTimeMillis = -1;
+
+            /**
+             * Sets resultCode value of {@link SatelliteIncomingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setResultCode(int resultCode) {
+                this.mResultCode = resultCode;
+                return this;
+            }
+
+            /**
+             * Sets datagramSizeBytes value of {@link SatelliteIncomingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setDatagramSizeBytes(int datagramSizeBytes) {
+                this.mDatagramSizeBytes = datagramSizeBytes;
+                return this;
+            }
+
+            /**
+             * Sets datagramTransferTimeMillis value of {@link SatelliteIncomingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setDatagramTransferTimeMillis(long datagramTransferTimeMillis) {
+                this.mDatagramTransferTimeMillis = datagramTransferTimeMillis;
+                return this;
+            }
+
+            /**
+             * Returns IncomingDatagramParams, which contains whole component of
+             * {@link SatelliteIncomingDatagram} atom
+             */
+            public SatelliteIncomingDatagramParams build() {
+                return new SatelliteStats()
+                        .new SatelliteIncomingDatagramParams(Builder.this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "IncomingDatagramParams("
+                    + ", resultCode=" + mResultCode
+                    + ", datagramSizeBytes=" + mDatagramSizeBytes
+                    + ", datagramTransferTimeMillis=" + mDatagramTransferTimeMillis + ")";
+        }
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteOutgoingDatagram} atom.
+     * Refer to {@link #onSatelliteOutgoingDatagramMetrics(SatelliteOutgoingDatagramParams)}.
+     */
+    public class SatelliteOutgoingDatagramParams {
+        private final int mDatagramType;
+        private final int mResultCode;
+        private final int mDatagramSizeBytes;
+        private final long mDatagramTransferTimeMillis;
+
+        private SatelliteOutgoingDatagramParams(Builder builder) {
+            this.mDatagramType = builder.mDatagramType;
+            this.mResultCode = builder.mResultCode;
+            this.mDatagramSizeBytes = builder.mDatagramSizeBytes;
+            this.mDatagramTransferTimeMillis = builder.mDatagramTransferTimeMillis;
+        }
+
+        public int getDatagramType() {
+            return mDatagramType;
+        }
+
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        public int getDatagramSizeBytes() {
+            return mDatagramSizeBytes;
+        }
+
+        public long getDatagramTransferTimeMillis() {
+            return mDatagramTransferTimeMillis;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteOutgoingDatagramParams} data structure class
+         */
+        public static class Builder {
+            private int mDatagramType = -1;
+            private int mResultCode = -1;
+            private int mDatagramSizeBytes = -1;
+            private long mDatagramTransferTimeMillis = -1;
+
+            /**
+             * Sets datagramType value of {@link SatelliteOutgoingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setDatagramType(int datagramType) {
+                this.mDatagramType = datagramType;
+                return this;
+            }
+
+            /**
+             * Sets resultCode value of {@link SatelliteOutgoingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setResultCode(int resultCode) {
+                this.mResultCode = resultCode;
+                return this;
+            }
+
+            /**
+             * Sets datagramSizeBytes value of {@link SatelliteOutgoingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setDatagramSizeBytes(int datagramSizeBytes) {
+                this.mDatagramSizeBytes = datagramSizeBytes;
+                return this;
+            }
+
+            /**
+             * Sets datagramTransferTimeMillis value of {@link SatelliteOutgoingDatagram} atom
+             * then returns Builder class
+             */
+            public Builder setDatagramTransferTimeMillis(long datagramTransferTimeMillis) {
+                this.mDatagramTransferTimeMillis = datagramTransferTimeMillis;
+                return this;
+            }
+
+            /**
+             * Returns OutgoingDatagramParams, which contains whole component of
+             * {@link SatelliteOutgoingDatagram} atom
+             */
+            public SatelliteOutgoingDatagramParams build() {
+                return new SatelliteStats()
+                        .new SatelliteOutgoingDatagramParams(Builder.this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "OutgoingDatagramParams("
+                    + "datagramType=" + mDatagramType
+                    + ", resultCode=" + mResultCode
+                    + ", datagramSizeBytes=" + mDatagramSizeBytes
+                    + ", datagramTransferTimeMillis=" + mDatagramTransferTimeMillis + ")";
+        }
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteProvision} atom.
+     * Refer to {@link #onSatelliteProvisionMetrics(SatelliteProvisionParams)}.
+     */
+    public class SatelliteProvisionParams {
+        private final int mResultCode;
+        private final int mProvisioningTimeSec;
+        private final boolean mIsProvisionRequest;
+        private final boolean mIsCanceled;
+
+        private SatelliteProvisionParams(Builder builder) {
+            this.mResultCode = builder.mResultCode;
+            this.mProvisioningTimeSec = builder.mProvisioningTimeSec;
+            this.mIsProvisionRequest = builder.mIsProvisionRequest;
+            this.mIsCanceled = builder.mIsCanceled;
+        }
+
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        public int getProvisioningTimeSec() {
+            return mProvisioningTimeSec;
+        }
+
+        public boolean getIsProvisionRequest() {
+            return mIsProvisionRequest;
+        }
+
+        public boolean getIsCanceled() {
+            return mIsCanceled;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteProvisionParams} data structure class
+         */
+        public static class Builder {
+            private int mResultCode = -1;
+            private int mProvisioningTimeSec = -1;
+            private boolean mIsProvisionRequest = false;
+            private boolean mIsCanceled = false;
+
+            /**
+             * Sets resultCode value of {@link SatelliteProvision} atom
+             * then returns Builder class
+             */
+            public Builder setResultCode(int resultCode) {
+                this.mResultCode = resultCode;
+                return this;
+            }
+
+            /**
+             * Sets provisioningTimeSec value of {@link SatelliteProvision} atom
+             * then returns Builder class
+             */
+            public Builder setProvisioningTimeSec(int provisioningTimeSec) {
+                this.mProvisioningTimeSec = provisioningTimeSec;
+                return this;
+            }
+
+            /**
+             * Sets isProvisionRequest value of {@link SatelliteProvision} atom
+             * then returns Builder class
+             */
+            public Builder setIsProvisionRequest(boolean isProvisionRequest) {
+                this.mIsProvisionRequest = isProvisionRequest;
+                return this;
+            }
+
+            /**
+             * Sets isCanceled value of {@link SatelliteProvision} atom
+             * then returns Builder class
+             */
+            public Builder setIsCanceled(boolean isCanceled) {
+                this.mIsCanceled = isCanceled;
+                return this;
+            }
+
+            /**
+             * Returns ProvisionParams, which contains whole component of
+             * {@link SatelliteProvision} atom
+             */
+            public SatelliteProvisionParams build() {
+                return new SatelliteStats()
+                        .new SatelliteProvisionParams(Builder.this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "ProvisionParams("
+                    + "resultCode=" + mResultCode
+                    + ", provisioningTimeSec=" + mProvisioningTimeSec
+                    + ", isProvisionRequest=" + mIsProvisionRequest
+                    + ", isCanceled" + mIsCanceled + ")";
+        }
+    }
+
+    /**
+     * A data class to contain whole component of {@link SatelliteSosMessageRecommender} atom.
+     * Refer to {@link #onSatelliteSosMessageRecommender(SatelliteSosMessageRecommenderParams)}.
+     */
+    public class SatelliteSosMessageRecommenderParams {
+        private final boolean mIsDisplaySosMessageSent;
+        private final int mCountOfTimerStarted;
+        private final boolean mIsImsRegistered;
+        private final int mCellularServiceState;
+
+        private SatelliteSosMessageRecommenderParams(Builder builder) {
+            this.mIsDisplaySosMessageSent = builder.mIsDisplaySosMessageSent;
+            this.mCountOfTimerStarted = builder.mCountOfTimerStarted;
+            this.mIsImsRegistered = builder.mIsImsRegistered;
+            this.mCellularServiceState = builder.mCellularServiceState;
+        }
+
+        public boolean isDisplaySosMessageSent() {
+            return mIsDisplaySosMessageSent;
+        }
+
+        public int getCountOfTimerStarted() {
+            return mCountOfTimerStarted;
+        }
+
+        public boolean isImsRegistered() {
+            return mIsImsRegistered;
+        }
+
+        public int getCellularServiceState() {
+            return mCellularServiceState;
+        }
+
+        /**
+         * A builder class to create {@link SatelliteProvisionParams} data structure class
+         */
+        public static class Builder {
+            private boolean mIsDisplaySosMessageSent = false;
+            private int mCountOfTimerStarted = -1;
+            private boolean mIsImsRegistered = false;
+            private int mCellularServiceState = -1;
+
+            /**
+             * Sets resultCode value of {@link SatelliteSosMessageRecommender} atom
+             * then returns Builder class
+             */
+            public Builder setDisplaySosMessageSent(
+                    boolean isDisplaySosMessageSent) {
+                this.mIsDisplaySosMessageSent = isDisplaySosMessageSent;
+                return this;
+            }
+
+            /**
+             * Sets countOfTimerIsStarted value of {@link SatelliteSosMessageRecommender} atom
+             * then returns Builder class
+             */
+            public Builder setCountOfTimerStarted(int countOfTimerStarted) {
+                this.mCountOfTimerStarted = countOfTimerStarted;
+                return this;
+            }
+
+            /**
+             * Sets isImsRegistered value of {@link SatelliteSosMessageRecommender} atom
+             * then returns Builder class
+             */
+            public Builder setImsRegistered(boolean isImsRegistered) {
+                this.mIsImsRegistered = isImsRegistered;
+                return this;
+            }
+
+            /**
+             * Sets cellularServiceState value of {@link SatelliteSosMessageRecommender} atom
+             * then returns Builder class
+             */
+            public Builder setCellularServiceState(int cellularServiceState) {
+                this.mCellularServiceState = cellularServiceState;
+                return this;
+            }
+
+            /**
+             * Returns SosMessageRecommenderParams, which contains whole component of
+             * {@link SatelliteSosMessageRecommenderParams} atom
+             */
+            public SatelliteSosMessageRecommenderParams build() {
+                return new SatelliteStats()
+                        .new SatelliteSosMessageRecommenderParams(Builder.this);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SosMessageRecommenderParams("
+                    + "isDisplaySosMessageSent=" + mIsDisplaySosMessageSent
+                    + ", countOfTimerStarted=" + mCountOfTimerStarted
+                    + ", isImsRegistered=" + mIsImsRegistered
+                    + ", cellularServiceState=" + mCellularServiceState + ")";
+        }
+    }
+
+    /**  Create a new atom or update an existing atom for SatelliteController metrics */
+    public synchronized void onSatelliteControllerMetrics(SatelliteControllerParams param) {
+        SatelliteController proto = new SatelliteController();
+        proto.countOfSatelliteServiceEnablementsSuccess =
+                param.getCountOfSatelliteServiceEnablementsSuccess();
+        proto.countOfSatelliteServiceEnablementsFail =
+                param.getCountOfSatelliteServiceEnablementsFail();
+        proto.countOfOutgoingDatagramSuccess = param.getCountOfOutgoingDatagramSuccess();
+        proto.countOfOutgoingDatagramFail = param.getCountOfOutgoingDatagramFail();
+        proto.countOfIncomingDatagramSuccess = param.getCountOfIncomingDatagramSuccess();
+        proto.countOfIncomingDatagramFail = param.getCountOfIncomingDatagramFail();
+        proto.countOfDatagramTypeSosSmsSuccess = param.getCountOfDatagramTypeSosSmsSuccess();
+        proto.countOfDatagramTypeSosSmsFail = param.getCountOfDatagramTypeSosSmsFail();
+        proto.countOfDatagramTypeLocationSharingSuccess =
+                param.getCountOfDatagramTypeLocationSharingSuccess();
+        proto.countOfDatagramTypeLocationSharingFail =
+                param.getCountOfDatagramTypeLocationSharingFail();
+        proto.countOfProvisionSuccess = param.getCountOfProvisionSuccess();
+        proto.countOfProvisionFail = param.getCountOfProvisionFail();
+        proto.countOfDeprovisionSuccess = param.getCountOfDeprovisionSuccess();
+        proto.countOfDeprovisionFail = param.getCountOfDeprovisionFail();
+        proto.totalServiceUptimeSec = param.getTotalServiceUptimeSec();
+        proto.totalBatteryConsumptionPercent = param.getTotalBatteryConsumptionPercent();
+        proto.totalBatteryChargedTimeSec = param.getTotalBatteryChargedTimeSec();
+
+        mAtomsStorage.addSatelliteControllerStats(proto);
+    }
+
+    /**  Create a new atom or update an existing atom for SatelliteSession metrics */
+    public synchronized void onSatelliteSessionMetrics(SatelliteSessionParams param) {
+        SatelliteSession proto = new SatelliteSession();
+        proto.satelliteServiceInitializationResult =
+                param.getSatelliteServiceInitializationResult();
+        proto.satelliteTechnology = param.getSatelliteTechnology();
+        proto.count = 1;
+        mAtomsStorage.addSatelliteSessionStats(proto);
+    }
+
+    /**  Create a new atom for SatelliteIncomingDatagram metrics */
+    public synchronized void onSatelliteIncomingDatagramMetrics(
+            SatelliteIncomingDatagramParams param) {
+        SatelliteIncomingDatagram proto = new SatelliteIncomingDatagram();
+        proto.resultCode = param.getResultCode();
+        proto.datagramSizeBytes = param.getDatagramSizeBytes();
+        proto.datagramTransferTimeMillis = param.getDatagramTransferTimeMillis();
+        mAtomsStorage.addSatelliteIncomingDatagramStats(proto);
+    }
+
+    /**  Create a new atom for SatelliteOutgoingDatagram metrics */
+    public synchronized void onSatelliteOutgoingDatagramMetrics(
+            SatelliteOutgoingDatagramParams param) {
+        SatelliteOutgoingDatagram proto = new SatelliteOutgoingDatagram();
+        proto.datagramType = param.getDatagramType();
+        proto.resultCode = param.getResultCode();
+        proto.datagramSizeBytes = param.getDatagramSizeBytes();
+        proto.datagramTransferTimeMillis = param.getDatagramTransferTimeMillis();
+        mAtomsStorage.addSatelliteOutgoingDatagramStats(proto);
+    }
+
+    /**  Create a new atom for SatelliteProvision metrics */
+    public synchronized void onSatelliteProvisionMetrics(SatelliteProvisionParams param) {
+        SatelliteProvision proto = new SatelliteProvision();
+        proto.resultCode = param.getResultCode();
+        proto.provisioningTimeSec = param.getProvisioningTimeSec();
+        proto.isProvisionRequest = param.getIsProvisionRequest();
+        proto.isCanceled = param.getIsCanceled();
+        mAtomsStorage.addSatelliteProvisionStats(proto);
+    }
+
+    /**  Create a new atom or update an existing atom for SatelliteSosMessageRecommender metrics */
+    public synchronized void onSatelliteSosMessageRecommender(
+            SatelliteSosMessageRecommenderParams param) {
+        SatelliteSosMessageRecommender proto = new SatelliteSosMessageRecommender();
+        proto.isDisplaySosMessageSent = param.isDisplaySosMessageSent();
+        proto.countOfTimerStarted = param.getCountOfTimerStarted();
+        proto.isImsRegistered = param.isImsRegistered();
+        proto.cellularServiceState = param.getCellularServiceState();
+        proto.count = 1;
+        mAtomsStorage.addSatelliteSosMessageRecommenderStats(proto);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
index 9d9088e..b830cd0 100644
--- a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
@@ -15,7 +15,13 @@
  */
 
 package com.android.internal.telephony.metrics;
+import static android.telephony.TelephonyManager.DATA_CONNECTED;
 
+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 android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.SystemClock;
 import android.telephony.AccessNetworkConstants;
@@ -25,33 +31,36 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 
-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 com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.data.DataNetwork;
+import com.android.internal.telephony.data.DataNetworkController;
+import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
 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;
 
+import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
 /** Tracks service state duration and switch metrics for each phone. */
-public class ServiceStateStats {
+public class ServiceStateStats extends DataNetworkControllerCallback {
     private static final String TAG = ServiceStateStats.class.getSimpleName();
 
     private final AtomicReference<TimestampedServiceState> mLastState =
             new AtomicReference<>(new TimestampedServiceState(null, 0L));
     private final Phone mPhone;
     private final PersistAtomsStorage mStorage;
+    private final DeviceStateHelper mDeviceStateHelper;
 
     public ServiceStateStats(Phone phone) {
+        super(Runnable::run);
         mPhone = phone;
         mStorage = PhoneFactory.getMetricsCollector().getAtomsStorage();
+        mDeviceStateHelper = PhoneFactory.getMetricsCollector().getDeviceStateHelper();
     }
 
     /** Finalizes the durations of the current service state segment. */
@@ -80,6 +89,21 @@
         addServiceState(lastState, now);
     }
 
+    /** Registers for internet pdn connected callback. */
+    public void registerDataNetworkControllerCallback() {
+        mPhone.getDataNetworkController().registerDataNetworkControllerCallback(this);
+    }
+
+    /** Updates service state when internet pdn gets connected. */
+    public void onInternetDataNetworkConnected(@NonNull List<DataNetwork> internetNetworks) {
+        onInternetDataNetworkChanged(true);
+    }
+
+    /** Updates service state when internet pdn gets disconnected. */
+    public void onInternetDataNetworkDisconnected() {
+        onInternetDataNetworkChanged(false);
+    }
+
     /** Updates the current service state. */
     public void onServiceStateChanged(ServiceState serviceState) {
         final long now = getTimeMillis();
@@ -97,7 +121,8 @@
             newState.isMultiSim = SimSlotState.isMultiSim();
             newState.carrierId = mPhone.getCarrierId();
             newState.isEmergencyOnly = isEmergencyOnly(serviceState);
-
+            newState.isInternetPdnUp = isInternetPdnUp(mPhone);
+            newState.foldState = mDeviceStateHelper.getFoldState();
             TimestampedServiceState prevState =
                     mLastState.getAndSet(new TimestampedServiceState(newState, now));
             addServiceStateAndSwitch(
@@ -105,6 +130,26 @@
         }
     }
 
+    /** Updates the fold state of the device for the current service state. */
+    public void onFoldStateChanged(int foldState) {
+        final long now = getTimeMillis();
+        CellularServiceState lastServiceState = mLastState.get().mServiceState;
+        if (lastServiceState == null || lastServiceState.foldState == foldState) {
+            // Not need to update the fold state if modem is off or if is the
+            // same fold state
+            return;
+        } else {
+            TimestampedServiceState lastState =
+                    mLastState.getAndUpdate(
+                            state -> {
+                                CellularServiceState newServiceState = copyOf(state.mServiceState);
+                                newServiceState.foldState = foldState;
+                                return new TimestampedServiceState(newServiceState, now);
+                            });
+            addServiceState(lastState, now);
+        }
+    }
+
     private void addServiceState(TimestampedServiceState prevState, long now) {
         addServiceStateAndSwitch(prevState, now, null);
     }
@@ -224,6 +269,8 @@
         copy.carrierId = state.carrierId;
         copy.totalTimeMillis = state.totalTimeMillis;
         copy.isEmergencyOnly = state.isEmergencyOnly;
+        copy.isInternetPdnUp = state.isInternetPdnUp;
+        copy.foldState = state.foldState;
         return copy;
     }
 
@@ -310,6 +357,29 @@
                 || nrState == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED;
     }
 
+    private static boolean isInternetPdnUp(Phone phone) {
+        DataNetworkController dataNetworkController = phone.getDataNetworkController();
+        if (dataNetworkController != null) {
+            return dataNetworkController.getInternetDataNetworkState() == DATA_CONNECTED;
+        }
+        return false;
+    }
+
+    private void onInternetDataNetworkChanged(boolean internetPdnUp) {
+        final long now = getTimeMillis();
+        TimestampedServiceState lastState =
+                mLastState.getAndUpdate(
+                        state -> {
+                            if (state.mServiceState == null) {
+                                return new TimestampedServiceState(null, now);
+                            }
+                            CellularServiceState newServiceState = copyOf(state.mServiceState);
+                            newServiceState.isInternetPdnUp = internetPdnUp;
+                            return new TimestampedServiceState(newServiceState, now);
+                        });
+        addServiceState(lastState, now);
+    }
+
     @VisibleForTesting
     protected long getTimeMillis() {
         return SystemClock.elapsedRealtime();
diff --git a/src/java/com/android/internal/telephony/metrics/SmsStats.java b/src/java/com/android/internal/telephony/metrics/SmsStats.java
index 48826fd..2f1e6a7 100644
--- a/src/java/com/android/internal/telephony/metrics/SmsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/SmsStats.java
@@ -58,6 +58,7 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
+import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms;
 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
 import com.android.telephony.Rlog;
 
@@ -155,46 +156,62 @@
 
     /** 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,
+            @SmsManager.Result int sendErrorCode, long messageId, boolean isFromDefaultApp,
             long intervalMillis) {
-        onOutgoingSms(isOverIms, is3gpp2, fallbackToCs, errorCode, NO_ERROR_CODE,
+        onOutgoingSms(isOverIms, is3gpp2, fallbackToCs, sendErrorCode, NO_ERROR_CODE,
                 messageId, isFromDefaultApp, intervalMillis);
     }
 
     /** 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,
+            @SmsManager.Result int sendErrorCode, int networkErrorCode, long messageId,
             boolean isFromDefaultApp, long intervalMillis) {
         OutgoingSms proto =
                 getOutgoingDefaultProto(is3gpp2, isOverIms, messageId, isFromDefaultApp,
                         intervalMillis);
 
+        // The field errorCode is used for up-to-Android-13 devices. From Android 14, sendErrorCode
+        // and networkErrorCode will be used. The field errorCode will be deprecated when most
+        // devices use Android 14 or higher versions.
         if (isOverIms) {
             // Populate error code and result for IMS case
-            proto.errorCode = errorCode;
+            proto.errorCode = sendErrorCode;
             if (fallbackToCs) {
                 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_FALLBACK;
-            } else if (errorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) {
+            } else if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) {
                 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY;
-            } else if (errorCode != SmsManager.RESULT_ERROR_NONE) {
+            } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) {
                 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR;
             }
         } else {
             // Populate error code and result for CS case
-            if (errorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) {
+            if (sendErrorCode == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY) {
                 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR_RETRY;
-            } else if (errorCode != SmsManager.RESULT_ERROR_NONE) {
+            } else if (sendErrorCode != SmsManager.RESULT_ERROR_NONE) {
                 proto.sendResult = OUTGOING_SMS__SEND_RESULT__SMS_SEND_RESULT_ERROR;
             }
-            proto.errorCode = radioSpecificErrorCode;
-            if (errorCode == SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE
-                    && radioSpecificErrorCode == NO_ERROR_CODE) {
+            proto.errorCode = networkErrorCode;
+            if (sendErrorCode == SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE
+                    && networkErrorCode == NO_ERROR_CODE) {
                 proto.errorCode = is3gpp2 ? NO_NETWORK_ERROR_3GPP2 : NO_NETWORK_ERROR_3GPP;
             }
         }
+
+        proto.sendErrorCode = sendErrorCode;
+        proto.networkErrorCode = networkErrorCode;
+
         mAtomsStorage.addOutgoingSms(proto);
     }
 
+    /** Create a new atom when user attempted to send an outgoing short code sms. */
+    public void onOutgoingShortCodeSms(int category, int xmlVersion) {
+        OutgoingShortCodeSms proto = new OutgoingShortCodeSms();
+        proto.category = category;
+        proto.xmlVersion = xmlVersion;
+        proto.shortCodeSmsCount = 1;
+        mAtomsStorage.addOutgoingShortCodeSms(proto);
+    }
+
     /** Creates a proto for a normal single-part {@code IncomingSms} with default values. */
     private IncomingSms getIncomingDefaultProto(boolean is3gpp2,
             @InboundSmsHandler.SmsSource int smsSource) {
@@ -216,6 +233,7 @@
         // SMS messages (e.g. those handled by OS or error cases).
         proto.messageId = RANDOM.nextLong();
         proto.count = 1;
+        proto.isManagedProfile = mPhone.isManagedProfile();
         return proto;
     }
 
@@ -241,6 +259,7 @@
         proto.retryId = 0;
         proto.intervalMillis = intervalMillis;
         proto.count = 1;
+        proto.isManagedProfile = mPhone.isManagedProfile();
         return proto;
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index 27c17bd..ba07fa0 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -157,6 +157,8 @@
     private final PersistAtomsStorage mAtomsStorage =
             PhoneFactory.getMetricsCollector().getAtomsStorage();
     private final UiccController mUiccController = UiccController.getInstance();
+    private final DeviceStateHelper mDeviceStateHelper =
+            PhoneFactory.getMetricsCollector().getDeviceStateHelper();
 
     public VoiceCallSessionStats(int phoneId, Phone phone) {
         mPhoneId = phoneId;
@@ -446,7 +448,7 @@
         proto.srvccFailureCount = 0L;
         proto.srvccCancellationCount = 0L;
         proto.rttEnabled = false;
-        proto.isEmergency = conn.isEmergencyCall();
+        proto.isEmergency = conn.isEmergencyCall() || conn.isNetworkIdentifiedEmergencyCall();
         proto.isRoaming = serviceState != null ? serviceState.getVoiceRoaming() : false;
         proto.isMultiparty = conn.isMultiparty();
         proto.lastKnownRat = rat;
@@ -514,6 +516,9 @@
         // Update end RAT
         updateRatAtEnd(proto, getVoiceRatWithVoNRFix(mPhone, getServiceState(), proto.bearerAtEnd));
 
+        // Set device fold state
+        proto.foldState = mDeviceStateHelper.getFoldState();
+
         mAtomsStorage.addVoiceCallSession(proto);
 
         // merge RAT usages to PersistPullers when the call session ends (i.e. no more active calls)
diff --git a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
index 8115127..8b34933 100644
--- a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.time.UnixEpochTime;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 import android.content.Context;
@@ -372,7 +373,7 @@
                 builder.addDebugInfo("Clearing time suggestion"
                         + " reason=" + reason);
             } else {
-                TimestampedValue<Long> newNitzTime = nitzSignal.createTimeSignal();
+                UnixEpochTime newNitzTime = nitzSignal.createTimeSignal();
                 builder.setUnixEpochTime(newNitzTime);
                 builder.addDebugInfo("Sending new time suggestion"
                         + " nitzSignal=" + nitzSignal
diff --git a/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java b/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
index 9c7aac9..74b30f8 100644
--- a/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
@@ -18,13 +18,13 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.time.UnixEpochTime;
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.app.timedetector.TimeDetector;
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
 import android.app.timezonedetector.TimeZoneDetector;
 import android.content.Context;
 import android.os.SystemClock;
-import android.os.TimestampedValue;
 import android.util.LocalLog;
 
 import com.android.internal.telephony.Phone;
@@ -69,8 +69,9 @@
         Objects.requireNonNull(timeSuggestion);
 
         if (timeSuggestion.getUnixEpochTime() != null) {
-            TimestampedValue<Long> unixEpochTime = timeSuggestion.getUnixEpochTime();
-            TelephonyMetrics.getInstance().writeNITZEvent(mSlotIndex, unixEpochTime.getValue());
+            UnixEpochTime unixEpochTime = timeSuggestion.getUnixEpochTime();
+            TelephonyMetrics.getInstance().writeNITZEvent(
+                    mSlotIndex, unixEpochTime.getUnixEpochTimeMillis());
         }
         mTimeDetector.suggestTelephonyTime(timeSuggestion);
     }
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramController.java b/src/java/com/android/internal/telephony/satellite/DatagramController.java
new file mode 100644
index 0000000..e7f09c2
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/DatagramController.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Build;
+import android.os.Looper;
+import android.os.SystemProperties;
+import android.telephony.Rlog;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Datagram controller used for sending and receiving satellite datagrams.
+ */
+public class DatagramController {
+    private static final String TAG = "DatagramController";
+
+    @NonNull private static DatagramController sInstance;
+    @NonNull private final Context mContext;
+    @NonNull private final PointingAppController mPointingAppController;
+    @NonNull private final DatagramDispatcher mDatagramDispatcher;
+    @NonNull private final DatagramReceiver mDatagramReceiver;
+    public static final long MAX_DATAGRAM_ID = (long) Math.pow(2, 16);
+    public static final int ROUNDING_UNIT = 10;
+    public static final long SATELLITE_ALIGN_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
+    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
+    private static final boolean DEBUG = !"user".equals(Build.TYPE);
+
+    /** Variables used to update onSendDatagramStateChanged(). */
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private int mSendSubId;
+    @GuardedBy("mLock")
+    private @SatelliteManager.SatelliteDatagramTransferState int mSendDatagramTransferState =
+            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+    @GuardedBy("mLock")
+    private int mSendPendingCount = 0;
+    @GuardedBy("mLock")
+    private int mSendErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;
+    /** Variables used to update onReceiveDatagramStateChanged(). */
+    @GuardedBy("mLock")
+    private int mReceiveSubId;
+    @GuardedBy("mLock")
+    private @SatelliteManager.SatelliteDatagramTransferState int mReceiveDatagramTransferState =
+            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+    @GuardedBy("mLock")
+    private int mReceivePendingCount = 0;
+    @GuardedBy("mLock")
+    private int mReceiveErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;
+
+    private SatelliteDatagram mDemoModeDatagram;
+    private boolean mIsDemoMode = false;
+    private long mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
+
+    /**
+     * @return The singleton instance of DatagramController.
+     */
+    public static DatagramController getInstance() {
+        if (sInstance == null) {
+            loge("DatagramController was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the DatagramController singleton instance.
+     * @param context The Context to use to create the DatagramController.
+     * @param looper The looper for the handler.
+     * @param pointingAppController PointingAppController is used to update
+     *                              PointingApp about datagram transfer state changes.
+     * @return The singleton instance of DatagramController.
+     */
+    public static DatagramController make(@NonNull Context context, @NonNull Looper looper,
+            @NonNull PointingAppController pointingAppController) {
+        if (sInstance == null) {
+            sInstance = new DatagramController(context, looper, pointingAppController);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a DatagramController to send and receive satellite datagrams.
+     *
+     * @param context The Context for the DatagramController.
+     * @param looper The looper for the handler
+     * @param pointingAppController PointingAppController is used to update PointingApp
+     *                              about datagram transfer state changes.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected DatagramController(@NonNull Context context, @NonNull Looper  looper,
+            @NonNull PointingAppController pointingAppController) {
+        mContext = context;
+        mPointingAppController = pointingAppController;
+
+        // Create the DatagramDispatcher singleton,
+        // which is used to send satellite datagrams.
+        mDatagramDispatcher = DatagramDispatcher.make(mContext, looper, this);
+
+        // Create the DatagramReceiver singleton,
+        // which is used to receive satellite datagrams.
+        mDatagramReceiver = DatagramReceiver.make(mContext, looper, this);
+    }
+
+    /**
+     * Register to receive incoming datagrams over satellite.
+     *
+     * @param subId The subId of the subscription to register for incoming satellite datagrams.
+     * @param callback The callback to handle incoming datagrams over satellite.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+     */
+    @SatelliteManager.SatelliteError public int registerForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        return mDatagramReceiver.registerForSatelliteDatagram(subId, callback);
+    }
+
+    /**
+     * Unregister to stop receiving incoming datagrams over satellite.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteDatagram(int, ISatelliteDatagramCallback)}.
+     */
+    public void unregisterForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        mDatagramReceiver.unregisterForSatelliteDatagram(subId, callback);
+    }
+
+    /**
+     * Poll pending satellite datagrams over satellite.
+     *
+     * This method requests modem to check if there are any pending datagrams to be received over
+     * satellite. If there are any incoming datagrams, they will be received via
+     * {@link android.telephony.satellite.SatelliteDatagramCallback#onSatelliteDatagramReceived(
+     * long, SatelliteDatagram, int, Consumer)}
+     *
+     * @param subId The subId of the subscription used for receiving datagrams.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
+        mDatagramReceiver.pollPendingSatelliteDatagrams(subId, callback);
+    }
+
+    /**
+     * Send datagram over satellite.
+     *
+     * Gateway encodes SOS message or location sharing message into a datagram and passes it as
+     * input to this method. Datagram received here will be passed down to modem without any
+     * encoding or encryption.
+     *
+     * When demo mode is on, save the sent datagram and this datagram will be used as a received
+     * datagram.
+     *
+     * @param subId The subId of the subscription to send satellite datagrams for.
+     * @param datagramType datagram type indicating whether the datagram is of type
+     *                     SOS_SMS or LOCATION_SHARING.
+     * @param datagram encoded gateway datagram which is encrypted by the caller.
+     *                 Datagram will be passed down to modem without any encoding or encryption.
+     * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+     *                                 full screen mode.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
+            @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+            @NonNull Consumer<Integer> callback) {
+        setDemoModeDatagram(datagramType, datagram);
+        mDatagramDispatcher.sendSatelliteDatagram(subId, datagramType, datagram,
+                needFullScreenPointingUI, callback);
+    }
+
+    /**
+     * Update send status to {@link PointingAppController}.
+     *
+     * @param subId The subId of the subscription to send satellite datagrams for
+     * @param datagramTransferState The new send datagram transfer state.
+     * @param sendPendingCount number of datagrams that are currently being sent
+     * @param errorCode If datagram transfer failed, the reason for failure.
+     */
+    public void updateSendStatus(int subId,
+            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
+            int sendPendingCount, int errorCode) {
+        synchronized (mLock) {
+            logd("updateSendStatus"
+                    + " subId: " + subId
+                    + " datagramTransferState: " + datagramTransferState
+                    + " sendPendingCount: " + sendPendingCount + " errorCode: " + errorCode);
+
+            mSendSubId = subId;
+            mSendDatagramTransferState = datagramTransferState;
+            mSendPendingCount = sendPendingCount;
+            mSendErrorCode = errorCode;
+
+            notifyDatagramTransferStateChangedToSessionController();
+            mPointingAppController.updateSendDatagramTransferState(mSendSubId,
+                    mSendDatagramTransferState, mSendPendingCount, mSendErrorCode);
+        }
+    }
+
+    /**
+     * Update receive status to {@link PointingAppController}.
+     *
+     * @param subId The subId of the subscription used to receive datagrams
+     * @param datagramTransferState The new receive datagram transfer state.
+     * @param receivePendingCount The number of datagrams that are currently pending to be received.
+     * @param errorCode If datagram transfer failed, the reason for failure.
+     */
+    public void updateReceiveStatus(int subId,
+            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
+            int receivePendingCount, int errorCode) {
+        synchronized (mLock) {
+            logd("updateReceiveStatus"
+                    + " subId: " + subId
+                    + " datagramTransferState: " + datagramTransferState
+                    + " receivePendingCount: " + receivePendingCount + " errorCode: " + errorCode);
+
+            mReceiveSubId = subId;
+            mReceiveDatagramTransferState = datagramTransferState;
+            mReceivePendingCount = receivePendingCount;
+            mReceiveErrorCode = errorCode;
+
+            notifyDatagramTransferStateChangedToSessionController();
+            mPointingAppController.updateReceiveDatagramTransferState(mReceiveSubId,
+                    mReceiveDatagramTransferState, mReceivePendingCount, mReceiveErrorCode);
+        }
+
+        if (isPollingInIdleState()) {
+            mDatagramDispatcher.retrySendingDatagrams();
+        }
+    }
+
+    /**
+     * Return receive pending datagram count
+     * @return receive pending datagram count.
+     */
+    public int getReceivePendingCount() {
+        return mReceivePendingCount;
+    }
+
+    /**
+     * This function is used by {@link SatelliteController} to notify {@link DatagramController}
+     * that satellite modem state has changed.
+     *
+     * @param state Current satellite modem state.
+     */
+    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
+        mDatagramDispatcher.onSatelliteModemStateChanged(state);
+        mDatagramReceiver.onSatelliteModemStateChanged(state);
+    }
+
+    void onDeviceAlignedWithSatellite(boolean isAligned) {
+        mDatagramDispatcher.onDeviceAlignedWithSatellite(isAligned);
+        mDatagramReceiver.onDeviceAlignedWithSatellite(isAligned);
+    }
+
+    @VisibleForTesting
+    public boolean isReceivingDatagrams() {
+        synchronized (mLock) {
+            return (mReceiveDatagramTransferState
+                    == SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        }
+    }
+
+    public boolean isSendingInIdleState() {
+        synchronized (mLock) {
+            return mSendDatagramTransferState ==
+                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+        }
+    }
+
+    public boolean isPollingInIdleState() {
+        synchronized (mLock) {
+            return mReceiveDatagramTransferState ==
+                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+        }
+    }
+
+    /**
+     * Set variables for {@link DatagramDispatcher} and {@link DatagramReceiver} to run demo mode
+     * @param isDemoMode {@code true} means demo mode is on, {@code false} otherwise.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void setDemoMode(boolean isDemoMode) {
+        mIsDemoMode = isDemoMode;
+        mDatagramDispatcher.setDemoMode(isDemoMode);
+        mDatagramReceiver.setDemoMode(isDemoMode);
+
+        if (!isDemoMode) {
+            mDemoModeDatagram = null;
+        }
+    }
+
+    /** Get the last sent datagram for demo mode */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public SatelliteDatagram getDemoModeDatagram() {
+        return mDemoModeDatagram;
+    }
+
+    /**
+     * Set last sent datagram for demo mode
+     * @param datagramType datagram type, only DATAGRAM_TYPE_SOS_MESSAGE will be saved
+     * @param datagram datagram The last datagram saved when sendSatelliteDatagramForDemo is called
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void setDemoModeDatagram(@SatelliteManager.DatagramType int datagramType,
+            SatelliteDatagram datagram) {
+        if (mIsDemoMode &&  datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+            mDemoModeDatagram = datagram;
+        }
+    }
+
+    long getSatelliteAlignedTimeoutDuration() {
+        return mAlignTimeoutDuration;
+    }
+
+    /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds whether
+     * the device is aligned with the satellite for demo mode
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis) {
+        if (!isMockModemAllowed()) {
+            loge("Updating align timeout duration is not allowed");
+            return false;
+        }
+
+        logd("setSatelliteDeviceAlignedTimeoutDuration: timeoutMillis=" + timeoutMillis);
+        mAlignTimeoutDuration = timeoutMillis;
+        return true;
+    }
+
+    private boolean isMockModemAllowed() {
+        return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
+    }
+
+    private void notifyDatagramTransferStateChangedToSessionController() {
+        SatelliteSessionController sessionController = SatelliteSessionController.getInstance();
+        if (sessionController == null) {
+            loge("notifyDatagramTransferStateChangeToSessionController: SatelliteSessionController"
+                    + " is not initialized yet");
+        } else {
+            sessionController.onDatagramTransferStateChanged(
+                    mSendDatagramTransferState, mReceiveDatagramTransferState);
+        }
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
new file mode 100644
index 0000000..77b410d
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.android.internal.telephony.satellite.DatagramController.ROUNDING_UNIT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.metrics.SatelliteStats;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
+
+/**
+ * Datagram dispatcher used to send satellite datagrams.
+ */
+public class DatagramDispatcher extends Handler {
+    private static final String TAG = "DatagramDispatcher";
+
+    private static final int CMD_SEND_SATELLITE_DATAGRAM = 1;
+    private static final int EVENT_SEND_SATELLITE_DATAGRAM_DONE = 2;
+    private static final int EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT = 3;
+
+    @NonNull private static DatagramDispatcher sInstance;
+    @NonNull private final Context mContext;
+    @NonNull private final DatagramController mDatagramController;
+    @NonNull private final ControllerMetricsStats mControllerMetricsStats;
+
+    private boolean mIsDemoMode = false;
+    private boolean mIsAligned = false;
+    private DatagramDispatcherHandlerRequest mSendSatelliteDatagramRequest = null;
+
+    private static AtomicLong mNextDatagramId = new AtomicLong(0);
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private boolean mSendingDatagramInProgress;
+
+    /**
+     * Map key: datagramId, value: SendSatelliteDatagramArgument to retry sending emergency
+     * datagrams.
+     */
+    @GuardedBy("mLock")
+    private final LinkedHashMap<Long, SendSatelliteDatagramArgument>
+            mPendingEmergencyDatagramsMap = new LinkedHashMap<>();
+
+    /**
+     * Map key: datagramId, value: SendSatelliteDatagramArgument to retry sending non-emergency
+     * datagrams.
+     */
+    @GuardedBy("mLock")
+    private final LinkedHashMap<Long, SendSatelliteDatagramArgument>
+            mPendingNonEmergencyDatagramsMap = new LinkedHashMap<>();
+
+    /**
+     * Create the DatagramDispatcher singleton instance.
+     * @param context The Context to use to create the DatagramDispatcher.
+     * @param looper The looper for the handler.
+     * @param datagramController DatagramController which is used to update datagram transfer state.
+     * @return The singleton instance of DatagramDispatcher.
+     */
+    public static DatagramDispatcher make(@NonNull Context context, @NonNull Looper looper,
+            @NonNull DatagramController datagramController) {
+        if (sInstance == null) {
+            sInstance = new DatagramDispatcher(context, looper, datagramController);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a DatagramDispatcher to send satellite datagrams.
+     *
+     * @param context The Context for the DatagramDispatcher.
+     * @param looper The looper for the handler.
+     * @param datagramController DatagramController which is used to update datagram transfer state.
+     */
+    @VisibleForTesting
+    protected DatagramDispatcher(@NonNull Context context, @NonNull Looper looper,
+            @NonNull DatagramController datagramController) {
+        super(looper);
+        mContext = context;
+        mDatagramController = datagramController;
+        mControllerMetricsStats = ControllerMetricsStats.getInstance();
+
+        synchronized (mLock) {
+            mSendingDatagramInProgress = false;
+        }
+    }
+
+    private static final class DatagramDispatcherHandlerRequest {
+        /** The argument to use for the request */
+        public @NonNull Object argument;
+        /** The caller needs to specify the phone to be used for the request */
+        public @NonNull Phone phone;
+        /** The result of the request that is run on the main thread */
+        public @Nullable Object result;
+
+        DatagramDispatcherHandlerRequest(Object argument, Phone phone) {
+            this.argument = argument;
+            this.phone = phone;
+        }
+    }
+
+    private static final class SendSatelliteDatagramArgument {
+        public int subId;
+        public long datagramId;
+        public @SatelliteManager.DatagramType int datagramType;
+        public @NonNull SatelliteDatagram datagram;
+        public boolean needFullScreenPointingUI;
+        public @NonNull Consumer<Integer> callback;
+        public long datagramStartTime;
+        public boolean skipCheckingSatelliteAligned = false;
+
+        SendSatelliteDatagramArgument(int subId, long datagramId,
+                @SatelliteManager.DatagramType int datagramType,
+                @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+                @NonNull Consumer<Integer> callback) {
+            this.subId = subId;
+            this.datagramId = datagramId;
+            this.datagramType = datagramType;
+            this.datagram = datagram;
+            this.needFullScreenPointingUI = needFullScreenPointingUI;
+            this.callback = callback;
+        }
+
+        /** returns the size of outgoing SMS, rounded by 10 bytes */
+        public int getDatagramRoundedSizeBytes() {
+            if (datagram.getSatelliteDatagram() != null) {
+                int sizeBytes = datagram.getSatelliteDatagram().length;
+                // rounded by ROUNDING_UNIT
+                return (int) (Math.round((double) sizeBytes / ROUNDING_UNIT) * ROUNDING_UNIT);
+            } else {
+                return 0;
+            }
+        }
+
+        /** sets the start time at datagram is sent out */
+        public void setDatagramStartTime() {
+            datagramStartTime =
+                    datagramStartTime == 0 ? System.currentTimeMillis() : datagramStartTime;
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        DatagramDispatcherHandlerRequest request;
+        Message onCompleted;
+        AsyncResult ar;
+
+        switch(msg.what) {
+            case CMD_SEND_SATELLITE_DATAGRAM: {
+                logd("CMD_SEND_SATELLITE_DATAGRAM");
+                request = (DatagramDispatcherHandlerRequest) msg.obj;
+                SendSatelliteDatagramArgument argument =
+                        (SendSatelliteDatagramArgument) request.argument;
+                onCompleted = obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);
+
+                if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                    SatelliteModemInterface.getInstance().sendSatelliteDatagram(argument.datagram,
+                            argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
+                            argument.needFullScreenPointingUI, onCompleted);
+                    break;
+                }
+
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.sendSatelliteDatagram(onCompleted, argument.datagram,
+                            argument.needFullScreenPointingUI);
+                } else {
+                    loge("sendSatelliteDatagram: No phone object");
+                    synchronized (mLock) {
+                        // Remove current datagram from pending map
+                        if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+                            mPendingEmergencyDatagramsMap.remove(argument.datagramId);
+                        } else {
+                            mPendingNonEmergencyDatagramsMap.remove(argument.datagramId);
+                        }
+
+                        // Update send status
+                        mDatagramController.updateSendStatus(argument.subId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+                                getPendingDatagramCount(),
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                        mDatagramController.updateSendStatus(argument.subId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                                0, SatelliteManager.SATELLITE_ERROR_NONE);
+
+                        // report phone == null case
+                        reportSendDatagramCompleted(argument,
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                        argument.callback.accept(
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+
+                        // Abort sending all the pending datagrams
+                        abortSendingPendingDatagrams(argument.subId,
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    }
+                }
+                break;
+            }
+
+            case EVENT_SEND_SATELLITE_DATAGRAM_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (DatagramDispatcherHandlerRequest) ar.userObj;
+                int error = SatelliteServiceUtils.getSatelliteError(ar, "sendSatelliteDatagram");
+                SendSatelliteDatagramArgument argument =
+                        (SendSatelliteDatagramArgument) request.argument;
+
+                synchronized (mLock) {
+                    if (mIsDemoMode && (error == SatelliteManager.SATELLITE_ERROR_NONE)) {
+                        if (argument.skipCheckingSatelliteAligned) {
+                            logd("Satellite was already aligned. No need to check alignment again");
+                        } else if (!mIsAligned) {
+                            logd("Satellite is not aligned in demo mode, wait for the alignment.");
+                            startSatelliteAlignedTimer(request);
+                            break;
+                        }
+                    }
+
+                    logd("EVENT_SEND_SATELLITE_DATAGRAM_DONE error: " + error);
+                    // log metrics about the outgoing datagram
+                    reportSendDatagramCompleted(argument, error);
+
+                    mSendingDatagramInProgress = false;
+
+                    // Remove current datagram from pending map.
+                    if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+                        mPendingEmergencyDatagramsMap.remove(argument.datagramId);
+                    } else {
+                        mPendingNonEmergencyDatagramsMap.remove(argument.datagramId);
+                    }
+
+                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                        // Update send status for current datagram
+                        mDatagramController.updateSendStatus(argument.subId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS,
+                                getPendingDatagramCount(), error);
+                        mControllerMetricsStats.reportOutgoingDatagramSuccessCount(
+                                argument.datagramType);
+
+                        if (getPendingDatagramCount() > 0) {
+                            // Send response for current datagram
+                            argument.callback.accept(error);
+                            // Send pending datagrams
+                            sendPendingDatagrams();
+                        } else {
+                            mDatagramController.updateSendStatus(argument.subId,
+                                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                                    0, SatelliteManager.SATELLITE_ERROR_NONE);
+                            // Send response for current datagram
+                            argument.callback.accept(error);
+                        }
+                    } else {
+                        // Update send status
+                        mDatagramController.updateSendStatus(argument.subId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+                                getPendingDatagramCount(), error);
+                        mDatagramController.updateSendStatus(argument.subId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                                0, SatelliteManager.SATELLITE_ERROR_NONE);
+                        // Send response for current datagram
+                        // after updating datagram transfer state internally.
+                        argument.callback.accept(error);
+                        // Abort sending all the pending datagrams
+                        mControllerMetricsStats.reportOutgoingDatagramFailCount(
+                                argument.datagramType);
+                        abortSendingPendingDatagrams(argument.subId,
+                                SatelliteManager.SATELLITE_REQUEST_ABORTED);
+                    }
+                }
+                break;
+            }
+
+            case EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT: {
+                handleEventSatelliteAlignedTimeout((DatagramDispatcherHandlerRequest) msg.obj);
+                break;
+            }
+
+            default:
+                logw("DatagramDispatcherHandler: unexpected message code: " + msg.what);
+                break;
+        }
+    }
+
+    /**
+     * Send datagram over satellite.
+     *
+     * Gateway encodes SOS message or location sharing message into a datagram and passes it as
+     * input to this method. Datagram received here will be passed down to modem without any
+     * encoding or encryption.
+     *
+     * @param subId The subId of the subscription to send satellite datagrams for.
+     * @param datagramType datagram type indicating whether the datagram is of type
+     *                     SOS_SMS or LOCATION_SHARING.
+     * @param datagram encoded gateway datagram which is encrypted by the caller.
+     *                 Datagram will be passed down to modem without any encoding or encryption.
+     * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+     *                                 full screen mode.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
+            @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+            @NonNull Consumer<Integer> callback) {
+        Phone phone = SatelliteServiceUtils.getPhone();
+
+        long datagramId = mNextDatagramId.getAndUpdate(
+                n -> ((n + 1) % DatagramController.MAX_DATAGRAM_ID));
+
+        SendSatelliteDatagramArgument datagramArgs =
+                new SendSatelliteDatagramArgument(subId, datagramId, datagramType, datagram,
+                        needFullScreenPointingUI, callback);
+
+        synchronized (mLock) {
+            // Add datagram to pending datagram map
+            if (datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+                mPendingEmergencyDatagramsMap.put(datagramId, datagramArgs);
+            } else {
+                mPendingNonEmergencyDatagramsMap.put(datagramId, datagramArgs);
+            }
+
+            // Modem can be busy receiving datagrams, so send datagram only when modem is not busy.
+            if (!mSendingDatagramInProgress && mDatagramController.isPollingInIdleState()) {
+                mSendingDatagramInProgress = true;
+                datagramArgs.setDatagramStartTime();
+                mDatagramController.updateSendStatus(subId,
+                        SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                        getPendingDatagramCount(), SatelliteManager.SATELLITE_ERROR_NONE);
+                sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM, datagramArgs, phone);
+            }
+        }
+    }
+
+    public void retrySendingDatagrams() {
+        synchronized (mLock) {
+            sendPendingDatagrams();
+        }
+    }
+
+    /** Set demo mode
+     *
+     * @param isDemoMode {@code true} means demo mode is on, {@code false} otherwise.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    protected void setDemoMode(boolean isDemoMode) {
+        mIsDemoMode = isDemoMode;
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    protected void onDeviceAlignedWithSatellite(boolean isAligned) {
+        if (mIsDemoMode) {
+            synchronized (mLock) {
+                mIsAligned = isAligned;
+                if (isAligned) handleEventSatelliteAligned();
+            }
+        }
+    }
+
+    private void startSatelliteAlignedTimer(@NonNull DatagramDispatcherHandlerRequest request) {
+        if (isSatelliteAlignedTimerStarted()) {
+            logd("Satellite aligned timer was already started");
+            return;
+        }
+        mSendSatelliteDatagramRequest = request;
+        sendMessageDelayed(
+                obtainMessage(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT, request),
+                getSatelliteAlignedTimeoutDuration());
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected long getSatelliteAlignedTimeoutDuration() {
+        return mDatagramController.getSatelliteAlignedTimeoutDuration();
+    }
+
+    private void handleEventSatelliteAligned() {
+        if (isSatelliteAlignedTimerStarted()) {
+            stopSatelliteAlignedTimer();
+
+            if (mSendSatelliteDatagramRequest == null) {
+                loge("handleEventSatelliteAligned: mSendSatelliteDatagramRequest is null");
+            } else {
+                SendSatelliteDatagramArgument argument =
+                        (SendSatelliteDatagramArgument) mSendSatelliteDatagramRequest.argument;
+                argument.skipCheckingSatelliteAligned = true;
+                Message message = obtainMessage(
+                        EVENT_SEND_SATELLITE_DATAGRAM_DONE, mSendSatelliteDatagramRequest);
+                mSendSatelliteDatagramRequest = null;
+                AsyncResult.forMessage(message, null, null);
+                message.sendToTarget();
+            }
+        }
+    }
+
+    private void handleEventSatelliteAlignedTimeout(
+            @NonNull DatagramDispatcherHandlerRequest request) {
+        SatelliteManager.SatelliteException exception =
+                new SatelliteManager.SatelliteException(
+                        SatelliteManager.SATELLITE_NOT_REACHABLE);
+        Message message = obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);
+        AsyncResult.forMessage(message, null, exception);
+        message.sendToTarget();
+    }
+
+    private boolean isSatelliteAlignedTimerStarted() {
+        return hasMessages(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT);
+    }
+
+    private void stopSatelliteAlignedTimer() {
+        removeMessages(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT);
+    }
+
+    /**
+     * Send pending satellite datagrams. Emergency datagrams are given priority over
+     * non-emergency datagrams.
+     */
+    @GuardedBy("mLock")
+    private void sendPendingDatagrams() {
+        logd("sendPendingDatagrams()");
+        if (!mDatagramController.isPollingInIdleState()) {
+            // Datagram should be sent to satellite modem when modem is free.
+            logd("sendPendingDatagrams: modem is receiving datagrams");
+            return;
+        }
+
+        if (getPendingDatagramCount() <= 0) {
+            logd("sendPendingDatagrams: no pending datagrams to send");
+            return;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        Set<Entry<Long, SendSatelliteDatagramArgument>> pendingDatagram = null;
+        if (!mSendingDatagramInProgress && !mPendingEmergencyDatagramsMap.isEmpty()) {
+            pendingDatagram = mPendingEmergencyDatagramsMap.entrySet();
+        } else if (!mSendingDatagramInProgress && !mPendingNonEmergencyDatagramsMap.isEmpty()) {
+            pendingDatagram = mPendingNonEmergencyDatagramsMap.entrySet();
+        }
+
+        if ((pendingDatagram != null) && pendingDatagram.iterator().hasNext()) {
+            mSendingDatagramInProgress = true;
+            SendSatelliteDatagramArgument datagramArg =
+                    pendingDatagram.iterator().next().getValue();
+            // Sets the trigger time for getting pending datagrams
+            datagramArg.setDatagramStartTime();
+            mDatagramController.updateSendStatus(datagramArg.subId,
+                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                    getPendingDatagramCount(), SatelliteManager.SATELLITE_ERROR_NONE);
+            sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM, datagramArg, phone);
+        }
+    }
+
+    /**
+     * Send error code to all the pending datagrams
+     *
+     * @param pendingDatagramsMap The pending datagrams map to be cleaned up.
+     * @param errorCode error code to be returned.
+     */
+    @GuardedBy("mLock")
+    private void sendErrorCodeAndCleanupPendingDatagrams(
+            LinkedHashMap<Long, SendSatelliteDatagramArgument> pendingDatagramsMap,
+            @SatelliteManager.SatelliteError int errorCode) {
+        if (pendingDatagramsMap.size() == 0) {
+            return;
+        }
+        loge("sendErrorCodeAndCleanupPendingDatagrams: cleaning up resources");
+
+        // Send error code to all the pending datagrams
+        for (Entry<Long, SendSatelliteDatagramArgument> entry :
+                pendingDatagramsMap.entrySet()) {
+            SendSatelliteDatagramArgument argument = entry.getValue();
+            reportSendDatagramCompleted(argument, errorCode);
+            mControllerMetricsStats.reportOutgoingDatagramFailCount(argument.datagramType);
+            argument.callback.accept(errorCode);
+        }
+
+        // Clear pending datagram maps
+        pendingDatagramsMap.clear();
+    }
+
+    /**
+     * Abort sending all the pending datagrams.
+     *
+     * @param subId The subId of the subscription used to send datagram
+     * @param errorCode The error code that resulted in abort.
+     */
+    @GuardedBy("mLock")
+    private void abortSendingPendingDatagrams(int subId,
+            @SatelliteManager.SatelliteError int errorCode) {
+        logd("abortSendingPendingDatagrams()");
+        sendErrorCodeAndCleanupPendingDatagrams(mPendingEmergencyDatagramsMap, errorCode);
+        sendErrorCodeAndCleanupPendingDatagrams(mPendingNonEmergencyDatagramsMap, errorCode);
+    }
+
+    /**
+     * Return pending datagram count
+     * @return pending datagram count
+     */
+    @GuardedBy("mLock")
+    private int getPendingDatagramCount() {
+        return mPendingEmergencyDatagramsMap.size() + mPendingNonEmergencyDatagramsMap.size();
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread and returns immediately.
+     *
+     * @param command command to be executed on the main thread
+     * @param argument additional parameters required to perform of the operation
+     * @param phone phone object used to perform the operation.
+     */
+    private void sendRequestAsync(int command, @NonNull Object argument, @Nullable Phone phone) {
+        DatagramDispatcherHandlerRequest request = new DatagramDispatcherHandlerRequest(
+                argument, phone);
+        Message msg = this.obtainMessage(command, request);
+        msg.sendToTarget();
+    }
+
+    private void reportSendDatagramCompleted(@NonNull SendSatelliteDatagramArgument argument,
+            @NonNull @SatelliteManager.SatelliteError int resultCode) {
+        SatelliteStats.getInstance().onSatelliteOutgoingDatagramMetrics(
+                new SatelliteStats.SatelliteOutgoingDatagramParams.Builder()
+                        .setDatagramType(argument.datagramType)
+                        .setResultCode(resultCode)
+                        .setDatagramSizeBytes(argument.getDatagramRoundedSizeBytes())
+                        .setDatagramTransferTimeMillis(
+                                System.currentTimeMillis() - argument.datagramStartTime)
+                        .build());
+    }
+
+    /**
+     * Destroys this DatagramDispatcher. Used for tearing down static resources during testing.
+     */
+    @VisibleForTesting
+    public void destroy() {
+        sInstance = null;
+    }
+
+    /**
+     * This function is used by {@link DatagramController} to notify {@link DatagramDispatcher}
+     * that satellite modem state has changed.
+     *
+     * @param state Current satellite modem state.
+     */
+    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
+        synchronized (mLock) {
+            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
+                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
+                logd("onSatelliteModemStateChanged: cleaning up resources");
+                cleanUpResources();
+            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_IDLE) {
+                sendPendingDatagrams();
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void cleanUpResources() {
+        mSendingDatagramInProgress = false;
+        if (getPendingDatagramCount() > 0) {
+            mDatagramController.updateSendStatus(
+                    SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+                    getPendingDatagramCount(), SatelliteManager.SATELLITE_REQUEST_ABORTED);
+        }
+        mDatagramController.updateSendStatus(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                0, SatelliteManager.SATELLITE_ERROR_NONE);
+        abortSendingPendingDatagrams(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                SatelliteManager.SATELLITE_REQUEST_ABORTED);
+
+        stopSatelliteAlignedTimer();
+        mIsDemoMode = false;
+        mSendSatelliteDatagramRequest = null;
+        mIsAligned = false;
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+
+    private static void logw(@NonNull String log) { Rlog.w(TAG, log); }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
new file mode 100644
index 0000000..06eede1
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
@@ -0,0 +1,805 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.android.internal.telephony.satellite.DatagramController.ROUNDING_UNIT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Telephony;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Pair;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.IVoidConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.metrics.SatelliteStats;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.internal.util.FunctionalUtils;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
+
+/**
+ * Datagram receiver used to receive satellite datagrams and then,
+ * deliver received datagrams to messaging apps.
+ */
+public class DatagramReceiver extends Handler {
+    private static final String TAG = "DatagramReceiver";
+
+    private static final int CMD_POLL_PENDING_SATELLITE_DATAGRAMS = 1;
+    private static final int EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE = 2;
+    private static final int EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT = 3;
+
+    /** Key used to read/write satellite datagramId in shared preferences. */
+    private static final String SATELLITE_DATAGRAM_ID_KEY = "satellite_datagram_id_key";
+    private static AtomicLong mNextDatagramId = new AtomicLong(0);
+
+    @NonNull private static DatagramReceiver sInstance;
+    @NonNull private final Context mContext;
+    @NonNull private final ContentResolver mContentResolver;
+    @NonNull private SharedPreferences mSharedPreferences = null;
+    @NonNull private final DatagramController mDatagramController;
+    @NonNull private final ControllerMetricsStats mControllerMetricsStats;
+    @NonNull private final Looper mLooper;
+
+    private long mDatagramTransferStartTime = 0;
+    private boolean mIsDemoMode = false;
+    @GuardedBy("mLock")
+    private boolean mIsAligned = false;
+    private DatagramReceiverHandlerRequest mPollPendingSatelliteDatagramsRequest = null;
+    private final Object mLock = new Object();
+
+    /**
+     * Map key: subId, value: SatelliteDatagramListenerHandler to notify registrants.
+     */
+    private final ConcurrentHashMap<Integer, SatelliteDatagramListenerHandler>
+            mSatelliteDatagramListenerHandlers = new ConcurrentHashMap<>();
+
+    /**
+     * Map key: DatagramId, value: pendingAckCount
+     * This map is used to track number of listeners that are yet to send ack for a particular
+     * datagram.
+     */
+    private final ConcurrentHashMap<Long, Integer>
+            mPendingAckCountHashMap = new ConcurrentHashMap<>();
+
+    /**
+     * Create the DatagramReceiver singleton instance.
+     * @param context The Context to use to create the DatagramReceiver.
+     * @param looper The looper for the handler.
+     * @param datagramController DatagramController which is used to update datagram transfer state.
+     * @return The singleton instance of DatagramReceiver.
+     */
+    public static DatagramReceiver make(@NonNull Context context, @NonNull Looper looper,
+            @NonNull DatagramController datagramController) {
+        if (sInstance == null) {
+            sInstance = new DatagramReceiver(context, looper, datagramController);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a DatagramReceiver to received satellite datagrams.
+     * The received datagrams will be delivered to respective messaging apps.
+     *
+     * @param context The Context for the DatagramReceiver.
+     * @param looper The looper for the handler.
+     * @param datagramController DatagramController which is used to update datagram transfer state.
+     */
+    @VisibleForTesting
+    protected DatagramReceiver(@NonNull Context context, @NonNull Looper looper,
+            @NonNull DatagramController datagramController) {
+        super(looper);
+        mContext = context;
+        mLooper = looper;
+        mContentResolver = context.getContentResolver();
+        mDatagramController = datagramController;
+        mControllerMetricsStats = ControllerMetricsStats.getInstance();
+
+        try {
+            mSharedPreferences =
+                    mContext.getSharedPreferences(SatelliteController.SATELLITE_SHARED_PREF,
+                            Context.MODE_PRIVATE);
+        } catch (Exception e) {
+            loge("Cannot get default shared preferences: " + e);
+        }
+
+        if ((mSharedPreferences != null) &&
+                (!mSharedPreferences.contains(SATELLITE_DATAGRAM_ID_KEY))) {
+            mSharedPreferences.edit().putLong(SATELLITE_DATAGRAM_ID_KEY, mNextDatagramId.get())
+                    .commit();
+        }
+    }
+
+    private static final class DatagramReceiverHandlerRequest {
+        /** The argument to use for the request */
+        public @NonNull Object argument;
+        /** The caller needs to specify the phone to be used for the request */
+        public @NonNull Phone phone;
+        /** The subId of the subscription used for the request. */
+        public int subId;
+        /** The result of the request that is run on the main thread */
+        public @Nullable Object result;
+
+        DatagramReceiverHandlerRequest(Object argument, Phone phone, int subId) {
+            this.argument = argument;
+            this.phone = phone;
+            this.subId = subId;
+        }
+    }
+
+    /**
+     * Listeners are updated about incoming datagrams using a backgroundThread.
+     */
+    @VisibleForTesting
+    public static final class SatelliteDatagramListenerHandler extends Handler {
+        public static final int EVENT_SATELLITE_DATAGRAM_RECEIVED = 1;
+        public static final int EVENT_RETRY_DELIVERING_RECEIVED_DATAGRAM = 2;
+        public static final int EVENT_RECEIVED_ACK = 3;
+
+        @NonNull private final ConcurrentHashMap<IBinder, ISatelliteDatagramCallback> mListeners;
+        private final int mSubId;
+
+        private static final class DatagramRetryArgument {
+            public long datagramId;
+            @NonNull public SatelliteDatagram datagram;
+            public int pendingCount;
+            @NonNull public ISatelliteDatagramCallback listener;
+
+            DatagramRetryArgument(long datagramId, @NonNull SatelliteDatagram datagram,
+                    int pendingCount, @NonNull ISatelliteDatagramCallback listener) {
+                this.datagramId = datagramId;
+                this.datagram = datagram;
+                this.pendingCount = pendingCount;
+                this.listener = listener;
+            }
+
+            @Override
+            public boolean equals(Object other) {
+                if (this == other) return true;
+                if (other == null || getClass() != other.getClass()) return false;
+                DatagramRetryArgument that = (DatagramRetryArgument) other;
+                return datagramId == that.datagramId
+                        && datagram.equals(that.datagram)
+                        && pendingCount  == that.pendingCount
+                        && listener.equals(that.listener);
+            }
+        }
+
+        @VisibleForTesting
+        public SatelliteDatagramListenerHandler(@NonNull Looper looper, int subId) {
+            super(looper);
+            mSubId = subId;
+            mListeners = new ConcurrentHashMap<>();
+        }
+
+        public void addListener(@NonNull ISatelliteDatagramCallback listener) {
+            mListeners.put(listener.asBinder(), listener);
+        }
+
+        public void removeListener(@NonNull ISatelliteDatagramCallback listener) {
+            mListeners.remove(listener.asBinder());
+        }
+
+        public boolean hasListeners() {
+            return !mListeners.isEmpty();
+        }
+
+        public int getNumOfListeners() {
+            return mListeners.size();
+        }
+
+        private int getTimeoutToReceiveAck() {
+            return sInstance.mContext.getResources().getInteger(
+                    R.integer.config_timeout_to_receive_delivered_ack_millis);
+        }
+
+        private long getDatagramId() {
+            long datagramId = 0;
+            if (sInstance.mSharedPreferences == null) {
+                try {
+                    // Try to recreate if it is null
+                    sInstance.mSharedPreferences = sInstance.mContext
+                            .getSharedPreferences(SatelliteController.SATELLITE_SHARED_PREF,
+                            Context.MODE_PRIVATE);
+                } catch (Exception e) {
+                    loge("Cannot get default shared preferences: " + e);
+                }
+            }
+
+            if (sInstance.mSharedPreferences != null) {
+                long prevDatagramId = sInstance.mSharedPreferences
+                        .getLong(SATELLITE_DATAGRAM_ID_KEY, mNextDatagramId.get());
+                datagramId = (prevDatagramId + 1) % DatagramController.MAX_DATAGRAM_ID;
+                mNextDatagramId.set(datagramId);
+                sInstance.mSharedPreferences.edit().putLong(SATELLITE_DATAGRAM_ID_KEY, datagramId)
+                        .commit();
+            } else {
+                loge("Shared preferences is null - returning default datagramId");
+                datagramId = mNextDatagramId.getAndUpdate(
+                        n -> ((n + 1) % DatagramController.MAX_DATAGRAM_ID));
+            }
+
+            return datagramId;
+        }
+
+        private void insertDatagram(long datagramId, @NonNull SatelliteDatagram datagram) {
+            ContentValues contentValues = new ContentValues();
+            contentValues.put(
+                    Telephony.SatelliteDatagrams.COLUMN_UNIQUE_KEY_DATAGRAM_ID, datagramId);
+            contentValues.put(
+                    Telephony.SatelliteDatagrams.COLUMN_DATAGRAM, datagram.getSatelliteDatagram());
+            Uri uri = sInstance.mContentResolver.insert(Telephony.SatelliteDatagrams.CONTENT_URI,
+                    contentValues);
+            if (uri == null) {
+                loge("Cannot insert datagram with datagramId: " + datagramId);
+            } else {
+                logd("Inserted datagram with datagramId: " + datagramId);
+            }
+        }
+
+        private void deleteDatagram(long datagramId) {
+            String whereClause = (Telephony.SatelliteDatagrams.COLUMN_UNIQUE_KEY_DATAGRAM_ID
+                    + "=" + datagramId);
+            try (Cursor cursor = sInstance.mContentResolver.query(
+                    Telephony.SatelliteDatagrams.CONTENT_URI,
+                    null, whereClause, null, null)) {
+                if ((cursor != null) && (cursor.getCount() == 1)) {
+                    int numRowsDeleted = sInstance.mContentResolver.delete(
+                            Telephony.SatelliteDatagrams.CONTENT_URI, whereClause, null);
+                    if (numRowsDeleted == 0) {
+                        loge("Cannot delete datagram with datagramId: " + datagramId);
+                    } else {
+                        logd("Deleted datagram with datagramId: " + datagramId);
+                    }
+                } else {
+                    loge("Datagram with datagramId: " + datagramId + " is not present in DB.");
+                }
+            } catch(SQLException e) {
+                loge("deleteDatagram SQLException e:" + e);
+            }
+        }
+
+        private void onSatelliteDatagramReceived(@NonNull DatagramRetryArgument argument) {
+            try {
+                IVoidConsumer internalAck = new IVoidConsumer.Stub() {
+                    /**
+                     * This callback will be used by datagram receiver app
+                     * to send ack back to Telephony. If the callback is not
+                     * received within five minutes, then Telephony will
+                     * resend the datagram again.
+                     */
+                    @Override
+                    public void accept() {
+                        logd("acknowledgeSatelliteDatagramReceived: "
+                                + "datagramId=" + argument.datagramId);
+                        sendMessage(obtainMessage(EVENT_RECEIVED_ACK, argument));
+                    }
+                };
+
+                argument.listener.onSatelliteDatagramReceived(argument.datagramId,
+                        argument.datagram, argument.pendingCount, internalAck);
+            } catch (RemoteException e) {
+                logd("EVENT_SATELLITE_DATAGRAM_RECEIVED RemoteException: " + e);
+            }
+        }
+
+        @Override
+        public void handleMessage(@NonNull Message msg) {
+            switch (msg.what) {
+                case EVENT_SATELLITE_DATAGRAM_RECEIVED: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    Pair<SatelliteDatagram, Integer> result =
+                            (Pair<SatelliteDatagram, Integer>) ar.result;
+                    SatelliteDatagram satelliteDatagram = result.first;
+                    int pendingCount = result.second;
+                    logd("Received EVENT_SATELLITE_DATAGRAM_RECEIVED for subId=" + mSubId
+                            + " pendingCount:" + pendingCount);
+
+                    if (pendingCount <= 0 && satelliteDatagram == null) {
+                        sInstance.mDatagramController.updateReceiveStatus(mSubId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE,
+                                pendingCount, SatelliteManager.SATELLITE_ERROR_NONE);
+                    } else if (satelliteDatagram != null) {
+                        sInstance.mDatagramController.updateReceiveStatus(mSubId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS,
+                                pendingCount, SatelliteManager.SATELLITE_ERROR_NONE);
+
+                        long datagramId = getDatagramId();
+                        sInstance.mPendingAckCountHashMap.put(datagramId, getNumOfListeners());
+                        insertDatagram(datagramId, satelliteDatagram);
+
+                        mListeners.values().forEach(listener -> {
+                            DatagramRetryArgument argument = new DatagramRetryArgument(datagramId,
+                                    satelliteDatagram, pendingCount, listener);
+                            onSatelliteDatagramReceived(argument);
+                            // wait for ack and retry after the timeout specified.
+                            sendMessageDelayed(
+                                    obtainMessage(EVENT_RETRY_DELIVERING_RECEIVED_DATAGRAM,
+                                            argument), getTimeoutToReceiveAck());
+                        });
+
+                        sInstance.mControllerMetricsStats.reportIncomingDatagramCount(
+                                SatelliteManager.SATELLITE_ERROR_NONE);
+                    }
+
+                    if (pendingCount <= 0) {
+                        sInstance.mDatagramController.updateReceiveStatus(mSubId,
+                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                                pendingCount, SatelliteManager.SATELLITE_ERROR_NONE);
+                    } else {
+                        // Poll for pending datagrams
+                        IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                logd("pollPendingSatelliteDatagram result: " + result);
+                            }
+                        };
+                        Consumer<Integer> callback = FunctionalUtils.ignoreRemoteException(
+                                internalCallback::accept);
+                        sInstance.pollPendingSatelliteDatagramsInternal(mSubId, callback);
+                    }
+
+                    // Send the captured data about incoming datagram to metric
+                    sInstance.reportMetrics(
+                            satelliteDatagram, SatelliteManager.SATELLITE_ERROR_NONE);
+                    break;
+                }
+
+                case EVENT_RETRY_DELIVERING_RECEIVED_DATAGRAM: {
+                    DatagramRetryArgument argument = (DatagramRetryArgument) msg.obj;
+                    logd("Received EVENT_RETRY_DELIVERING_RECEIVED_DATAGRAM datagramId:"
+                            + argument.datagramId);
+                    onSatelliteDatagramReceived(argument);
+                    break;
+                }
+
+                case EVENT_RECEIVED_ACK: {
+                    DatagramRetryArgument argument = (DatagramRetryArgument) msg.obj;
+                    int pendingAckCount = sInstance.mPendingAckCountHashMap
+                            .get(argument.datagramId);
+                    pendingAckCount -= 1;
+                    sInstance.mPendingAckCountHashMap.put(argument.datagramId, pendingAckCount);
+                    logd("Received EVENT_RECEIVED_ACK datagramId:" + argument.datagramId);
+                    removeMessages(EVENT_RETRY_DELIVERING_RECEIVED_DATAGRAM, argument);
+
+                    if (pendingAckCount <= 0) {
+                        // Delete datagram from DB after receiving ack from all listeners
+                        deleteDatagram(argument.datagramId);
+                        sInstance.mPendingAckCountHashMap.remove(argument.datagramId);
+                    }
+                    break;
+                }
+
+                default:
+                    loge("SatelliteDatagramListenerHandler unknown event: " + msg.what);
+            }
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        DatagramReceiverHandlerRequest request;
+        Message onCompleted;
+        AsyncResult ar;
+
+        switch (msg.what) {
+            case CMD_POLL_PENDING_SATELLITE_DATAGRAMS: {
+                request = (DatagramReceiverHandlerRequest) msg.obj;
+                onCompleted =
+                        obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE, request);
+
+                if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                    SatelliteModemInterface.getInstance()
+                            .pollPendingSatelliteDatagrams(onCompleted);
+                    break;
+                }
+
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.pollPendingSatelliteDatagrams(onCompleted);
+                } else {
+                    loge("pollPendingSatelliteDatagrams: No phone object");
+                    mDatagramController.updateReceiveStatus(request.subId,
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
+                            mDatagramController.getReceivePendingCount(),
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+
+                    mDatagramController.updateReceiveStatus(request.subId,
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                            mDatagramController.getReceivePendingCount(),
+                            SatelliteManager.SATELLITE_ERROR_NONE);
+
+                    reportMetrics(null, SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    mControllerMetricsStats.reportIncomingDatagramCount(
+                                    SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    // Send response for current request
+                    ((Consumer<Integer>) request.argument)
+                            .accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                }
+                break;
+            }
+
+            case EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (DatagramReceiverHandlerRequest) ar.userObj;
+                int error = SatelliteServiceUtils.getSatelliteError(ar,
+                        "pollPendingSatelliteDatagrams");
+
+                if (mIsDemoMode && error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    SatelliteDatagram datagram = mDatagramController.getDemoModeDatagram();
+                    final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(
+                            request.subId, mContext);
+                    SatelliteDatagramListenerHandler listenerHandler =
+                            mSatelliteDatagramListenerHandlers.get(validSubId);
+                    if (listenerHandler != null) {
+                        Pair<SatelliteDatagram, Integer> pair = new Pair<>(datagram, 0);
+                        ar = new AsyncResult(null, pair, null);
+                        Message message = listenerHandler.obtainMessage(
+                                SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAM_RECEIVED,
+                                ar);
+                        listenerHandler.sendMessage(message);
+                    } else {
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    }
+                }
+
+                logd("EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE error: " + error);
+                if (error != SatelliteManager.SATELLITE_ERROR_NONE) {
+                    mDatagramController.updateReceiveStatus(request.subId,
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
+                            mDatagramController.getReceivePendingCount(), error);
+
+                    mDatagramController.updateReceiveStatus(request.subId,
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                            mDatagramController.getReceivePendingCount(),
+                            SatelliteManager.SATELLITE_ERROR_NONE);
+
+                    reportMetrics(null, error);
+                    mControllerMetricsStats.reportIncomingDatagramCount(error);
+                }
+                // Send response for current request
+                ((Consumer<Integer>) request.argument).accept(error);
+                break;
+            }
+
+            case EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT: {
+                handleEventSatelliteAlignedTimeout((DatagramReceiverHandlerRequest) msg.obj);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Register to receive incoming datagrams over satellite.
+     *
+     * @param subId The subId of the subscription to register for incoming satellite datagrams.
+     * @param callback The callback to handle incoming datagrams over satellite.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+     */
+    @SatelliteManager.SatelliteError public int registerForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        if (!SatelliteController.getInstance().isSatelliteSupported()) {
+            return SatelliteManager.SATELLITE_NOT_SUPPORTED;
+        }
+
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        SatelliteDatagramListenerHandler satelliteDatagramListenerHandler =
+                mSatelliteDatagramListenerHandlers.get(validSubId);
+        if (satelliteDatagramListenerHandler == null) {
+            satelliteDatagramListenerHandler = new SatelliteDatagramListenerHandler(
+                    mLooper, validSubId);
+            if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                SatelliteModemInterface.getInstance().registerForSatelliteDatagramsReceived(
+                        satelliteDatagramListenerHandler,
+                        SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAM_RECEIVED, null);
+            } else {
+                Phone phone = SatelliteServiceUtils.getPhone();
+                phone.registerForSatelliteDatagramsReceived(satelliteDatagramListenerHandler,
+                        SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAM_RECEIVED, null);
+            }
+        }
+
+        satelliteDatagramListenerHandler.addListener(callback);
+        mSatelliteDatagramListenerHandlers.put(validSubId, satelliteDatagramListenerHandler);
+        return SatelliteManager.SATELLITE_ERROR_NONE;
+    }
+
+    /**
+     * Unregister to stop receiving incoming datagrams over satellite.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteDatagram(int, ISatelliteDatagramCallback)}.
+     */
+    public void unregisterForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        SatelliteDatagramListenerHandler handler =
+                mSatelliteDatagramListenerHandlers.get(validSubId);
+        if (handler != null) {
+            handler.removeListener(callback);
+
+            if (!handler.hasListeners()) {
+                mSatelliteDatagramListenerHandlers.remove(validSubId);
+                if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                    SatelliteModemInterface.getInstance()
+                            .unregisterForSatelliteDatagramsReceived(handler);
+                } else {
+                    Phone phone = SatelliteServiceUtils.getPhone();
+                    if (phone != null) {
+                        phone.unregisterForSatelliteDatagramsReceived(handler);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Poll pending satellite datagrams over satellite.
+     *
+     * This method requests modem to check if there are any pending datagrams to be received over
+     * satellite. If there are any incoming datagrams, they will be received via
+     * {@link android.telephony.satellite.SatelliteDatagramCallback
+     * #onSatelliteDatagramReceived(long, SatelliteDatagram, int, Consumer)}
+     *
+     * @param subId The subId of the subscription used for receiving datagrams.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
+        if (!mDatagramController.isPollingInIdleState()) {
+            // Poll request should be sent to satellite modem only when it is free.
+            logd("pollPendingSatelliteDatagrams: satellite modem is busy receiving datagrams.");
+            callback.accept(SatelliteManager.SATELLITE_MODEM_BUSY);
+            return;
+        }
+
+        pollPendingSatelliteDatagramsInternal(subId, callback);
+    }
+
+    private void pollPendingSatelliteDatagramsInternal(int subId,
+            @NonNull Consumer<Integer> callback) {
+        if (!mDatagramController.isSendingInIdleState()) {
+            // Poll request should be sent to satellite modem only when it is free.
+            logd("pollPendingSatelliteDatagrams: satellite modem is busy sending datagrams.");
+            callback.accept(SatelliteManager.SATELLITE_MODEM_BUSY);
+            return;
+        }
+
+        mDatagramController.updateReceiveStatus(subId,
+                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING,
+                mDatagramController.getReceivePendingCount(),
+                SatelliteManager.SATELLITE_ERROR_NONE);
+        mDatagramTransferStartTime = System.currentTimeMillis();
+        Phone phone = SatelliteServiceUtils.getPhone();
+
+        if (mIsDemoMode) {
+            DatagramReceiverHandlerRequest request = new DatagramReceiverHandlerRequest(
+                    callback, phone, subId);
+            synchronized (mLock) {
+                if (mIsAligned) {
+                    Message msg = obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE,
+                            request);
+                    AsyncResult.forMessage(msg, null, null);
+                    msg.sendToTarget();
+                } else {
+                    startSatelliteAlignedTimer(request);
+                }
+            }
+        } else {
+            sendRequestAsync(CMD_POLL_PENDING_SATELLITE_DATAGRAMS, callback, phone, subId);
+        }
+    }
+
+    /**
+     * This function is used by {@link DatagramController} to notify {@link DatagramReceiver}
+     * that satellite modem state has changed.
+     *
+     * @param state Current satellite modem state.
+     */
+    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
+        synchronized (mLock) {
+            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
+                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
+                logd("onSatelliteModemStateChanged: cleaning up resources");
+                cleanUpResources();
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void cleanupDemoModeResources() {
+        if (isSatelliteAlignedTimerStarted()) {
+            stopSatelliteAlignedTimer();
+            if (mPollPendingSatelliteDatagramsRequest == null) {
+                loge("Satellite aligned timer was started "
+                        + "but mPollPendingSatelliteDatagramsRequest is null");
+            } else {
+                Consumer<Integer> callback =
+                        (Consumer<Integer>) mPollPendingSatelliteDatagramsRequest.argument;
+                callback.accept(SatelliteManager.SATELLITE_REQUEST_ABORTED);
+            }
+        }
+        mIsDemoMode = false;
+        mPollPendingSatelliteDatagramsRequest = null;
+        mIsAligned = false;
+    }
+
+    @GuardedBy("mLock")
+    private void cleanUpResources() {
+        if (mDatagramController.isReceivingDatagrams()) {
+            mDatagramController.updateReceiveStatus(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
+                    mDatagramController.getReceivePendingCount(),
+                    SatelliteManager.SATELLITE_REQUEST_ABORTED);
+        }
+        mDatagramController.updateReceiveStatus(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, 0,
+                SatelliteManager.SATELLITE_ERROR_NONE);
+        cleanupDemoModeResources();
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread and returns immediately.
+     *
+     * @param command command to be executed on the main thread
+     * @param argument additional parameters required to perform of the operation
+     * @param phone phone object used to perform the operation
+     * @param subId The subId of the subscription used for the request.
+     */
+    private void sendRequestAsync(int command, @NonNull Object argument, @Nullable Phone phone,
+            int subId) {
+        DatagramReceiverHandlerRequest request = new DatagramReceiverHandlerRequest(
+                argument, phone, subId);
+        Message msg = this.obtainMessage(command, request);
+        msg.sendToTarget();
+    }
+
+    /** Report incoming datagram related metrics */
+    private void reportMetrics(@Nullable SatelliteDatagram satelliteDatagram,
+            @NonNull @SatelliteManager.SatelliteError int resultCode) {
+        int datagramSizeRoundedBytes = -1;
+        int datagramTransferTime = 0;
+
+        if (satelliteDatagram != null) {
+            if (satelliteDatagram.getSatelliteDatagram() != null) {
+                int sizeBytes = satelliteDatagram.getSatelliteDatagram().length;
+                // rounded by 10 bytes
+                datagramSizeRoundedBytes =
+                        (int) (Math.round((double) sizeBytes / ROUNDING_UNIT) * ROUNDING_UNIT);
+            }
+            datagramTransferTime = (int) (System.currentTimeMillis() - mDatagramTransferStartTime);
+            mDatagramTransferStartTime = 0;
+        }
+
+        SatelliteStats.getInstance().onSatelliteIncomingDatagramMetrics(
+                new SatelliteStats.SatelliteIncomingDatagramParams.Builder()
+                        .setResultCode(resultCode)
+                        .setDatagramSizeBytes(datagramSizeRoundedBytes)
+                        .setDatagramTransferTimeMillis(datagramTransferTime)
+                        .build());
+    }
+
+    /** Set demo mode
+     *
+     * @param isDemoMode {@code true} means demo mode is on, {@code false} otherwise.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    protected void setDemoMode(boolean isDemoMode) {
+        mIsDemoMode = isDemoMode;
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    protected void onDeviceAlignedWithSatellite(boolean isAligned) {
+        if (mIsDemoMode) {
+            synchronized (mLock) {
+                mIsAligned = isAligned;
+                if (isAligned) handleEventSatelliteAligned();
+            }
+        }
+    }
+
+    private void startSatelliteAlignedTimer(DatagramReceiverHandlerRequest request) {
+        if (isSatelliteAlignedTimerStarted()) {
+            logd("Satellite aligned timer was already started");
+            return;
+        }
+        mPollPendingSatelliteDatagramsRequest = request;
+        sendMessageDelayed(
+                obtainMessage(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT, request),
+                getSatelliteAlignedTimeoutDuration());
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected long getSatelliteAlignedTimeoutDuration() {
+        return mDatagramController.getSatelliteAlignedTimeoutDuration();
+    }
+
+    private void handleEventSatelliteAligned() {
+        if (isSatelliteAlignedTimerStarted()) {
+            stopSatelliteAlignedTimer();
+
+            if (mPollPendingSatelliteDatagramsRequest == null) {
+                loge("handleSatelliteAlignedTimer: mPollPendingSatelliteDatagramsRequest is null");
+            } else {
+                Message message = obtainMessage(
+                        EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE,
+                        mPollPendingSatelliteDatagramsRequest);
+                mPollPendingSatelliteDatagramsRequest = null;
+                AsyncResult.forMessage(message, null, null);
+                message.sendToTarget();
+            }
+        }
+    }
+
+    private void handleEventSatelliteAlignedTimeout(DatagramReceiverHandlerRequest request) {
+        SatelliteManager.SatelliteException exception =
+                new SatelliteManager.SatelliteException(
+                        SatelliteManager.SATELLITE_NOT_REACHABLE);
+        Message message = obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE, request);
+        AsyncResult.forMessage(message, null, exception);
+        message.sendToTarget();
+    }
+
+    private boolean isSatelliteAlignedTimerStarted() {
+        return hasMessages(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT);
+    }
+
+    private void stopSatelliteAlignedTimer() {
+        removeMessages(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT);
+    }
+
+    /**
+     * Destroys this DatagramDispatcher. Used for tearing down static resources during testing.
+     */
+    @VisibleForTesting
+    public void destroy() {
+        sInstance = null;
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/PointingAppController.java b/src/java/com/android/internal/telephony/satellite/PointingAppController.java
new file mode 100644
index 0000000..f7f93cf
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/PointingAppController.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.telephony.Rlog;
+import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.PointingInfo;
+import android.telephony.satellite.SatelliteManager;
+import android.text.TextUtils;
+
+import com.android.internal.R;
+import com.android.internal.telephony.Phone;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+
+/**
+ * PointingApp controller to manage interactions with PointingUI app.
+ */
+public class PointingAppController {
+    private static final String TAG = "PointingAppController";
+    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
+    private static final boolean DEBUG = !"user".equals(Build.TYPE);
+
+    @NonNull
+    private static PointingAppController sInstance;
+    @NonNull private final Context mContext;
+    private boolean mStartedSatelliteTransmissionUpdates;
+    @NonNull private String mPointingUiPackageName = "";
+    @NonNull private String mPointingUiClassName = "";
+
+    /**
+     * Map key: subId, value: SatelliteTransmissionUpdateHandler to notify registrants.
+     */
+    private final ConcurrentHashMap<Integer, SatelliteTransmissionUpdateHandler>
+            mSatelliteTransmissionUpdateHandlers = new ConcurrentHashMap<>();
+
+    /**
+     * @return The singleton instance of PointingAppController.
+     */
+    public static PointingAppController getInstance() {
+        if (sInstance == null) {
+            loge("PointingAppController was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the PointingAppController singleton instance.
+     * @param context The Context to use to create the PointingAppController.
+     * @return The singleton instance of PointingAppController.
+     */
+    public static PointingAppController make(@NonNull Context context) {
+        if (sInstance == null) {
+            sInstance = new PointingAppController(context);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a PointingAppController to manage interactions with PointingUI app.
+     *
+     * @param context The Context for the PointingUIController.
+     */
+    private PointingAppController(@NonNull Context context) {
+        mContext = context;
+        mStartedSatelliteTransmissionUpdates = false;
+    }
+
+    /**
+     * Set the flag mStartedSatelliteTransmissionUpdates to true or false based on the state of
+     * transmission updates
+     * @param startedSatelliteTransmissionUpdates boolean to set the flag
+     */
+    public void setStartedSatelliteTransmissionUpdates(
+            boolean startedSatelliteTransmissionUpdates) {
+        mStartedSatelliteTransmissionUpdates = startedSatelliteTransmissionUpdates;
+    }
+
+    private static final class DatagramTransferStateHandlerRequest {
+        public int datagramTransferState;
+        public int pendingCount;
+        public int errorCode;
+
+        DatagramTransferStateHandlerRequest(int datagramTransferState, int pendingCount,
+                int errorCode) {
+            this.datagramTransferState = datagramTransferState;
+            this.pendingCount = pendingCount;
+            this.errorCode = errorCode;
+        }
+    }
+
+
+    private static final class SatelliteTransmissionUpdateHandler extends Handler {
+        public static final int EVENT_POSITION_INFO_CHANGED = 1;
+        public static final int EVENT_SEND_DATAGRAM_STATE_CHANGED = 2;
+        public static final int EVENT_RECEIVE_DATAGRAM_STATE_CHANGED = 3;
+        public static final int EVENT_DATAGRAM_TRANSFER_STATE_CHANGED = 4;
+
+        private final ConcurrentHashMap<IBinder, ISatelliteTransmissionUpdateCallback> mListeners;
+        SatelliteTransmissionUpdateHandler(Looper looper) {
+            super(looper);
+            mListeners = new ConcurrentHashMap<>();
+        }
+
+        public void addListener(ISatelliteTransmissionUpdateCallback listener) {
+            mListeners.put(listener.asBinder(), listener);
+        }
+
+        public void removeListener(ISatelliteTransmissionUpdateCallback listener) {
+            mListeners.remove(listener.asBinder());
+        }
+
+        public boolean hasListeners() {
+            return !mListeners.isEmpty();
+        }
+
+        @Override
+        public void handleMessage(@NonNull Message msg) {
+            switch (msg.what) {
+                case EVENT_POSITION_INFO_CHANGED: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    PointingInfo pointingInfo = (PointingInfo) ar.result;
+                    List<IBinder> toBeRemoved = new ArrayList<>();
+                    mListeners.values().forEach(listener -> {
+                        try {
+                            listener.onSatellitePositionChanged(pointingInfo);
+                        } catch (RemoteException e) {
+                            logd("EVENT_POSITION_INFO_CHANGED RemoteException: " + e);
+                            toBeRemoved.add(listener.asBinder());
+                        }
+                    });
+                    toBeRemoved.forEach(listener -> {
+                        mListeners.remove(listener);
+                    });
+                    break;
+                }
+
+                case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED: {
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    logd("Receive EVENT_DATAGRAM_TRANSFER_STATE_CHANGED state=" + (int) ar.result);
+                    break;
+                }
+
+                case EVENT_SEND_DATAGRAM_STATE_CHANGED: {
+                    logd("Received EVENT_SEND_DATAGRAM_STATE_CHANGED");
+                    DatagramTransferStateHandlerRequest request =
+                            (DatagramTransferStateHandlerRequest) msg.obj;
+                    List<IBinder> toBeRemoved = new ArrayList<>();
+                    mListeners.values().forEach(listener -> {
+                        try {
+                            listener.onSendDatagramStateChanged(request.datagramTransferState,
+                                    request.pendingCount, request.errorCode);
+                        } catch (RemoteException e) {
+                            logd("EVENT_SEND_DATAGRAM_STATE_CHANGED RemoteException: " + e);
+                            toBeRemoved.add(listener.asBinder());
+                        }
+                    });
+                    toBeRemoved.forEach(listener -> {
+                        mListeners.remove(listener);
+                    });
+                    break;
+                }
+
+                case EVENT_RECEIVE_DATAGRAM_STATE_CHANGED: {
+                    logd("Received EVENT_RECEIVE_DATAGRAM_STATE_CHANGED");
+                    DatagramTransferStateHandlerRequest request =
+                            (DatagramTransferStateHandlerRequest) msg.obj;
+                    List<IBinder> toBeRemoved = new ArrayList<>();
+                    mListeners.values().forEach(listener -> {
+                        try {
+                            listener.onReceiveDatagramStateChanged(request.datagramTransferState,
+                                    request.pendingCount, request.errorCode);
+                        } catch (RemoteException e) {
+                            logd("EVENT_RECEIVE_DATAGRAM_STATE_CHANGED RemoteException: " + e);
+                            toBeRemoved.add(listener.asBinder());
+                        }
+                    });
+                    toBeRemoved.forEach(listener -> {
+                        mListeners.remove(listener);
+                    });
+                    break;
+                }
+
+                default:
+                    loge("SatelliteTransmissionUpdateHandler unknown event: " + msg.what);
+            }
+        }
+    }
+
+    /**
+     * Register to start receiving updates for satellite position and datagram transfer state
+     * @param subId The subId of the subscription to register for receiving the updates.
+     * @param callback The callback to notify of satellite transmission updates.
+     * @param phone The Phone object to unregister for receiving the updates.
+     */
+    public void registerForSatelliteTransmissionUpdates(int subId,
+            ISatelliteTransmissionUpdateCallback callback, Phone phone) {
+        SatelliteTransmissionUpdateHandler handler =
+                mSatelliteTransmissionUpdateHandlers.get(subId);
+        if (handler != null) {
+            handler.addListener(callback);
+            return;
+        } else {
+            handler = new SatelliteTransmissionUpdateHandler(Looper.getMainLooper());
+            handler.addListener(callback);
+            mSatelliteTransmissionUpdateHandlers.put(subId, handler);
+            if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                SatelliteModemInterface.getInstance().registerForSatellitePositionInfoChanged(
+                        handler, SatelliteTransmissionUpdateHandler.EVENT_POSITION_INFO_CHANGED,
+                        null);
+                SatelliteModemInterface.getInstance().registerForDatagramTransferStateChanged(
+                        handler,
+                        SatelliteTransmissionUpdateHandler.EVENT_DATAGRAM_TRANSFER_STATE_CHANGED,
+                        null);
+            } else {
+                phone.registerForSatellitePositionInfoChanged(handler,
+                        SatelliteTransmissionUpdateHandler.EVENT_POSITION_INFO_CHANGED, null);
+            }
+        }
+    }
+
+    /**
+     * Unregister to stop receiving updates on satellite position and datagram transfer state
+     * If the callback was not registered before, it is ignored
+     * @param subId The subId of the subscription to unregister for receiving the updates.
+     * @param result The callback to get the error code in case of failure
+     * @param callback The callback that was passed to {@link
+     * #registerForSatelliteTransmissionUpdates(int, ISatelliteTransmissionUpdateCallback, Phone)}.
+     * @param phone The Phone object to unregister for receiving the updates
+     */
+    public void unregisterForSatelliteTransmissionUpdates(int subId, Consumer<Integer> result,
+            ISatelliteTransmissionUpdateCallback callback, Phone phone) {
+        SatelliteTransmissionUpdateHandler handler =
+                mSatelliteTransmissionUpdateHandlers.get(subId);
+        if (handler != null) {
+            handler.removeListener(callback);
+
+            if (handler.hasListeners()) {
+                result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+                return;
+            }
+
+            mSatelliteTransmissionUpdateHandlers.remove(subId);
+            if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+                SatelliteModemInterface.getInstance().unregisterForSatellitePositionInfoChanged(
+                        handler);
+                SatelliteModemInterface.getInstance().unregisterForDatagramTransferStateChanged(
+                        handler);
+            } else {
+                if (phone == null) {
+                    result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    return;
+                }
+                phone.unregisterForSatellitePositionInfoChanged(handler);
+            }
+        }
+    }
+
+    /**
+     * Start receiving satellite trasmission updates.
+     * This can be called by the pointing UI when the user starts pointing to the satellite.
+     * Modem should continue to report the pointing input as the device or satellite moves.
+     * The transmission updates will be received via
+     * {@link android.telephony.satellite.SatelliteTransmissionUpdateCallback
+     * #onSatellitePositionChanged(pointingInfo)}.
+     */
+    public void startSatelliteTransmissionUpdates(@NonNull Message message, @Nullable Phone phone) {
+        if (mStartedSatelliteTransmissionUpdates) {
+            logd("startSatelliteTransmissionUpdates: already started");
+            AsyncResult.forMessage(message, null, new SatelliteManager.SatelliteException(
+                    SatelliteManager.SATELLITE_ERROR_NONE));
+            message.sendToTarget();
+            return;
+        }
+        if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+            SatelliteModemInterface.getInstance().startSendingSatellitePointingInfo(message);
+            mStartedSatelliteTransmissionUpdates = true;
+            return;
+        }
+        if (phone != null) {
+            phone.startSatellitePositionUpdates(message);
+            mStartedSatelliteTransmissionUpdates = true;
+        } else {
+            loge("startSatelliteTransmissionUpdates: No phone object");
+            AsyncResult.forMessage(message, null, new SatelliteManager.SatelliteException(
+                    SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE));
+            message.sendToTarget();
+        }
+    }
+
+    /**
+     * Stop receiving satellite transmission updates.
+     * This can be called by the pointing UI when the user stops pointing to the satellite.
+     */
+    public void stopSatelliteTransmissionUpdates(@NonNull Message message, @Nullable Phone phone) {
+        if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
+            SatelliteModemInterface.getInstance().stopSendingSatellitePointingInfo(message);
+            return;
+        }
+        if (phone != null) {
+            phone.stopSatellitePositionUpdates(message);
+        } else {
+            loge("startSatelliteTransmissionUpdates: No phone object");
+            AsyncResult.forMessage(message, null, new SatelliteManager.SatelliteException(
+                    SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE));
+            message.sendToTarget();
+        }
+    }
+
+    /**
+     * Check if Pointing is needed and Launch Pointing UI
+     * @param needFullScreenPointingUI if pointing UI has to be launchd with Full screen
+     */
+    public void startPointingUI(boolean needFullScreenPointingUI) {
+        String packageName = getPointingUiPackageName();
+        if (TextUtils.isEmpty(packageName)) {
+            logd("startPointingUI: config_pointing_ui_package is not set. Ignore the request");
+            return;
+        }
+
+        Intent launchIntent;
+        String className = getPointingUiClassName();
+        if (!TextUtils.isEmpty(className)) {
+            launchIntent = new Intent()
+                    .setComponent(new ComponentName(packageName, className))
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        } else {
+            launchIntent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
+        }
+        if (launchIntent == null) {
+            loge("startPointingUI: launchIntent is null");
+            return;
+        }
+        launchIntent.putExtra("needFullScreen", needFullScreenPointingUI);
+
+        try {
+            mContext.startActivity(launchIntent);
+        } catch (ActivityNotFoundException ex) {
+            loge("startPointingUI: Pointing UI app activity is not found, ex=" + ex);
+        }
+    }
+
+    public void updateSendDatagramTransferState(int subId,
+            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
+            int sendPendingCount, int errorCode) {
+        DatagramTransferStateHandlerRequest request = new DatagramTransferStateHandlerRequest(
+                datagramTransferState, sendPendingCount, errorCode);
+        SatelliteTransmissionUpdateHandler handler =
+                mSatelliteTransmissionUpdateHandlers.get(subId);
+
+        if (handler != null) {
+            Message msg = handler.obtainMessage(
+                    SatelliteTransmissionUpdateHandler.EVENT_SEND_DATAGRAM_STATE_CHANGED,
+                    request);
+            msg.sendToTarget();
+        } else {
+            loge("SatelliteTransmissionUpdateHandler not found for subId: " + subId);
+        }
+    }
+
+    public void updateReceiveDatagramTransferState(int subId,
+            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
+            int receivePendingCount, int errorCode) {
+        DatagramTransferStateHandlerRequest request = new DatagramTransferStateHandlerRequest(
+                datagramTransferState, receivePendingCount, errorCode);
+        SatelliteTransmissionUpdateHandler handler =
+                mSatelliteTransmissionUpdateHandlers.get(subId);
+
+        if (handler != null) {
+            Message msg = handler.obtainMessage(
+                    SatelliteTransmissionUpdateHandler.EVENT_RECEIVE_DATAGRAM_STATE_CHANGED,
+                    request);
+            msg.sendToTarget();
+        } else {
+            loge(" SatelliteTransmissionUpdateHandler not found for subId: " + subId);
+        }
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite pointing UI app package and class names.
+     *
+     * @param packageName The package name of the satellite pointing UI app.
+     * @param className The class name of the satellite pointing UI app.
+     * @return {@code true} if the satellite pointing UI app package and class is set successfully,
+     * {@code false} otherwise.
+     */
+    boolean setSatellitePointingUiClassName(
+            @Nullable String packageName, @Nullable String className) {
+        if (!isMockModemAllowed()) {
+            loge("setSatellitePointingUiClassName: modifying satellite pointing UI package and "
+                    + "class name is not allowed");
+            return false;
+        }
+
+        logd("setSatellitePointingUiClassName: config_pointing_ui_package is updated, new "
+                + "packageName=" + packageName
+                + ", config_pointing_ui_class new className=" + className);
+
+        if (packageName == null || packageName.equals("null")) {
+            mPointingUiPackageName = "";
+            mPointingUiClassName = "";
+        } else {
+            mPointingUiPackageName = packageName;
+            if (className == null || className.equals("null")) {
+                mPointingUiClassName = "";
+            } else {
+                mPointingUiClassName = className;
+            }
+        }
+
+        return true;
+    }
+
+    @NonNull private String getPointingUiPackageName() {
+        if (!TextUtils.isEmpty(mPointingUiPackageName)) {
+            return mPointingUiPackageName;
+        }
+        return TextUtils.emptyIfNull(mContext.getResources().getString(
+                R.string.config_pointing_ui_package));
+    }
+
+    @NonNull private String getPointingUiClassName() {
+        if (!TextUtils.isEmpty(mPointingUiClassName)) {
+            return mPointingUiClassName;
+        }
+        return TextUtils.emptyIfNull(mContext.getResources().getString(
+                R.string.config_pointing_ui_class));
+    }
+
+    private boolean isMockModemAllowed() {
+        return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+    /**
+     * TODO: The following needs to be added in this class:
+     * - check if pointingUI crashes - then restart it
+     */
+}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
new file mode 100644
index 0000000..5cd8444
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -0,0 +1,2280 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.database.ContentObserver;
+import android.net.wifi.WifiManager;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.provider.Settings;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteStateCallback;
+import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+import android.uwb.UwbManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.internal.telephony.satellite.metrics.ProvisionMetricsStats;
+import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
+import com.android.internal.util.FunctionalUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+/**
+ * Satellite controller is the backend service of
+ * {@link android.telephony.satellite.SatelliteManager}.
+ */
+public class SatelliteController extends Handler {
+    private static final String TAG = "SatelliteController";
+    /** Whether enabling verbose debugging message or not. */
+    private static final boolean DBG = false;
+    /** File used to store shared preferences related to satellite. */
+    public static final String SATELLITE_SHARED_PREF = "satellite_shared_pref";
+    /** Value to pass for the setting key SATELLITE_MODE_ENABLED, enabled = 1, disabled = 0 */
+    public static final int SATELLITE_MODE_ENABLED_TRUE = 1;
+    public static final int SATELLITE_MODE_ENABLED_FALSE = 0;
+
+    /** Message codes used in handleMessage() */
+    //TODO: Move the Commands and events related to position updates to PointingAppController
+    private static final int CMD_START_SATELLITE_TRANSMISSION_UPDATES = 1;
+    private static final int EVENT_START_SATELLITE_TRANSMISSION_UPDATES_DONE = 2;
+    private static final int CMD_STOP_SATELLITE_TRANSMISSION_UPDATES = 3;
+    private static final int EVENT_STOP_SATELLITE_TRANSMISSION_UPDATES_DONE = 4;
+    private static final int CMD_PROVISION_SATELLITE_SERVICE = 7;
+    private static final int EVENT_PROVISION_SATELLITE_SERVICE_DONE = 8;
+    private static final int CMD_DEPROVISION_SATELLITE_SERVICE = 9;
+    private static final int EVENT_DEPROVISION_SATELLITE_SERVICE_DONE = 10;
+    private static final int CMD_SET_SATELLITE_ENABLED = 11;
+    private static final int EVENT_SET_SATELLITE_ENABLED_DONE = 12;
+    private static final int CMD_IS_SATELLITE_ENABLED = 13;
+    private static final int EVENT_IS_SATELLITE_ENABLED_DONE = 14;
+    private static final int CMD_IS_SATELLITE_SUPPORTED = 15;
+    private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 16;
+    private static final int CMD_GET_SATELLITE_CAPABILITIES = 17;
+    private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 18;
+    private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 19;
+    private static final int EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE = 20;
+    private static final int CMD_GET_TIME_SATELLITE_NEXT_VISIBLE = 21;
+    private static final int EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE = 22;
+    private static final int EVENT_RADIO_STATE_CHANGED = 23;
+    private static final int CMD_IS_SATELLITE_PROVISIONED = 24;
+    private static final int EVENT_IS_SATELLITE_PROVISIONED_DONE = 25;
+    private static final int EVENT_SATELLITE_PROVISION_STATE_CHANGED = 26;
+    private static final int EVENT_PENDING_DATAGRAMS = 27;
+    private static final int EVENT_SATELLITE_MODEM_STATE_CHANGED = 28;
+
+    @NonNull private static SatelliteController sInstance;
+    @NonNull private final Context mContext;
+    @NonNull private final SatelliteModemInterface mSatelliteModemInterface;
+    @NonNull private SatelliteSessionController mSatelliteSessionController;
+    @NonNull private final PointingAppController mPointingAppController;
+    @NonNull private final DatagramController mDatagramController;
+    @NonNull private final ControllerMetricsStats mControllerMetricsStats;
+    @NonNull private final ProvisionMetricsStats mProvisionMetricsStats;
+    private SharedPreferences mSharedPreferences = null;
+    private final CommandsInterface mCi;
+    private ContentResolver mContentResolver = null;
+
+    private final Object mRadioStateLock = new Object();
+
+    /** Flags to indicate whether the resepective radio is enabled */
+    @GuardedBy("mRadioStateLock")
+    private boolean mBTStateEnabled = false;
+    @GuardedBy("mRadioStateLock")
+    private boolean mNfcStateEnabled = false;
+    @GuardedBy("mRadioStateLock")
+    private boolean mUwbStateEnabled = false;
+    @GuardedBy("mRadioStateLock")
+    private boolean mWifiStateEnabled = false;
+
+    // Flags to indicate that respective radios need to be disabled when satellite is enabled
+    private boolean mDisableBTOnSatelliteEnabled = false;
+    private boolean mDisableNFCOnSatelliteEnabled = false;
+    private boolean mDisableUWBOnSatelliteEnabled = false;
+    private boolean mDisableWifiOnSatelliteEnabled = false;
+
+    private final Object mSatelliteEnabledRequestLock = new Object();
+    @GuardedBy("mSatelliteEnabledRequestLock")
+    private RequestSatelliteEnabledArgument mSatelliteEnabledRequest = null;
+    /** Flag to indicate that satellite is enabled successfully
+     * and waiting for all the radios to be disabled so that success can be sent to callback
+     */
+    @GuardedBy("mSatelliteEnabledRequestLock")
+    private boolean mWaitingForRadioDisabled = false;
+
+    private final AtomicBoolean mRegisteredForProvisionStateChangedWithSatelliteService =
+            new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForProvisionStateChangedWithPhone =
+            new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForPendingDatagramCountWithSatelliteService =
+            new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForPendingDatagramCountWithPhone =
+            new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForSatelliteModemStateChangedWithSatelliteService =
+            new AtomicBoolean(false);
+    private final AtomicBoolean mRegisteredForSatelliteModemStateChangedWithPhone =
+            new AtomicBoolean(false);
+    /**
+     * Map key: subId, value: callback to get error code of the provision request.
+     */
+    private final ConcurrentHashMap<Integer, Consumer<Integer>> mSatelliteProvisionCallbacks =
+            new ConcurrentHashMap<>();
+
+    /**
+     * Map key: binder of the callback, value: callback to receive provision state changed events.
+     */
+    private final ConcurrentHashMap<IBinder, ISatelliteProvisionStateCallback>
+            mSatelliteProvisionStateChangedListeners = new ConcurrentHashMap<>();
+    private final Object mIsSatelliteSupportedLock = new Object();
+    @GuardedBy("mIsSatelliteSupportedLock")
+    private Boolean mIsSatelliteSupported = null;
+    private boolean mIsDemoModeEnabled = false;
+    private final Object mIsSatelliteEnabledLock = new Object();
+    @GuardedBy("mIsSatelliteEnabledLock")
+    private Boolean mIsSatelliteEnabled = null;
+    private boolean mIsRadioOn = false;
+    private final Object mIsSatelliteProvisionedLock = new Object();
+    @GuardedBy("mIsSatelliteProvisionedLock")
+    private Boolean mIsSatelliteProvisioned = null;
+    private final Object mSatelliteCapabilitiesLock = new Object();
+    @GuardedBy("mSatelliteCapabilitiesLock")
+    private SatelliteCapabilities mSatelliteCapabilities;
+    private final Object mNeedsSatellitePointingLock = new Object();
+    @GuardedBy("mNeedsSatellitePointingLock")
+    private boolean mNeedsSatellitePointing = false;
+
+    /**
+     * @return The singleton instance of SatelliteController.
+     */
+    public static SatelliteController getInstance() {
+        if (sInstance == null) {
+            loge("SatelliteController was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the SatelliteController singleton instance.
+     * @param context The Context to use to create the SatelliteController.
+     */
+    public static void make(@NonNull Context context) {
+        if (sInstance == null) {
+            HandlerThread satelliteThread = new HandlerThread(TAG);
+            satelliteThread.start();
+            sInstance = new SatelliteController(context, satelliteThread.getLooper());
+        }
+    }
+
+    /**
+     * Create a SatelliteController to act as a backend service of
+     * {@link android.telephony.satellite.SatelliteManager}
+     *
+     * @param context The Context for the SatelliteController.
+     * @param looper The looper for the handler. It does not run on main thread.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public SatelliteController(@NonNull Context context, @NonNull Looper looper) {
+        super(looper);
+
+        mContext = context;
+        Phone phone = SatelliteServiceUtils.getPhone();
+        mCi = phone.mCi;
+        // Create the SatelliteModemInterface singleton, which is used to manage connections
+        // to the satellite service and HAL interface.
+        mSatelliteModemInterface = SatelliteModemInterface.make(mContext, this);
+
+        // Create the PointingUIController singleton,
+        // which is used to manage interactions with PointingUI app.
+        mPointingAppController = PointingAppController.make(mContext);
+
+        // Create the SatelliteControllerMetrics to report controller metrics
+        // should be called before making DatagramController
+        mControllerMetricsStats = ControllerMetricsStats.make(mContext);
+        mProvisionMetricsStats = ProvisionMetricsStats.getOrCreateInstance();
+
+        // Create the DatagramController singleton,
+        // which is used to send and receive satellite datagrams.
+        mDatagramController = DatagramController.make(mContext, looper, mPointingAppController);
+
+        requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                new ResultReceiver(this) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        logd("requestIsSatelliteSupported: resultCode=" + resultCode);
+                    }
+                });
+        mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
+        mIsRadioOn = phone.isRadioOn();
+        registerForSatelliteProvisionStateChanged();
+        registerForPendingDatagramCount();
+        registerForSatelliteModemStateChanged();
+        mContentResolver = mContext.getContentResolver();
+
+        try {
+            mSharedPreferences = mContext.getSharedPreferences(SATELLITE_SHARED_PREF,
+                    Context.MODE_PRIVATE);
+        } catch (Exception e) {
+            loge("Cannot get default shared preferences: " + e);
+        }
+
+        initializeSatelliteModeRadios();
+
+        ContentObserver satelliteModeRadiosContentObserver = new ContentObserver(this) {
+            @Override
+            public void onChange(boolean selfChange) {
+                initializeSatelliteModeRadios();
+            }
+        };
+        if (mContentResolver != null) {
+            mContentResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.SATELLITE_MODE_RADIOS),
+                    false, satelliteModeRadiosContentObserver);
+        }
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void initializeSatelliteModeRadios() {
+        if (mContentResolver != null) {
+            BTWifiNFCStateReceiver bTWifiNFCSateReceiver = new BTWifiNFCStateReceiver();
+            UwbAdapterStateCallback uwbAdapterStateCallback = new UwbAdapterStateCallback();
+            IntentFilter radioStateIntentFilter = new IntentFilter();
+
+            synchronized (mRadioStateLock) {
+                // Initialize radio states to default value
+                mDisableBTOnSatelliteEnabled = false;
+                mDisableNFCOnSatelliteEnabled = false;
+                mDisableWifiOnSatelliteEnabled = false;
+                mDisableUWBOnSatelliteEnabled = false;
+
+                mBTStateEnabled = false;
+                mNfcStateEnabled = false;
+                mWifiStateEnabled = false;
+                mUwbStateEnabled = false;
+
+                // Read satellite mode radios from settings
+                String satelliteModeRadios = Settings.Global.getString(mContentResolver,
+                        Settings.Global.SATELLITE_MODE_RADIOS);
+                if (satelliteModeRadios == null) {
+                    loge("initializeSatelliteModeRadios: satelliteModeRadios is null");
+                    return;
+                }
+                logd("Radios To be checked when satellite is on: " + satelliteModeRadios);
+
+                if (satelliteModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
+                    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+                    if (bluetoothAdapter != null) {
+                        mDisableBTOnSatelliteEnabled = true;
+                        mBTStateEnabled = bluetoothAdapter.isEnabled();
+                        radioStateIntentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+                    }
+                }
+
+                if (satelliteModeRadios.contains(Settings.Global.RADIO_NFC)) {
+                    Context applicationContext = mContext.getApplicationContext();
+                    NfcAdapter nfcAdapter = null;
+                    if (applicationContext != null) {
+                        nfcAdapter = NfcAdapter.getDefaultAdapter(mContext.getApplicationContext());
+                    }
+                    if (nfcAdapter != null) {
+                        mDisableNFCOnSatelliteEnabled = true;
+                        mNfcStateEnabled = nfcAdapter.isEnabled();
+                        radioStateIntentFilter.addAction(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
+                    }
+                }
+
+                if (satelliteModeRadios.contains(Settings.Global.RADIO_WIFI)) {
+                    WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
+                    if (wifiManager != null) {
+                        mDisableWifiOnSatelliteEnabled = true;
+                        mWifiStateEnabled = wifiManager.isWifiEnabled();
+                        radioStateIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+                    }
+                }
+                mContext.registerReceiver(bTWifiNFCSateReceiver, radioStateIntentFilter);
+
+                if (satelliteModeRadios.contains(Settings.Global.RADIO_UWB)) {
+                    UwbManager uwbManager = mContext.getSystemService(UwbManager.class);
+                    if (uwbManager != null) {
+                        mDisableUWBOnSatelliteEnabled = true;
+                        mUwbStateEnabled = uwbManager.isUwbEnabled();
+                        final long identity = Binder.clearCallingIdentity();
+                        try {
+                            uwbManager.registerAdapterStateCallback(mContext.getMainExecutor(),
+                                    uwbAdapterStateCallback);
+                        } finally {
+                            Binder.restoreCallingIdentity(identity);
+                        }
+                    }
+                }
+
+                logd("mDisableBTOnSatelliteEnabled: " + mDisableBTOnSatelliteEnabled
+                        + " mDisableNFCOnSatelliteEnabled: " + mDisableNFCOnSatelliteEnabled
+                        + " mDisableWifiOnSatelliteEnabled: " + mDisableWifiOnSatelliteEnabled
+                        + " mDisableUWBOnSatelliteEnabled: " + mDisableUWBOnSatelliteEnabled);
+
+                logd("mBTStateEnabled: " + mBTStateEnabled
+                        + " mNfcStateEnabled: " + mNfcStateEnabled
+                        + " mWifiStateEnabled: " + mWifiStateEnabled
+                        + " mUwbStateEnabled: " + mUwbStateEnabled);
+            }
+        }
+    }
+
+    protected class UwbAdapterStateCallback implements UwbManager.AdapterStateCallback {
+
+        public String toString(int state) {
+            switch (state) {
+                case UwbManager.AdapterStateCallback.STATE_DISABLED:
+                    return "Disabled";
+
+                case UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE:
+                    return "Inactive";
+
+                case UwbManager.AdapterStateCallback.STATE_ENABLED_ACTIVE:
+                    return "Active";
+
+                default:
+                    return "";
+            }
+        }
+
+        @Override
+        public void onStateChanged(int state, int reason) {
+            logd("UwbAdapterStateCallback#onStateChanged() called, state = " + toString(state));
+            logd("Adapter state changed reason " + String.valueOf(reason));
+            synchronized (mRadioStateLock) {
+                if (state == UwbManager.AdapterStateCallback.STATE_DISABLED) {
+                    mUwbStateEnabled = false;
+                    evaluateToSendSatelliteEnabledSuccess();
+                } else {
+                    mUwbStateEnabled = true;
+                }
+                logd("mUwbStateEnabled: " + mUwbStateEnabled);
+            }
+        }
+    }
+
+    protected class BTWifiNFCStateReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (action == null) {
+                logd("BTWifiNFCStateReceiver NULL action for intent " + intent);
+                return;
+            }
+
+            switch (action) {
+                case BluetoothAdapter.ACTION_STATE_CHANGED:
+                    int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                            BluetoothAdapter.ERROR);
+                    logd("Bluetooth state updated to " + btState);
+                    synchronized (mRadioStateLock) {
+                        if (btState == BluetoothAdapter.STATE_OFF) {
+                            mBTStateEnabled = false;
+                            evaluateToSendSatelliteEnabledSuccess();
+                        } else if (btState == BluetoothAdapter.STATE_ON) {
+                            mBTStateEnabled = true;
+                        }
+                        logd("mBTStateEnabled: " + mBTStateEnabled);
+                    }
+                    break;
+
+                case NfcAdapter.ACTION_ADAPTER_STATE_CHANGED:
+                    int nfcState = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, -1);
+                    logd("Nfc state updated to " + nfcState);
+                    synchronized (mRadioStateLock) {
+                        if (nfcState == NfcAdapter.STATE_ON) {
+                            mNfcStateEnabled = true;
+                        } else if (nfcState == NfcAdapter.STATE_OFF) {
+                            mNfcStateEnabled = false;
+                            evaluateToSendSatelliteEnabledSuccess();
+                        }
+                        logd("mNfcStateEnabled: " + mNfcStateEnabled);
+                    }
+                    break;
+
+                case WifiManager.WIFI_STATE_CHANGED_ACTION:
+                    int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                            WifiManager.WIFI_STATE_UNKNOWN);
+                    logd("Wifi state updated to " + wifiState);
+                    synchronized (mRadioStateLock) {
+                        if (wifiState == WifiManager.WIFI_STATE_ENABLED) {
+                            mWifiStateEnabled = true;
+                        } else if (wifiState == WifiManager.WIFI_STATE_DISABLED) {
+                            mWifiStateEnabled = false;
+                            evaluateToSendSatelliteEnabledSuccess();
+                        }
+                        logd("mWifiStateEnabled: " + mWifiStateEnabled);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private static final class SatelliteControllerHandlerRequest {
+        /** The argument to use for the request */
+        public @NonNull Object argument;
+        /** The caller needs to specify the phone to be used for the request */
+        public @NonNull Phone phone;
+        /** The result of the request that is run on the main thread */
+        public @Nullable Object result;
+
+        SatelliteControllerHandlerRequest(Object argument, Phone phone) {
+            this.argument = argument;
+            this.phone = phone;
+        }
+    }
+
+    private static final class RequestSatelliteEnabledArgument {
+        public boolean enableSatellite;
+        public boolean enableDemoMode;
+        @NonNull public Consumer<Integer> callback;
+
+        RequestSatelliteEnabledArgument(boolean enableSatellite, boolean enableDemoMode,
+                Consumer<Integer> callback) {
+            this.enableSatellite = enableSatellite;
+            this.enableDemoMode = enableDemoMode;
+            this.callback = callback;
+        }
+    }
+
+    private static final class ProvisionSatelliteServiceArgument {
+        @NonNull public String token;
+        @NonNull public byte[] provisionData;
+        @NonNull public Consumer<Integer> callback;
+        public int subId;
+
+        ProvisionSatelliteServiceArgument(String token, byte[] provisionData,
+                Consumer<Integer> callback, int subId) {
+            this.token = token;
+            this.provisionData = provisionData;
+            this.callback = callback;
+            this.subId = subId;
+        }
+    }
+
+    /**
+     * Arguments to send to SatelliteTransmissionUpdate registrants
+     */
+    public static final class SatelliteTransmissionUpdateArgument {
+        @NonNull public Consumer<Integer> errorCallback;
+        @NonNull public ISatelliteTransmissionUpdateCallback callback;
+        public int subId;
+
+        SatelliteTransmissionUpdateArgument(Consumer<Integer> errorCallback,
+                ISatelliteTransmissionUpdateCallback callback, int subId) {
+            this.errorCallback = errorCallback;
+            this.callback = callback;
+            this.subId = subId;
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        SatelliteControllerHandlerRequest request;
+        Message onCompleted;
+        AsyncResult ar;
+
+        switch(msg.what) {
+            case CMD_START_SATELLITE_TRANSMISSION_UPDATES: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted =
+                        obtainMessage(EVENT_START_SATELLITE_TRANSMISSION_UPDATES_DONE, request);
+                mPointingAppController.startSatelliteTransmissionUpdates(onCompleted,
+                        request.phone);
+                break;
+            }
+
+            case EVENT_START_SATELLITE_TRANSMISSION_UPDATES_DONE: {
+                handleStartSatelliteTransmissionUpdatesDone((AsyncResult) msg.obj);
+                break;
+            }
+
+            case CMD_STOP_SATELLITE_TRANSMISSION_UPDATES: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted =
+                        obtainMessage(EVENT_STOP_SATELLITE_TRANSMISSION_UPDATES_DONE, request);
+                mPointingAppController.stopSatelliteTransmissionUpdates(onCompleted, request.phone);
+                break;
+            }
+
+            case EVENT_STOP_SATELLITE_TRANSMISSION_UPDATES_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "stopSatelliteTransmissionUpdates");
+                ((Consumer<Integer>) request.argument).accept(error);
+                break;
+            }
+
+            case CMD_PROVISION_SATELLITE_SERVICE: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                ProvisionSatelliteServiceArgument argument =
+                        (ProvisionSatelliteServiceArgument) request.argument;
+                if (mSatelliteProvisionCallbacks.containsKey(argument.subId)) {
+                    argument.callback.accept(
+                            SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
+                    notifyRequester(request);
+                    break;
+                }
+                mSatelliteProvisionCallbacks.put(argument.subId, argument.callback);
+                onCompleted = obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
+                // Log the current time for provision triggered
+                mProvisionMetricsStats.setProvisioningStartTime();
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface.provisionSatelliteService(argument.token,
+                            argument.provisionData, onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.provisionSatelliteService(onCompleted, argument.token);
+                } else {
+                    loge("provisionSatelliteService: No phone object");
+                    argument.callback.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    notifyRequester(request);
+                    mProvisionMetricsStats
+                            .setResultCode(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE)
+                            .reportProvisionMetrics();
+                    mControllerMetricsStats.reportProvisionCount(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                }
+                break;
+            }
+
+            case EVENT_PROVISION_SATELLITE_SERVICE_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int errorCode =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "provisionSatelliteService");
+                handleEventProvisionSatelliteServiceDone(
+                        (ProvisionSatelliteServiceArgument) request.argument, errorCode);
+                notifyRequester(request);
+                break;
+            }
+
+            case CMD_DEPROVISION_SATELLITE_SERVICE: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                ProvisionSatelliteServiceArgument argument =
+                        (ProvisionSatelliteServiceArgument) request.argument;
+                onCompleted = obtainMessage(EVENT_DEPROVISION_SATELLITE_SERVICE_DONE, request);
+                if (argument.callback != null) {
+                    mProvisionMetricsStats.setProvisioningStartTime();
+                }
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface
+                            .deprovisionSatelliteService(argument.token, onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.deprovisionSatelliteService(onCompleted, argument.token);
+                } else {
+                    loge("deprovisionSatelliteService: No phone object");
+                    if (argument.callback != null) {
+                        argument.callback.accept(
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                        mProvisionMetricsStats
+                                .setResultCode(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE)
+                                .reportProvisionMetrics();
+                        mControllerMetricsStats.reportDeprovisionCount(
+                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+                    }
+                }
+                break;
+            }
+
+            case EVENT_DEPROVISION_SATELLITE_SERVICE_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int errorCode =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "deprovisionSatelliteService");
+                handleEventDeprovisionSatelliteServiceDone(
+                        (ProvisionSatelliteServiceArgument) request.argument, errorCode);
+                break;
+            }
+
+            case CMD_SET_SATELLITE_ENABLED: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                handleSatelliteEnabled(request);
+                break;
+            }
+
+            case EVENT_SET_SATELLITE_ENABLED_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                RequestSatelliteEnabledArgument argument =
+                        (RequestSatelliteEnabledArgument) request.argument;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar, "setSatelliteEnabled");
+                logd("EVENT_SET_SATELLITE_ENABLED_DONE = " + error);
+
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (argument.enableSatellite) {
+                        synchronized (mSatelliteEnabledRequestLock) {
+                            mWaitingForRadioDisabled = true;
+                        }
+                        setSettingsKeyForSatelliteMode(SATELLITE_MODE_ENABLED_TRUE);
+
+                        /**
+                         * TODO for NTN-based satellites: Check if satellite is acquired.
+                         */
+                        if (mNeedsSatellitePointing) {
+                            mPointingAppController.startPointingUI(false);
+                        }
+                        evaluateToSendSatelliteEnabledSuccess();
+                    } else {
+                        synchronized (mSatelliteEnabledRequestLock) {
+                            if (mSatelliteEnabledRequest != null &&
+                                    mSatelliteEnabledRequest.enableSatellite == true &&
+                                    argument.enableSatellite == false && mWaitingForRadioDisabled) {
+                                // Previous mSatelliteEnabledRequest is successful but waiting for
+                                // all radios to be turned off.
+                                mSatelliteEnabledRequest.callback.accept(
+                                        SatelliteManager.SATELLITE_ERROR_NONE);
+                            }
+                        }
+                        resetSatelliteEnabledRequest();
+
+                        setSettingsKeyForSatelliteMode(SATELLITE_MODE_ENABLED_FALSE);
+                        setDemoModeEnabled(argument.enableDemoMode);
+                        synchronized (mIsSatelliteEnabledLock) {
+                            mIsSatelliteEnabled = argument.enableSatellite;
+                        }
+                        // If satellite is disabled, send success to callback immediately
+                        argument.callback.accept(error);
+                        updateSatelliteEnabledState(
+                                argument.enableSatellite, "EVENT_SET_SATELLITE_ENABLED_DONE");
+                    }
+                } else {
+                    synchronized (mSatelliteEnabledRequestLock) {
+                        if (mSatelliteEnabledRequest != null &&
+                                mSatelliteEnabledRequest.enableSatellite == true &&
+                                argument.enableSatellite == false && mWaitingForRadioDisabled) {
+                            // Previous mSatelliteEnabledRequest is successful but waiting for
+                            // all radios to be turned off.
+                            mSatelliteEnabledRequest.callback.accept(
+                                    SatelliteManager.SATELLITE_ERROR_NONE);
+                        }
+                    }
+                    resetSatelliteEnabledRequest();
+
+                    // If Satellite enable/disable request returned Error, no need to wait for radio
+                    argument.callback.accept(error);
+                }
+
+                if (argument.enableSatellite) {
+                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                        mControllerMetricsStats.onSatelliteEnabled();
+                        mControllerMetricsStats.reportServiceEnablementSuccessCount();
+                    } else {
+                        mControllerMetricsStats.reportServiceEnablementFailCount();
+                    }
+                    SessionMetricsStats.getInstance()
+                            .setInitializationResult(error)
+                            .setRadioTechnology(SatelliteManager.NT_RADIO_TECHNOLOGY_PROPRIETARY)
+                            .reportSessionMetrics();
+                } else {
+                    mControllerMetricsStats.onSatelliteDisabled();
+                }
+                break;
+            }
+
+            case CMD_IS_SATELLITE_ENABLED: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted = obtainMessage(EVENT_IS_SATELLITE_ENABLED_DONE, request);
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface.requestIsSatelliteEnabled(onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.isSatellitePowerOn(onCompleted);
+                } else {
+                    loge("isSatelliteEnabled: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_IS_SATELLITE_ENABLED_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "isSatelliteEnabled");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("isSatelliteEnabled: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        boolean enabled = ((int[]) ar.result)[0] == 1;
+                        if (DBG) logd("isSatelliteEnabled: " + enabled);
+                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_ENABLED, enabled);
+                        updateSatelliteEnabledState(enabled, "EVENT_IS_SATELLITE_ENABLED_DONE");
+                    }
+                } else if (error == SatelliteManager.SATELLITE_REQUEST_NOT_SUPPORTED) {
+                    updateSatelliteSupportedStateWhenSatelliteServiceConnected(false);
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case CMD_IS_SATELLITE_SUPPORTED: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted = obtainMessage(EVENT_IS_SATELLITE_SUPPORTED_DONE, request);
+
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface.requestIsSatelliteSupported(onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.isSatelliteSupported(onCompleted);
+                } else {
+                    loge("isSatelliteSupported: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_IS_SATELLITE_SUPPORTED_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar, "isSatelliteSupported");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("isSatelliteSupported: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        boolean supported = (boolean) ar.result;
+                        if (DBG) logd("isSatelliteSupported: " + supported);
+                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, supported);
+                        updateSatelliteSupportedStateWhenSatelliteServiceConnected(supported);
+                    }
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case CMD_GET_SATELLITE_CAPABILITIES: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted = obtainMessage(EVENT_GET_SATELLITE_CAPABILITIES_DONE, request);
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface.requestSatelliteCapabilities(onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.getSatelliteCapabilities(onCompleted);
+                } else {
+                    loge("getSatelliteCapabilities: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_GET_SATELLITE_CAPABILITIES_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "getSatelliteCapabilities");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("getSatelliteCapabilities: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        SatelliteCapabilities capabilities = (SatelliteCapabilities) ar.result;
+                        synchronized (mNeedsSatellitePointingLock) {
+                            mNeedsSatellitePointing = capabilities.isPointingRequired();
+                        }
+                        if (DBG) logd("getSatelliteCapabilities: " + capabilities);
+                        bundle.putParcelable(SatelliteManager.KEY_SATELLITE_CAPABILITIES,
+                                capabilities);
+                        synchronized (mSatelliteCapabilitiesLock) {
+                            mSatelliteCapabilities = capabilities;
+                        }
+                    }
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case CMD_IS_SATELLITE_COMMUNICATION_ALLOWED: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted =
+                        obtainMessage(EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE, request);
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface
+                            .requestIsSatelliteCommunicationAllowedForCurrentLocation(
+                                    onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.isSatelliteCommunicationAllowedForCurrentLocation(onCompleted);
+                } else {
+                    loge("isSatelliteCommunicationAllowedForCurrentLocation: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "isSatelliteCommunicationAllowedForCurrentLocation");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("isSatelliteCommunicationAllowedForCurrentLocation: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        boolean communicationAllowed = (boolean) ar.result;
+                        if (DBG) {
+                            logd("isSatelliteCommunicationAllowedForCurrentLocation: "
+                                    + communicationAllowed);
+                        }
+                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                                communicationAllowed);
+                    }
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case CMD_GET_TIME_SATELLITE_NEXT_VISIBLE: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted = obtainMessage(EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE,
+                        request);
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface
+                            .requestTimeForNextSatelliteVisibility(onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.requestTimeForNextSatelliteVisibility(onCompleted);
+                } else {
+                    loge("requestTimeForNextSatelliteVisibility: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error = SatelliteServiceUtils.getSatelliteError(ar,
+                        "requestTimeForNextSatelliteVisibility");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("requestTimeForNextSatelliteVisibility: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        int nextVisibilityDuration = ((int[]) ar.result)[0];
+                        if (DBG) {
+                            logd("requestTimeForNextSatelliteVisibility: " +
+                                    nextVisibilityDuration);
+                        }
+                        bundle.putInt(SatelliteManager.KEY_SATELLITE_NEXT_VISIBILITY,
+                                nextVisibilityDuration);
+                    }
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case EVENT_RADIO_STATE_CHANGED: {
+                if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF
+                        || mCi.getRadioState() == TelephonyManager.RADIO_POWER_UNAVAILABLE) {
+                    mIsRadioOn = false;
+                    logd("Radio State Changed to " + mCi.getRadioState());
+                    IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                        @Override
+                        public void accept(int result) {
+                            logd("RequestSatelliteEnabled: result=" + result);
+                        }
+                    };
+                    Phone phone = SatelliteServiceUtils.getPhone();
+                    Consumer<Integer> result = FunctionalUtils
+                            .ignoreRemoteException(errorCallback::accept);
+                    RequestSatelliteEnabledArgument message =
+                            new RequestSatelliteEnabledArgument(false, false, result);
+                    request = new SatelliteControllerHandlerRequest(message, phone);
+                    handleSatelliteEnabled(request);
+                } else {
+                    mIsRadioOn = true;
+                    if (!mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                        synchronized (mIsSatelliteSupportedLock) {
+                            if (mIsSatelliteSupported == null) {
+                                ResultReceiver receiver = new ResultReceiver(this) {
+                                    @Override
+                                    protected void onReceiveResult(
+                                            int resultCode, Bundle resultData) {
+                                        logd("requestIsSatelliteSupported: resultCode="
+                                                + resultCode);
+                                    }
+                                };
+                                requestIsSatelliteSupported(
+                                        SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, receiver);
+                            }
+                        }
+                    } else {
+                        logd("EVENT_RADIO_STATE_CHANGED: Satellite vendor service is supported."
+                                + " Ignored the event");
+                    }
+                }
+                break;
+            }
+
+            case CMD_IS_SATELLITE_PROVISIONED: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                onCompleted = obtainMessage(EVENT_IS_SATELLITE_PROVISIONED_DONE, request);
+                if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+                    mSatelliteModemInterface.requestIsSatelliteProvisioned(onCompleted);
+                    break;
+                }
+                Phone phone = request.phone;
+                if (phone != null) {
+                    phone.isSatelliteProvisioned(onCompleted);
+                } else {
+                    loge("isSatelliteProvisioned: No phone object");
+                    ((ResultReceiver) request.argument).send(
+                            SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+                }
+                break;
+            }
+
+            case EVENT_IS_SATELLITE_PROVISIONED_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                int error =  SatelliteServiceUtils.getSatelliteError(ar,
+                        "isSatelliteProvisioned");
+                Bundle bundle = new Bundle();
+                if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
+                    if (ar.result == null) {
+                        loge("isSatelliteProvisioned: result is null");
+                        error = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+                    } else {
+                        boolean provisioned = ((int[]) ar.result)[0] == 1;
+                        if (DBG) logd("isSatelliteProvisioned: " + provisioned);
+                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED, provisioned);
+                        synchronized (mIsSatelliteProvisionedLock) {
+                            mIsSatelliteProvisioned = provisioned;
+                        }
+                    }
+                }
+                ((ResultReceiver) request.argument).send(error, bundle);
+                break;
+            }
+
+            case EVENT_SATELLITE_PROVISION_STATE_CHANGED:
+                ar = (AsyncResult) msg.obj;
+                if (ar.result == null) {
+                    loge("EVENT_SATELLITE_PROVISION_STATE_CHANGED: result is null");
+                } else {
+                    handleEventSatelliteProvisionStateChanged((boolean) ar.result);
+                }
+                break;
+
+            case EVENT_PENDING_DATAGRAMS:
+                logd("Received EVENT_PENDING_DATAGRAMS");
+                IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        logd("pollPendingSatelliteDatagram result: " + result);
+                    }
+                };
+                pollPendingSatelliteDatagrams(
+                        SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, internalCallback);
+                break;
+
+            case EVENT_SATELLITE_MODEM_STATE_CHANGED:
+                ar = (AsyncResult) msg.obj;
+                if (ar.result == null) {
+                    loge("EVENT_SATELLITE_MODEM_STATE_CHANGED: result is null");
+                } else {
+                    handleEventSatelliteModemStateChanged((int) ar.result);
+                }
+                break;
+
+            default:
+                Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
+                        msg.what);
+                break;
+        }
+    }
+
+    private void notifyRequester(SatelliteControllerHandlerRequest request) {
+        synchronized (request) {
+            request.notifyAll();
+        }
+    }
+
+    /**
+     * Request to enable or disable the satellite modem and demo mode. If the satellite modem is
+     * enabled, this will also disable the cellular modem, and if the satellite modem is disabled,
+     * this will also re-enable the cellular modem.
+     *
+     * @param subId The subId of the subscription to set satellite enabled for.
+     * @param enableSatellite {@code true} to enable the satellite modem and
+     *                        {@code false} to disable.
+     * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
+     * @param callback The callback to get the error code of the request.
+     */
+    public void requestSatelliteEnabled(int subId, boolean enableSatellite, boolean enableDemoMode,
+            @NonNull IIntegerConsumer callback) {
+        logd("requestSatelliteEnabled subId: " + subId + " enableSatellite: " + enableSatellite
+                + " enableDemoMode: " + enableDemoMode);
+
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+            return;
+        }
+
+        if (enableSatellite) {
+            if (!mIsRadioOn) {
+                loge("Radio is not on, can not enable satellite");
+                result.accept(SatelliteManager.SATELLITE_INVALID_MODEM_STATE);
+                return;
+            }
+        } else {
+            /* if disable satellite, always assume demo is also disabled */
+            enableDemoMode = false;
+        }
+
+        synchronized (mIsSatelliteEnabledLock) {
+            if (mIsSatelliteEnabled != null) {
+                if (mIsSatelliteEnabled == enableSatellite) {
+                    if (enableDemoMode != mIsDemoModeEnabled) {
+                        loge("Received invalid demo mode while satellite session is enabled"
+                                + " enableDemoMode = " + enableDemoMode);
+                        result.accept(SatelliteManager.SATELLITE_INVALID_ARGUMENTS);
+                        return;
+                    } else {
+                        logd("Enable request matches with current state"
+                                + " enableSatellite = " + enableSatellite);
+                        result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+                        return;
+                    }
+                }
+            }
+        }
+
+        RequestSatelliteEnabledArgument request =
+                new RequestSatelliteEnabledArgument(enableSatellite, enableDemoMode, result);
+        /**
+         * Multiple satellite enabled requests are handled as below:
+         * 1. If there are no ongoing requests, store current request in mSatelliteEnabledRequest
+         * 2. If there is a ongoing request, then:
+         *      1. ongoing request = enable, current request = enable: return IN_PROGRESS error
+         *      2. ongoing request = disable, current request = disable: return IN_PROGRESS error
+         *      3. ongoing request = disable, current request = enable: return SATELLITE_ERROR error
+         *      4. ongoing request = enable, current request = disable: send request to modem
+         */
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (mSatelliteEnabledRequest == null) {
+                mSatelliteEnabledRequest = request;
+            } else if (mSatelliteEnabledRequest.enableSatellite == request.enableSatellite) {
+                logd("requestSatelliteEnabled  enableSatellite: " + enableSatellite
+                        + " is already in progress.");
+                result.accept(SatelliteManager.SATELLITE_REQUEST_IN_PROGRESS);
+                return;
+            } else if (mSatelliteEnabledRequest.enableSatellite == false
+                    && request.enableSatellite == true) {
+                logd("requestSatelliteEnabled  enableSatellite: " + enableSatellite + " cannot be "
+                        + "processed. Disable satellite is already in progress.");
+                result.accept(SatelliteManager.SATELLITE_ERROR);
+                return;
+            }
+        }
+
+        sendRequestAsync(CMD_SET_SATELLITE_ENABLED, request, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Request to get whether the satellite modem is enabled.
+     *
+     * @param subId The subId of the subscription to check whether satellite is enabled for.
+     * @param result The result receiver that returns whether the satellite modem is enabled
+     *               if the request is successful or an error code if the request failed.
+     */
+    public void requestIsSatelliteEnabled(int subId, @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        synchronized (mIsSatelliteEnabledLock) {
+            if (mIsSatelliteEnabled != null) {
+                /* We have already successfully queried the satellite modem. */
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_ENABLED, mIsSatelliteEnabled);
+                result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+                return;
+            }
+        }
+
+        sendRequestAsync(CMD_IS_SATELLITE_ENABLED, result, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Get whether the satellite modem is enabled.
+     * This will return the cached value instead of querying the satellite modem.
+     *
+     * @return {@code true} if the satellite modem is enabled and {@code false} otherwise.
+     */
+    public boolean isSatelliteEnabled() {
+        if (mIsSatelliteEnabled == null) return false;
+        return mIsSatelliteEnabled;
+    }
+
+    /**
+     * Request to get whether the satellite service demo mode is enabled.
+     *
+     * @param subId The subId of the subscription to check whether the satellite demo mode
+     *              is enabled for.
+     * @param result The result receiver that returns whether the satellite demo mode is enabled
+     *               if the request is successful or an error code if the request failed.
+     */
+    public void requestIsDemoModeEnabled(int subId, @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+            return;
+        }
+
+        final Bundle bundle = new Bundle();
+        bundle.putBoolean(SatelliteManager.KEY_DEMO_MODE_ENABLED, mIsDemoModeEnabled);
+        result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+    }
+
+    /**
+     * Get whether the satellite service demo mode is enabled.
+     *
+     * @return {@code true} if the satellite demo mode is enabled and {@code false} otherwise.
+     */
+    public boolean isDemoModeEnabled() {
+        return mIsDemoModeEnabled;
+    }
+
+    /**
+     * Request to get whether the satellite service is supported on the device.
+     *
+     * @param subId The subId of the subscription to check satellite service support for.
+     * @param result The result receiver that returns whether the satellite service is supported on
+     *               the device if the request is successful or an error code if the request failed.
+     */
+    public void requestIsSatelliteSupported(int subId, @NonNull ResultReceiver result) {
+        synchronized (mIsSatelliteSupportedLock) {
+            if (mIsSatelliteSupported != null) {
+                /* We have already successfully queried the satellite modem. */
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, mIsSatelliteSupported);
+                result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+                return;
+            }
+        }
+
+        sendRequestAsync(CMD_IS_SATELLITE_SUPPORTED, result, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Request to get the {@link SatelliteCapabilities} of the satellite service.
+     *
+     * @param subId The subId of the subscription to get the satellite capabilities for.
+     * @param result The result receiver that returns the {@link SatelliteCapabilities}
+     *               if the request is successful or an error code if the request failed.
+     */
+    public void requestSatelliteCapabilities(int subId, @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        synchronized (mSatelliteCapabilitiesLock) {
+            if (mSatelliteCapabilities != null) {
+                Bundle bundle = new Bundle();
+                bundle.putParcelable(SatelliteManager.KEY_SATELLITE_CAPABILITIES,
+                        mSatelliteCapabilities);
+                result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+                return;
+            }
+        }
+
+        sendRequestAsync(CMD_GET_SATELLITE_CAPABILITIES, result, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Start receiving satellite transmission updates.
+     * This can be called by the pointing UI when the user starts pointing to the satellite.
+     * Modem should continue to report the pointing input as the device or satellite moves.
+     *
+     * @param subId The subId of the subscription to start satellite transmission updates for.
+     * @param errorCallback The callback to get the error code of the request.
+     * @param callback The callback to notify of satellite transmission updates.
+     */
+    public void startSatelliteTransmissionUpdates(int subId,
+            @NonNull IIntegerConsumer errorCallback,
+            @NonNull ISatelliteTransmissionUpdateCallback callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+            return;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        mPointingAppController.registerForSatelliteTransmissionUpdates(validSubId, callback, phone);
+        sendRequestAsync(CMD_START_SATELLITE_TRANSMISSION_UPDATES,
+                new SatelliteTransmissionUpdateArgument(result, callback, validSubId), phone);
+    }
+
+    /**
+     * Stop receiving satellite transmission updates.
+     * This can be called by the pointing UI when the user stops pointing to the satellite.
+     *
+     * @param subId The subId of the subscription to stop satellite transmission updates for.
+     * @param errorCallback The callback to get the error code of the request.
+     * @param callback The callback that was passed to {@link #startSatelliteTransmissionUpdates(
+     *                 int, IIntegerConsumer, ISatelliteTransmissionUpdateCallback)}.
+     */
+    public void stopSatelliteTransmissionUpdates(int subId, @NonNull IIntegerConsumer errorCallback,
+            @NonNull ISatelliteTransmissionUpdateCallback callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+            return;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        mPointingAppController.unregisterForSatelliteTransmissionUpdates(
+                validSubId, result, callback, phone);
+
+        // Even if handler is null - which means there are no listeners, the modem command to stop
+        // satellite transmission updates might have failed. The callers might want to retry
+        // sending the command. Thus, we always need to send this command to the modem.
+        sendRequestAsync(CMD_STOP_SATELLITE_TRANSMISSION_UPDATES, result, phone);
+    }
+
+    /**
+     * Register the subscription with a satellite provider.
+     * This is needed to register the subscription if the provider allows dynamic registration.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param token The token to be used as a unique identifier for provisioning with satellite
+     *              gateway.
+     * @param provisionData Data from the provisioning app that can be used by provisioning server
+     * @param callback The callback to get the error code of the request.
+     *
+     * @return The signal transport used by the caller to cancel the provision request,
+     *         or {@code null} if the request failed.
+     */
+    @Nullable public ICancellationSignal provisionSatelliteService(int subId,
+            @NonNull String token, @NonNull byte[] provisionData,
+            @NonNull IIntegerConsumer callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return null;
+        }
+        if (!satelliteSupported) {
+            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+            return null;
+        }
+
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        if (mSatelliteProvisionCallbacks.containsKey(validSubId)) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
+            return null;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned != null && satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+            return null;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        sendRequestAsync(CMD_PROVISION_SATELLITE_SERVICE,
+                new ProvisionSatelliteServiceArgument(token, provisionData, result, validSubId),
+                phone);
+
+        ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+        CancellationSignal.fromTransport(cancelTransport).setOnCancelListener(() -> {
+            sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
+                    new ProvisionSatelliteServiceArgument(token, provisionData, null,
+                            validSubId), phone);
+            mProvisionMetricsStats.setIsCanceled(true);
+        });
+        return cancelTransport;
+    }
+
+    /**
+     * Unregister the device/subscription with the satellite provider.
+     * This is needed if the provider allows dynamic registration. Once deprovisioned,
+     * {@link android.telephony.satellite.SatelliteProvisionStateCallback
+     * #onSatelliteProvisionStateChanged(boolean)}
+     * should report as deprovisioned.
+     *
+     * @param subId The subId of the subscription to be deprovisioned.
+     * @param token The token of the device/subscription to be deprovisioned.
+     * @param callback The callback to get the error code of the request.
+     */
+    public void deprovisionSatelliteService(int subId,
+            @NonNull String token, @NonNull IIntegerConsumer callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+            return;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
+                new ProvisionSatelliteServiceArgument(token, null, result, validSubId),
+                phone);
+    }
+
+    /**
+     * Registers for the satellite provision state changed.
+     *
+     * @param subId The subId of the subscription to register for provision state changed.
+     * @param callback The callback to handle the satellite provision state changed event.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+     */
+    @SatelliteManager.SatelliteError public int registerForSatelliteProvisionStateChanged(int subId,
+            @NonNull ISatelliteProvisionStateCallback callback) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+        }
+        if (!satelliteSupported) {
+            return SatelliteManager.SATELLITE_NOT_SUPPORTED;
+        }
+
+        mSatelliteProvisionStateChangedListeners.put(callback.asBinder(), callback);
+        return SatelliteManager.SATELLITE_ERROR_NONE;
+    }
+
+    /**
+     * Unregisters for the satellite provision state changed.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for provision state changed.
+     * @param callback The callback that was passed to
+     * {@link #registerForSatelliteProvisionStateChanged(int, ISatelliteProvisionStateCallback)}.
+     */
+    public void unregisterForSatelliteProvisionStateChanged(
+            int subId, @NonNull ISatelliteProvisionStateCallback callback) {
+        mSatelliteProvisionStateChangedListeners.remove(callback.asBinder());
+    }
+
+    /**
+     * Request to get whether the device is provisioned with a satellite provider.
+     *
+     * @param subId The subId of the subscription to get whether the device is provisioned for.
+     * @param result The result receiver that returns whether the device is provisioned with a
+     *               satellite provider if the request is successful or an error code if the
+     *               request failed.
+     */
+    public void requestIsSatelliteProvisioned(int subId, @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        synchronized (mIsSatelliteProvisionedLock) {
+            if (mIsSatelliteProvisioned != null) {
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
+                        mIsSatelliteProvisioned);
+                result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+                return;
+            }
+        }
+
+        sendRequestAsync(CMD_IS_SATELLITE_PROVISIONED, result, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Registers for modem state changed from satellite modem.
+     *
+     * @param subId The subId of the subscription to register for satellite modem state changed.
+     * @param callback The callback to handle the satellite modem state changed event.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+     */
+    @SatelliteManager.SatelliteError public int registerForSatelliteModemStateChanged(int subId,
+            @NonNull ISatelliteStateCallback callback) {
+        if (mSatelliteSessionController != null) {
+            mSatelliteSessionController.registerForSatelliteModemStateChanged(callback);
+        } else {
+            loge("registerForSatelliteModemStateChanged: mSatelliteSessionController"
+                    + " is not initialized yet");
+            return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+        }
+        return SatelliteManager.SATELLITE_ERROR_NONE;
+    }
+
+    /**
+     * Unregisters for modem state changed from satellite modem.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for satellite modem state changed.
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteModemStateChanged(int, ISatelliteStateCallback)}.
+     */
+    public void unregisterForSatelliteModemStateChanged(int subId,
+            @NonNull ISatelliteStateCallback callback) {
+        if (mSatelliteSessionController != null) {
+            mSatelliteSessionController.unregisterForSatelliteModemStateChanged(callback);
+        } else {
+            loge("registerForSatelliteModemStateChanged: mSatelliteSessionController"
+                    + " is not initialized yet");
+        }
+    }
+
+    /**
+     * Register to receive incoming datagrams over satellite.
+     *
+     * @param subId The subId of the subscription to register for incoming satellite datagrams.
+     * @param callback The callback to handle incoming datagrams over satellite.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
+     */
+    @SatelliteManager.SatelliteError public int registerForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        return mDatagramController.registerForSatelliteDatagram(subId, callback);
+    }
+
+    /**
+     * Unregister to stop receiving incoming datagrams over satellite.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteDatagram(int, ISatelliteDatagramCallback)}.
+     */
+    public void unregisterForSatelliteDatagram(int subId,
+            @NonNull ISatelliteDatagramCallback callback) {
+        mDatagramController.unregisterForSatelliteDatagram(subId, callback);
+    }
+
+    /**
+     * Poll pending satellite datagrams over satellite.
+     *
+     * This method requests modem to check if there are any pending datagrams to be received over
+     * satellite. If there are any incoming datagrams, they will be received via
+     * {@link android.telephony.satellite.SatelliteDatagramCallback#onSatelliteDatagramReceived(
+     * long, SatelliteDatagram, int, Consumer)}
+     *
+     * @param subId The subId of the subscription used for receiving datagrams.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void pollPendingSatelliteDatagrams(int subId, @NonNull IIntegerConsumer callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+            return;
+        }
+
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        mDatagramController.pollPendingSatelliteDatagrams(validSubId, result);
+    }
+
+    /**
+     * Send datagram over satellite.
+     *
+     * Gateway encodes SOS message or location sharing message into a datagram and passes it as
+     * input to this method. Datagram received here will be passed down to modem without any
+     * encoding or encryption.
+     *
+     * @param subId The subId of the subscription to send satellite datagrams for.
+     * @param datagramType datagram type indicating whether the datagram is of type
+     *                     SOS_SMS or LOCATION_SHARING.
+     * @param datagram encoded gateway datagram which is encrypted by the caller.
+     *                 Datagram will be passed down to modem without any encoding or encryption.
+     * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+     *                                 full screen mode.
+     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
+     */
+    public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
+            SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+            @NonNull IIntegerConsumer callback) {
+        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
+            return;
+        }
+
+        /**
+         * TODO for NTN-based satellites: Check if satellite is acquired.
+         */
+        if (mNeedsSatellitePointing) {
+            mPointingAppController.startPointingUI(needFullScreenPointingUI);
+        }
+
+        final int validSubId = SatelliteServiceUtils.getValidSatelliteSubId(subId, mContext);
+        mDatagramController.sendSatelliteDatagram(validSubId, datagramType, datagram,
+                needFullScreenPointingUI, result);
+    }
+
+    /**
+     * Request to get whether satellite communication is allowed for the current location.
+     *
+     * @param subId The subId of the subscription to check whether satellite communication is
+     *              allowed for the current location for.
+     * @param result The result receiver that returns whether satellite communication is allowed
+     *               for the current location if the request is successful or an error code
+     *               if the request failed.
+     */
+    public void requestIsSatelliteCommunicationAllowedForCurrentLocation(int subId,
+            @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        sendRequestAsync(
+                CMD_IS_SATELLITE_COMMUNICATION_ALLOWED, result, SatelliteServiceUtils.getPhone());
+    }
+
+    /**
+     * Request to get the time after which the satellite will be visible.
+     *
+     * @param subId The subId to get the time after which the satellite will be visible for.
+     * @param result The result receiver that returns the time after which the satellite will
+     *               be visible if the request is successful or an error code if the request failed.
+     */
+    public void requestTimeForNextSatelliteVisibility(int subId, @NonNull ResultReceiver result) {
+        Boolean satelliteSupported = isSatelliteSupportedInternal();
+        if (satelliteSupported == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteSupported) {
+            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
+            return;
+        }
+
+        Boolean satelliteProvisioned = isSatelliteProvisioned();
+        if (satelliteProvisioned == null) {
+            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
+            return;
+        }
+        if (!satelliteProvisioned) {
+            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
+            return;
+        }
+
+        Phone phone = SatelliteServiceUtils.getPhone();
+        sendRequestAsync(CMD_GET_TIME_SATELLITE_NEXT_VISIBLE, result, phone);
+    }
+
+    /**
+     * Inform whether the device is aligned with satellite for demo mode.
+     *
+     * @param subId The subId of the subscription.
+     * @param isAligned {@true} means device is aligned with the satellite, otherwise {@false}.
+     */
+    public void onDeviceAlignedWithSatellite(@NonNull int subId, @NonNull boolean isAligned) {
+        mDatagramController.onDeviceAlignedWithSatellite(isAligned);
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite vendor service package name.
+     *
+     * @param servicePackageName The package name of the satellite vendor service.
+     * @return {@code true} if the satellite vendor service is set successfully,
+     * {@code false} otherwise.
+     */
+    public boolean setSatelliteServicePackageName(@Nullable String servicePackageName) {
+        boolean result = mSatelliteModemInterface.setSatelliteServicePackageName(
+                servicePackageName);
+        if (result) {
+            logd("setSatelliteServicePackageName: Resetting cached states");
+
+            // Cached states need to be cleared whenever switching satellite vendor services.
+            synchronized (mIsSatelliteSupportedLock) {
+                mIsSatelliteSupported = null;
+            }
+            synchronized (mIsSatelliteProvisionedLock) {
+                mIsSatelliteProvisioned = null;
+            }
+            synchronized (mIsSatelliteEnabledLock) {
+                mIsSatelliteEnabled = null;
+            }
+            synchronized (mSatelliteCapabilitiesLock) {
+                mSatelliteCapabilities = null;
+            }
+            ResultReceiver receiver = new ResultReceiver(this) {
+                @Override
+                protected void onReceiveResult(int resultCode, Bundle resultData) {
+                    logd("requestIsSatelliteSupported: resultCode=" + resultCode);
+                }
+            };
+            requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, receiver);
+        }
+        return result;
+    }
+
+    /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds that
+     * satellite should stay at listening mode to wait for the next incoming page before disabling
+     * listening mode.
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    public boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
+        if (mSatelliteSessionController == null) {
+            loge("mSatelliteSessionController is not initialized yet");
+            return false;
+        }
+        return mSatelliteSessionController.setSatelliteListeningTimeoutDuration(timeoutMillis);
+    }
+
+    /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds whether
+     * the device is aligned with the satellite for demo mode
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    public boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis) {
+        return mDatagramController.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite gateway service package name.
+     *
+     * @param servicePackageName The package name of the satellite gateway service.
+     * @return {@code true} if the satellite gateway service is set successfully,
+     * {@code false} otherwise.
+     */
+    public boolean setSatelliteGatewayServicePackageName(@Nullable String servicePackageName) {
+        if (mSatelliteSessionController == null) {
+            loge("mSatelliteSessionController is not initialized yet");
+            return false;
+        }
+        return mSatelliteSessionController.setSatelliteGatewayServicePackageName(
+                servicePackageName);
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite pointing UI app package and class names.
+     *
+     * @param packageName The package name of the satellite pointing UI app.
+     * @param className The class name of the satellite pointing UI app.
+     * @return {@code true} if the satellite pointing UI app package and class is set successfully,
+     * {@code false} otherwise.
+     */
+    public boolean setSatellitePointingUiClassName(
+            @Nullable String packageName, @Nullable String className) {
+        return mPointingAppController.setSatellitePointingUiClassName(packageName, className);
+    }
+
+    /**
+     * This function is used by {@link SatelliteModemInterface} to notify
+     * {@link SatelliteController} that the satellite vendor service was just connected.
+     * <p>
+     * {@link SatelliteController} will send requests to satellite modem to check whether it support
+     * satellite and whether it is provisioned. {@link SatelliteController} will use these cached
+     * values to serve requests from its clients.
+     * <p>
+     * Because satellite vendor service might have just come back from a crash, we need to disable
+     * the satellite modem so that resources will be cleaned up and internal states will be reset.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void onSatelliteServiceConnected() {
+        if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+            synchronized (mIsSatelliteSupportedLock) {
+                if (mIsSatelliteSupported == null) {
+                    ResultReceiver receiver = new ResultReceiver(this) {
+                        @Override
+                        protected void onReceiveResult(
+                                int resultCode, Bundle resultData) {
+                            logd("requestIsSatelliteSupported: resultCode="
+                                    + resultCode);
+                        }
+                    };
+                    requestIsSatelliteSupported(
+                            SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, receiver);
+                }
+            }
+        } else {
+            logd("onSatelliteServiceConnected: Satellite vendor service is not supported."
+                    + " Ignored the event");
+        }
+    }
+
+    /**
+     * @return {@code true} is satellite is supported on the device, {@code  false} otherwise.
+     */
+    public boolean isSatelliteSupported() {
+        Boolean supported = isSatelliteSupportedInternal();
+        return (supported != null ? supported : false);
+    }
+
+    /**
+     * If we have not successfully queried the satellite modem for its satellite service support,
+     * we will retry the query one more time. Otherwise, we will return the cached result.
+     */
+    private Boolean isSatelliteSupportedInternal() {
+        synchronized (mIsSatelliteSupportedLock) {
+            if (mIsSatelliteSupported != null) {
+                /* We have already successfully queried the satellite modem. */
+                return mIsSatelliteSupported;
+            }
+        }
+        /**
+         * We have not successfully checked whether the modem supports satellite service.
+         * Thus, we need to retry it now.
+         */
+        requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                new ResultReceiver(this) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        logd("requestIsSatelliteSupported: resultCode=" + resultCode);
+                    }
+                });
+        return null;
+    }
+
+    private void handleEventProvisionSatelliteServiceDone(
+            @NonNull ProvisionSatelliteServiceArgument arg,
+            @SatelliteManager.SatelliteError int result) {
+        logd("handleEventProvisionSatelliteServiceDone: result="
+                + result + ", subId=" + arg.subId);
+
+        Consumer<Integer> callback = mSatelliteProvisionCallbacks.remove(arg.subId);
+        if (callback == null) {
+            loge("handleEventProvisionSatelliteServiceDone: callback is null for subId="
+                    + arg.subId);
+            mProvisionMetricsStats
+                    .setResultCode(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE)
+                    .setIsProvisionRequest(true)
+                    .reportProvisionMetrics();
+            mControllerMetricsStats.reportProvisionCount(
+                    SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+            return;
+        }
+        callback.accept(result);
+    }
+
+    private void handleEventDeprovisionSatelliteServiceDone(
+            @NonNull ProvisionSatelliteServiceArgument arg,
+            @SatelliteManager.SatelliteError int result) {
+        if (arg == null) {
+            loge("handleEventDeprovisionSatelliteServiceDone: arg is null");
+            return;
+        }
+        logd("handleEventDeprovisionSatelliteServiceDone: result="
+                + result + ", subId=" + arg.subId);
+
+        if (arg.callback != null) {
+            arg.callback.accept(result);
+            mProvisionMetricsStats.setResultCode(result)
+                    .setIsProvisionRequest(false)
+                    .reportProvisionMetrics();
+            mControllerMetricsStats.reportDeprovisionCount(result);
+        }
+    }
+
+    private void handleStartSatelliteTransmissionUpdatesDone(@NonNull AsyncResult ar) {
+        SatelliteControllerHandlerRequest request = (SatelliteControllerHandlerRequest) ar.userObj;
+        SatelliteTransmissionUpdateArgument arg =
+                (SatelliteTransmissionUpdateArgument) request.argument;
+        int errorCode =  SatelliteServiceUtils.getSatelliteError(ar,
+                "handleStartSatelliteTransmissionUpdatesDone");
+        arg.errorCallback.accept(errorCode);
+
+        if (errorCode != SatelliteManager.SATELLITE_ERROR_NONE) {
+            mPointingAppController.setStartedSatelliteTransmissionUpdates(false);
+            // We need to remove the callback from our listener list since the caller might not call
+            // stopSatelliteTransmissionUpdates to unregister the callback in case of failure.
+            mPointingAppController.unregisterForSatelliteTransmissionUpdates(arg.subId,
+                    arg.errorCallback, arg.callback, request.phone);
+        } else {
+            mPointingAppController.setStartedSatelliteTransmissionUpdates(true);
+        }
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread and returns immediately.
+     *
+     * @param command command to be executed on the main thread
+     * @param argument additional parameters required to perform of the operation
+     * @param phone phone object used to perform the operation.
+     */
+    private void sendRequestAsync(int command, @NonNull Object argument, @Nullable Phone phone) {
+        SatelliteControllerHandlerRequest request = new SatelliteControllerHandlerRequest(
+                argument, phone);
+        Message msg = this.obtainMessage(command, request);
+        msg.sendToTarget();
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread. As this is a synchronous
+     * request, it waits until the request is complete and then return the result.
+     *
+     * @param command command to be executed on the main thread
+     * @param argument additional parameters required to perform of the operation
+     * @param phone phone object used to perform the operation.
+     * @return result of the operation
+     */
+    private @Nullable Object sendRequest(int command, @NonNull Object argument,
+            @Nullable Phone phone) {
+        if (Looper.myLooper() == this.getLooper()) {
+            throw new RuntimeException("This method will deadlock if called from the main thread");
+        }
+
+        SatelliteControllerHandlerRequest request = new SatelliteControllerHandlerRequest(
+                argument, phone);
+        Message msg = this.obtainMessage(command, request);
+        msg.sendToTarget();
+
+        synchronized (request) {
+            while(request.result == null) {
+                try {
+                    request.wait();
+                } catch (InterruptedException e) {
+                    // Do nothing, go back and wait until the request is complete.
+                }
+            }
+        }
+        return request.result;
+    }
+
+    /**
+     * Check if satellite is provisioned for a subscription on the device.
+     * @return true if satellite is provisioned on the given subscription else return false.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    protected Boolean isSatelliteProvisioned() {
+        synchronized (mIsSatelliteProvisionedLock) {
+            if (mIsSatelliteProvisioned != null) {
+                return mIsSatelliteProvisioned;
+            }
+        }
+
+        requestIsSatelliteProvisioned(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                new ResultReceiver(this) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        logd("requestIsSatelliteProvisioned: resultCode=" + resultCode);
+                    }
+                });
+        return null;
+    }
+
+    private void handleSatelliteEnabled(SatelliteControllerHandlerRequest request) {
+        RequestSatelliteEnabledArgument argument =
+                (RequestSatelliteEnabledArgument) request.argument;
+        Message onCompleted = obtainMessage(EVENT_SET_SATELLITE_ENABLED_DONE, request);
+        if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+            mSatelliteModemInterface.requestSatelliteEnabled(argument.enableSatellite,
+                    argument.enableDemoMode, onCompleted);
+            return;
+        }
+        Phone phone = request.phone;
+        if (phone != null) {
+            phone.setSatellitePower(onCompleted, argument.enableSatellite);
+        } else {
+            loge("requestSatelliteEnabled: No phone object");
+            argument.callback.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+        }
+    }
+
+    private void updateSatelliteSupportedStateWhenSatelliteServiceConnected(boolean supported) {
+        synchronized (mIsSatelliteSupportedLock) {
+            mIsSatelliteSupported = supported;
+        }
+        mSatelliteSessionController = SatelliteSessionController.make(
+                mContext, getLooper(), supported);
+        if (supported) {
+            registerForSatelliteProvisionStateChanged();
+            registerForPendingDatagramCount();
+            registerForSatelliteModemStateChanged();
+
+            requestIsSatelliteProvisioned(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                    new ResultReceiver(this) {
+                        @Override
+                        protected void onReceiveResult(int resultCode, Bundle resultData) {
+                            logd("requestIsSatelliteProvisioned: resultCode=" + resultCode);
+                            requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                                    false, false,
+                                    new IIntegerConsumer.Stub() {
+                                        @Override
+                                        public void accept(int result) {
+                                            logd("requestSatelliteEnabled: result=" + result);
+                                        }
+                                    });
+                        }
+                    });
+            requestSatelliteCapabilities(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                    new ResultReceiver(this) {
+                        @Override
+                        protected void onReceiveResult(int resultCode, Bundle resultData) {
+                            logd("requestSatelliteCapabilities: resultCode=" + resultCode);
+                        }
+                    });
+        }
+    }
+
+    private void updateSatelliteEnabledState(boolean enabled, String caller) {
+        synchronized (mIsSatelliteEnabledLock) {
+            mIsSatelliteEnabled = enabled;
+        }
+        if (mSatelliteSessionController != null) {
+            mSatelliteSessionController.onSatelliteEnabledStateChanged(enabled);
+            mSatelliteSessionController.setDemoMode(mIsDemoModeEnabled);
+        } else {
+            loge(caller + ": mSatelliteSessionController is not initialized yet");
+        }
+    }
+
+    private void registerForSatelliteProvisionStateChanged() {
+        if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+            if (!mRegisteredForProvisionStateChangedWithSatelliteService.get()) {
+                mSatelliteModemInterface.registerForSatelliteProvisionStateChanged(
+                        this, EVENT_SATELLITE_PROVISION_STATE_CHANGED, null);
+                mRegisteredForProvisionStateChangedWithSatelliteService.set(true);
+            }
+        } else {
+            Phone phone = SatelliteServiceUtils.getPhone();
+            if (phone == null) {
+                loge("registerForSatelliteProvisionStateChanged: phone is null");
+            } else if (!mRegisteredForProvisionStateChangedWithPhone.get()) {
+                phone.registerForSatelliteProvisionStateChanged(
+                        this, EVENT_SATELLITE_PROVISION_STATE_CHANGED, null);
+                mRegisteredForProvisionStateChangedWithPhone.set(true);
+            }
+        }
+    }
+
+    private void registerForPendingDatagramCount() {
+        if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+            if (!mRegisteredForPendingDatagramCountWithSatelliteService.get()) {
+                mSatelliteModemInterface.registerForPendingDatagrams(
+                        this, EVENT_PENDING_DATAGRAMS, null);
+                mRegisteredForPendingDatagramCountWithSatelliteService.set(true);
+            }
+        } else {
+            Phone phone = SatelliteServiceUtils.getPhone();
+            if (phone == null) {
+                loge("registerForPendingDatagramCount: satellite phone is "
+                        + "not initialized yet");
+            } else if (!mRegisteredForPendingDatagramCountWithPhone.get()) {
+                phone.registerForPendingDatagramCount(this, EVENT_PENDING_DATAGRAMS, null);
+                mRegisteredForPendingDatagramCountWithPhone.set(true);
+            }
+        }
+    }
+
+    private void registerForSatelliteModemStateChanged() {
+        if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+            if (!mRegisteredForSatelliteModemStateChangedWithSatelliteService.get()) {
+                mSatelliteModemInterface.registerForSatelliteModemStateChanged(
+                        this, EVENT_SATELLITE_MODEM_STATE_CHANGED, null);
+                mRegisteredForSatelliteModemStateChangedWithSatelliteService.set(true);
+            }
+        } else {
+            Phone phone = SatelliteServiceUtils.getPhone();
+            if (phone == null) {
+                loge("registerForSatelliteModemStateChanged: satellite phone is "
+                        + "not initialized yet");
+            } else if (!mRegisteredForSatelliteModemStateChangedWithPhone.get()) {
+                phone.registerForSatelliteModemStateChanged(
+                        this, EVENT_SATELLITE_MODEM_STATE_CHANGED, null);
+                mRegisteredForSatelliteModemStateChangedWithPhone.set(true);
+            }
+        }
+    }
+
+    private void handleEventSatelliteProvisionStateChanged(boolean provisioned) {
+        logd("handleSatelliteProvisionStateChangedEvent: provisioned=" + provisioned);
+
+        synchronized (mIsSatelliteProvisionedLock) {
+            mIsSatelliteProvisioned = provisioned;
+        }
+
+        List<ISatelliteProvisionStateCallback> toBeRemoved = new ArrayList<>();
+        mSatelliteProvisionStateChangedListeners.values().forEach(listener -> {
+            try {
+                listener.onSatelliteProvisionStateChanged(provisioned);
+            } catch (RemoteException e) {
+                logd("handleSatelliteProvisionStateChangedEvent RemoteException: " + e);
+                toBeRemoved.add(listener);
+            }
+        });
+        toBeRemoved.forEach(listener -> {
+            mSatelliteProvisionStateChangedListeners.remove(listener.asBinder());
+        });
+    }
+
+    private void handleEventSatelliteModemStateChanged(
+            @SatelliteManager.SatelliteModemState int state) {
+        logd("handleEventSatelliteModemStateChanged: state=" + state);
+        if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
+                || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
+            setSettingsKeyForSatelliteMode(SATELLITE_MODE_ENABLED_FALSE);
+            setDemoModeEnabled(false);
+            updateSatelliteEnabledState(
+                    false, "handleEventSatelliteModemStateChanged");
+            cleanUpResources(state);
+        }
+
+        mDatagramController.onSatelliteModemStateChanged(state);
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void setSettingsKeyForSatelliteMode(int val) {
+        logd("setSettingsKeyForSatelliteMode val: " + val);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                    Settings.Global.SATELLITE_MODE_ENABLED, val);
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected boolean areAllRadiosDisabled() {
+        synchronized (mRadioStateLock) {
+            if ((mDisableBTOnSatelliteEnabled && mBTStateEnabled)
+                    || (mDisableNFCOnSatelliteEnabled && mNfcStateEnabled)
+                    || (mDisableWifiOnSatelliteEnabled && mWifiStateEnabled)
+                    || (mDisableUWBOnSatelliteEnabled && mUwbStateEnabled)) {
+                logd("All radios are not disabled yet.");
+                return false;
+            }
+            logd("All radios are disabled.");
+            return true;
+        }
+    }
+
+    private void evaluateToSendSatelliteEnabledSuccess() {
+        logd("evaluateToSendSatelliteEnabledSuccess");
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (areAllRadiosDisabled() && (mSatelliteEnabledRequest != null)
+                    && mWaitingForRadioDisabled) {
+                logd("Sending success to callback that sent enable satellite request");
+                setDemoModeEnabled(mSatelliteEnabledRequest.enableDemoMode);
+                synchronized (mIsSatelliteEnabledLock) {
+                    mIsSatelliteEnabled = mSatelliteEnabledRequest.enableSatellite;
+                }
+                mSatelliteEnabledRequest.callback.accept(SatelliteManager.SATELLITE_ERROR_NONE);
+                updateSatelliteEnabledState(
+                        mSatelliteEnabledRequest.enableSatellite,
+                        "EVENT_SET_SATELLITE_ENABLED_DONE");
+                mSatelliteEnabledRequest = null;
+                mWaitingForRadioDisabled = false;
+            }
+        }
+    }
+
+    private void resetSatelliteEnabledRequest() {
+        logd("resetSatelliteEnabledRequest");
+        synchronized (mSatelliteEnabledRequestLock) {
+            mSatelliteEnabledRequest = null;
+            mWaitingForRadioDisabled = false;
+        }
+    }
+
+    private void cleanUpResources(@SatelliteManager.SatelliteModemState int state) {
+        logd("cleanUpResources");
+        if (state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
+            synchronized (mSatelliteEnabledRequestLock) {
+                if (mSatelliteEnabledRequest != null) {
+                    mSatelliteEnabledRequest.callback.accept(
+                            SatelliteManager.SATELLITE_INVALID_MODEM_STATE);
+                }
+            }
+            resetSatelliteEnabledRequest();
+        }
+    }
+
+    private void setDemoModeEnabled(boolean enabled) {
+        mIsDemoModeEnabled = enabled;
+        mDatagramController.setDemoMode(mIsDemoModeEnabled);
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
new file mode 100644
index 0000000..80c67b3
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -0,0 +1,1069 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RegistrantList;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.telephony.Rlog;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteManager.SatelliteException;
+import android.telephony.satellite.stub.ISatellite;
+import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
+import android.telephony.satellite.stub.ISatelliteListener;
+import android.telephony.satellite.stub.SatelliteService;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.ExponentialBackoff;
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntegerConsumer;
+
+import java.util.Arrays;
+
+/**
+ * Satellite modem interface to manage connections with the satellite service and HAL interface.
+ */
+public class SatelliteModemInterface {
+    private static final String TAG = "SatelliteModemInterface";
+    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
+    private static final boolean DEBUG = !"user".equals(Build.TYPE);
+    private static final long REBIND_INITIAL_DELAY = 2 * 1000; // 2 seconds
+    private static final long REBIND_MAXIMUM_DELAY = 64 * 1000; // 1 minute
+    private static final int REBIND_MULTIPLIER = 2;
+
+    @NonNull private static SatelliteModemInterface sInstance;
+    @NonNull private final Context mContext;
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    @NonNull protected final ExponentialBackoff mExponentialBackoff;
+    @NonNull private final Object mLock = new Object();
+    @NonNull private final SatelliteController mSatelliteController;
+    /**
+     * {@code true} to use the vendor satellite service and {@code false} to use the HAL.
+     */
+    private boolean mIsSatelliteServiceSupported;
+    @Nullable private ISatellite mSatelliteService;
+    @Nullable private SatelliteServiceConnection mSatelliteServiceConnection;
+    @NonNull private String mVendorSatellitePackageName = "";
+    private boolean mIsBound;
+    private boolean mIsBinding;
+
+    @NonNull private final RegistrantList mSatelliteProvisionStateChangedRegistrants =
+            new RegistrantList();
+    @NonNull private final RegistrantList mSatellitePositionInfoChangedRegistrants =
+            new RegistrantList();
+    @NonNull private final RegistrantList mDatagramTransferStateChangedRegistrants =
+            new RegistrantList();
+    @NonNull private final RegistrantList mSatelliteModemStateChangedRegistrants =
+            new RegistrantList();
+    @NonNull private final RegistrantList mPendingDatagramsRegistrants = new RegistrantList();
+    @NonNull private final RegistrantList mSatelliteDatagramsReceivedRegistrants =
+            new RegistrantList();
+
+    @NonNull private final ISatelliteListener mListener = new ISatelliteListener.Stub() {
+        @Override
+        public void onSatelliteProvisionStateChanged(boolean provisioned) {
+            mSatelliteProvisionStateChangedRegistrants.notifyResult(provisioned);
+        }
+
+        @Override
+        public void onSatelliteDatagramReceived(
+                android.telephony.satellite.stub.SatelliteDatagram datagram, int pendingCount) {
+            mSatelliteDatagramsReceivedRegistrants.notifyResult(new Pair<>(
+                    SatelliteServiceUtils.fromSatelliteDatagram(datagram), pendingCount));
+        }
+
+        @Override
+        public void onPendingDatagrams() {
+            mPendingDatagramsRegistrants.notifyResult(null);
+        }
+
+        @Override
+        public void onSatellitePositionChanged(
+                android.telephony.satellite.stub.PointingInfo pointingInfo) {
+            mSatellitePositionInfoChangedRegistrants.notifyResult(
+                    SatelliteServiceUtils.fromPointingInfo(pointingInfo));
+        }
+
+        @Override
+        public void onSatelliteModemStateChanged(int state) {
+            mSatelliteModemStateChangedRegistrants.notifyResult(
+                    SatelliteServiceUtils.fromSatelliteModemState(state));
+            int datagramTransferState = SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN;
+            switch (state) {
+                case SatelliteManager.SATELLITE_MODEM_STATE_IDLE:
+                    datagramTransferState = SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+                    break;
+                case SatelliteManager.SATELLITE_MODEM_STATE_LISTENING:
+                    datagramTransferState =
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING;
+                    break;
+                case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
+                    datagramTransferState =
+                            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING;
+                    break;
+                case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING:
+                    // keep previous state as this could be retrying sending or receiving
+                    break;
+            }
+            mDatagramTransferStateChangedRegistrants.notifyResult(datagramTransferState);
+        }
+    };
+
+    /**
+     * @return The singleton instance of SatelliteModemInterface.
+     */
+    public static SatelliteModemInterface getInstance() {
+        if (sInstance == null) {
+            loge("SatelliteModemInterface was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the SatelliteModemInterface singleton instance.
+     * @param context The Context to use to create the SatelliteModemInterface.
+     * @param satelliteController The singleton instance of SatelliteController.
+     * @return The singleton instance of SatelliteModemInterface.
+     */
+    public static SatelliteModemInterface make(@NonNull Context context,
+            SatelliteController satelliteController) {
+        if (sInstance == null) {
+            sInstance = new SatelliteModemInterface(
+                    context, satelliteController, Looper.getMainLooper());
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a SatelliteModemInterface to manage connections to the SatelliteService.
+     *
+     * @param context The Context for the SatelliteModemInterface.
+     * @param looper The Looper to run binding retry on.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected SatelliteModemInterface(@NonNull Context context,
+            SatelliteController satelliteController, @NonNull Looper looper) {
+        mContext = context;
+        mIsSatelliteServiceSupported = getSatelliteServiceSupport();
+        mSatelliteController = satelliteController;
+        mExponentialBackoff = new ExponentialBackoff(REBIND_INITIAL_DELAY, REBIND_MAXIMUM_DELAY,
+                REBIND_MULTIPLIER, looper, () -> {
+            synchronized (mLock) {
+                if ((mIsBound && mSatelliteService != null) || mIsBinding) {
+                    return;
+                }
+            }
+            if (mSatelliteServiceConnection != null) {
+                synchronized (mLock) {
+                    mIsBound = false;
+                    mIsBinding = false;
+                }
+                unbindService();
+            }
+            bindService();
+        });
+        mExponentialBackoff.start();
+        logd("Created SatelliteModemInterface. Attempting to bind to SatelliteService.");
+        bindService();
+    }
+
+    /**
+     * Get the SatelliteService interface, if it exists.
+     *
+     * @return The bound ISatellite, or {@code null} if it is not yet connected.
+     */
+    @Nullable public ISatellite getService() {
+        return mSatelliteService;
+    }
+
+    @NonNull private String getSatellitePackageName() {
+        if (!TextUtils.isEmpty(mVendorSatellitePackageName)) {
+            return mVendorSatellitePackageName;
+        }
+        return TextUtils.emptyIfNull(mContext.getResources().getString(
+                R.string.config_satellite_service_package));
+    }
+
+    private boolean getSatelliteServiceSupport() {
+        return !TextUtils.isEmpty(getSatellitePackageName());
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void bindService() {
+        synchronized (mLock) {
+            if (mIsBinding || mIsBound) return;
+            mIsBinding = true;
+        }
+        String packageName = getSatellitePackageName();
+        if (TextUtils.isEmpty(packageName)) {
+            loge("Unable to bind to the satellite service because the package is undefined.");
+            // Since the package name comes from static device configs, stop retry because
+            // rebind will continue to fail without a valid package name.
+            synchronized (mLock) {
+                mIsBinding = false;
+            }
+            mExponentialBackoff.stop();
+            return;
+        }
+        Intent intent = new Intent(SatelliteService.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+
+        mSatelliteServiceConnection = new SatelliteServiceConnection();
+        logd("Binding to " + packageName);
+        try {
+            boolean success = mContext.bindService(
+                    intent, mSatelliteServiceConnection, Context.BIND_AUTO_CREATE);
+            if (success) {
+                logd("Successfully bound to the satellite service.");
+            } else {
+                synchronized (mLock) {
+                    mIsBinding = false;
+                }
+                mExponentialBackoff.notifyFailed();
+                loge("Error binding to the satellite service. Retrying in "
+                        + mExponentialBackoff.getCurrentDelay() + " ms.");
+            }
+        } catch (Exception e) {
+            synchronized (mLock) {
+                mIsBinding = false;
+            }
+            mExponentialBackoff.notifyFailed();
+            loge("Exception binding to the satellite service. Retrying in "
+                    + mExponentialBackoff.getCurrentDelay() + " ms. Exception: " + e);
+        }
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected void unbindService() {
+        disconnectSatelliteService();
+        mContext.unbindService(mSatelliteServiceConnection);
+        mSatelliteServiceConnection = null;
+    }
+
+    private void disconnectSatelliteService() {
+        // TODO: clean up any listeners and return failed for pending callbacks
+        mSatelliteService = null;
+    }
+
+    private class SatelliteServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            logd("onServiceConnected: ComponentName=" + name);
+            synchronized (mLock) {
+                mIsBound = true;
+                mIsBinding = false;
+            }
+            mSatelliteService = ISatellite.Stub.asInterface(service);
+            mExponentialBackoff.stop();
+            try {
+                mSatelliteService.setSatelliteListener(mListener);
+            } catch (RemoteException e) {
+                // TODO: Retry setSatelliteListener
+                logd("setSatelliteListener: RemoteException " + e);
+            }
+            mSatelliteController.onSatelliteServiceConnected();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            loge("onServiceDisconnected: Waiting for reconnect.");
+            synchronized (mLock) {
+                mIsBinding = false;
+            }
+            // Since we are still technically bound, clear the service and wait for reconnect.
+            disconnectSatelliteService();
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            loge("onBindingDied: Unbinding and rebinding service.");
+            synchronized (mLock) {
+                mIsBound = false;
+                mIsBinding = false;
+            }
+            unbindService();
+            mExponentialBackoff.start();
+        }
+    }
+
+    /**
+     * Registers for the satellite provision state changed.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteProvisionStateChanged(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mSatelliteProvisionStateChangedRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for the satellite provision state changed.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteProvisionStateChanged(@NonNull Handler h) {
+        mSatelliteProvisionStateChangedRegistrants.remove(h);
+    }
+
+    /**
+     * Registers for satellite position info changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatellitePositionInfoChanged(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mSatellitePositionInfoChangedRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for satellite position info changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatellitePositionInfoChanged(@NonNull Handler h) {
+        mSatellitePositionInfoChangedRegistrants.remove(h);
+    }
+
+    /**
+     * Registers for datagram transfer state changed.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForDatagramTransferStateChanged(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mDatagramTransferStateChangedRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for datagram transfer state changed.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForDatagramTransferStateChanged(@NonNull Handler h) {
+        mDatagramTransferStateChangedRegistrants.remove(h);
+    }
+
+    /**
+     * Registers for modem state changed from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteModemStateChanged(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mSatelliteModemStateChangedRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for modem state changed from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteModemStateChanged(@NonNull Handler h) {
+        mSatelliteModemStateChangedRegistrants.remove(h);
+    }
+
+    /**
+     * Registers for pending datagrams indication from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForPendingDatagrams(@NonNull Handler h, int what, @Nullable Object obj) {
+        mPendingDatagramsRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for pending datagrams indication from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForPendingDatagrams(@NonNull Handler h) {
+        mPendingDatagramsRegistrants.remove(h);
+    }
+
+    /**
+     * Registers for new datagrams received from satellite modem.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSatelliteDatagramsReceived(
+            @NonNull Handler h, int what, @Nullable Object obj) {
+        mSatelliteDatagramsReceivedRegistrants.add(h, what, obj);
+    }
+
+    /**
+     * Unregisters for new datagrams received from satellite modem.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSatelliteDatagramsReceived(@NonNull Handler h) {
+        mSatelliteDatagramsReceivedRegistrants.remove(h);
+    }
+
+    /**
+     * Request to enable or disable the satellite service listening mode.
+     * Listening mode allows the satellite service to listen for incoming pages.
+     *
+     * @param enable True to enable satellite listening mode and false to disable.
+     * @param timeout How long the satellite modem should wait for the next incoming page before
+     *                disabling listening mode.
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestSatelliteListeningEnabled(boolean enable, int timeout,
+            @Nullable Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestSatelliteListeningEnabled(enable, timeout,
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("requestSatelliteListeningEnabled: " + error);
+                                Binder.withCleanCallingIdentity(() -> {
+                                    if (message != null) {
+                                        sendMessageWithResult(message, null, error);
+                                    }
+                                });
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("requestSatelliteListeningEnabled: RemoteException " + e);
+                if (message != null) {
+                    sendMessageWithResult(
+                            message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+                }
+            }
+        } else {
+            loge("requestSatelliteListeningEnabled: Satellite service is unavailable.");
+            if (message != null) {
+                sendMessageWithResult(message, null,
+                        SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+            }
+        }
+    }
+
+    /**
+     * Allow cellular modem scanning while satellite mode is on.
+     * @param enabled  {@code true} to enable cellular modem while satellite mode is on
+     * and {@code false} to disable
+     * @param message The Message to send to result of the operation to.
+     */
+    public void enableCellularModemWhileSatelliteModeIsOn(boolean enabled,
+            @Nullable Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.enableCellularModemWhileSatelliteModeIsOn(enabled,
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("enableCellularModemWhileSatelliteModeIsOn: " + error);
+                                Binder.withCleanCallingIdentity(() -> {
+                                        if (message != null) {
+                                            sendMessageWithResult(message, null, error);
+                                        }
+                                });
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("enableCellularModemWhileSatelliteModeIsOn: RemoteException " + e);
+                if (message != null) {
+                    sendMessageWithResult(
+                            message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+                }
+            }
+        } else {
+            loge("enableCellularModemWhileSatelliteModeIsOn: Satellite service is unavailable.");
+            if (message != null) {
+                sendMessageWithResult(message, null,
+                        SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+            }
+        }
+    }
+    /**
+     * Request to enable or disable the satellite modem and demo mode. If the satellite modem
+     * is enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
+     * this may also re-enable the cellular modem.
+     *
+     * @param enableSatellite True to enable the satellite modem and false to disable.
+     * @param enableDemoMode True to enable demo mode and false to disable.
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
+            @NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestSatelliteEnabled(enableSatellite, enableDemoMode,
+                        new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("setSatelliteEnabled: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("setSatelliteEnabled: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("setSatelliteEnabled: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get whether the satellite modem is enabled.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestIsSatelliteEnabled(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestIsSatelliteEnabled(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("requestIsSatelliteEnabled: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                }, new IBooleanConsumer.Stub() {
+                    @Override
+                    public void accept(boolean result) {
+                        // Convert for compatibility with SatelliteResponse
+                        // TODO: This should just report result instead.
+                        int[] enabled = new int[] {result ? 1 : 0};
+                        logd("requestIsSatelliteEnabled: " + Arrays.toString(enabled));
+                        Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                message, enabled, SatelliteManager.SATELLITE_ERROR_NONE));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("requestIsSatelliteEnabled: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestIsSatelliteEnabled: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get whether the satellite service is supported on the device.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestIsSatelliteSupported(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestIsSatelliteSupported(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("requestIsSatelliteSupported: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                }, new IBooleanConsumer.Stub() {
+                    @Override
+                    public void accept(boolean result) {
+                        logd("requestIsSatelliteSupported: " + result);
+                        Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                message, result, SatelliteManager.SATELLITE_ERROR_NONE));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("requestIsSatelliteSupported: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestIsSatelliteSupported: Satellite service is unavailable.");
+            sendMessageWithResult(
+                    message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get the SatelliteCapabilities of the satellite service.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestSatelliteCapabilities(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestSatelliteCapabilities(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("requestSatelliteCapabilities: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                }, new ISatelliteCapabilitiesConsumer.Stub() {
+                    @Override
+                    public void accept(android.telephony.satellite.stub.SatelliteCapabilities
+                            result) {
+                        SatelliteCapabilities capabilities =
+                                SatelliteServiceUtils.fromSatelliteCapabilities(result);
+                        logd("requestSatelliteCapabilities: " + capabilities);
+                        Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                message, capabilities, SatelliteManager.SATELLITE_ERROR_NONE));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("requestSatelliteCapabilities: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestSatelliteCapabilities: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * User started pointing to the satellite.
+     * The satellite service should report the satellite pointing info via
+     * ISatelliteListener#onSatellitePositionChanged as the user device/satellite moves.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void startSendingSatellitePointingInfo(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.startSendingSatellitePointingInfo(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("startSendingSatellitePointingInfo: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("startSendingSatellitePointingInfo: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("startSendingSatellitePointingInfo: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * User stopped pointing to the satellite.
+     * The satellite service should stop reporting satellite pointing info to the framework.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void stopSendingSatellitePointingInfo(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.stopSendingSatellitePointingInfo(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("stopSendingSatellitePointingInfo: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("stopSendingSatellitePointingInfo: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("stopSendingSatellitePointingInfo: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Provision the device with a satellite provider.
+     * This is needed if the provider allows dynamic registration.
+     * Once provisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report true.
+     *
+     * @param token The token to be used as a unique identifier for provisioning with satellite
+     *              gateway.
+     * @param provisionData Data from the provisioning app that can be used by provisioning server
+     * @param message The Message to send to result of the operation to.
+     */
+    public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
+            @NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.provisionSatelliteService(token, provisionData,
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("provisionSatelliteService: " + error);
+                                Binder.withCleanCallingIdentity(() ->
+                                        sendMessageWithResult(message, null, error));
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("provisionSatelliteService: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("provisionSatelliteService: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Deprovision the device with the satellite provider.
+     * This is needed if the provider allows dynamic registration.
+     * Once deprovisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report false.
+     *
+     * @param token The token of the device/subscription to be deprovisioned.
+     * @param message The Message to send to result of the operation to.
+     */
+    public void deprovisionSatelliteService(@NonNull String token, @NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.deprovisionSatelliteService(token, new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("deprovisionSatelliteService: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("deprovisionSatelliteService: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("deprovisionSatelliteService: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get whether this device is provisioned with a satellite provider.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestIsSatelliteProvisioned(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestIsSatelliteProvisioned(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("requestIsSatelliteProvisioned: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                }, new IBooleanConsumer.Stub() {
+                    @Override
+                    public void accept(boolean result) {
+                        // Convert for compatibility with SatelliteResponse
+                        // TODO: This should just report result instead.
+                        int[] provisioned = new int[] {result ? 1 : 0};
+                        logd("requestIsSatelliteProvisioned: " + Arrays.toString(provisioned));
+                        Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                message, provisioned, SatelliteManager.SATELLITE_ERROR_NONE));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("requestIsSatelliteProvisioned: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestIsSatelliteProvisioned: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Poll the pending datagrams to be received over satellite.
+     * The satellite service should check if there are any pending datagrams to be received over
+     * satellite and report them via ISatelliteListener#onSatelliteDatagramsReceived.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void pollPendingSatelliteDatagrams(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.pollPendingSatelliteDatagrams(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("pollPendingSatelliteDatagrams: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("pollPendingSatelliteDatagrams: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("pollPendingSatelliteDatagrams: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Send datagram over satellite.
+     *
+     * @param datagram Datagram to send in byte format.
+     * @param isEmergency Whether this is an emergency datagram.
+     * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
+     *                                 full screen mode.
+     * @param message The Message to send to result of the operation to.
+     */
+    public void sendSatelliteDatagram(@NonNull SatelliteDatagram datagram, boolean isEmergency,
+            boolean needFullScreenPointingUI, @NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.sendSatelliteDatagram(
+                        SatelliteServiceUtils.toSatelliteDatagram(datagram), isEmergency,
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("sendSatelliteDatagram: " + error);
+                                Binder.withCleanCallingIdentity(() ->
+                                        sendMessageWithResult(message, null, error));
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("sendSatelliteDatagram: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("sendSatelliteDatagram: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request the current satellite modem state.
+     * The satellite service should report the current satellite modem state via
+     * ISatelliteListener#onSatelliteModemStateChanged.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestSatelliteModemState(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestSatelliteModemState(new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        int error = SatelliteServiceUtils.fromSatelliteError(result);
+                        logd("requestSatelliteModemState: " + error);
+                        Binder.withCleanCallingIdentity(() ->
+                                sendMessageWithResult(message, null, error));
+                    }
+                }, new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        // Convert SatelliteModemState from service to frameworks definition.
+                        int modemState = SatelliteServiceUtils.fromSatelliteModemState(result);
+                        logd("requestSatelliteModemState: " + modemState);
+                        Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                message, modemState, SatelliteManager.SATELLITE_ERROR_NONE));
+                    }
+                });
+            } catch (RemoteException e) {
+                loge("requestSatelliteModemState: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestSatelliteModemState: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get whether satellite communication is allowed for the current location.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestIsSatelliteCommunicationAllowedForCurrentLocation(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestIsSatelliteCommunicationAllowedForCurrentLocation(
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: "
+                                        + error);
+                                Binder.withCleanCallingIdentity(() ->
+                                        sendMessageWithResult(message, null, error));
+                            }
+                        }, new IBooleanConsumer.Stub() {
+                            @Override
+                            public void accept(boolean result) {
+                                logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: "
+                                        + result);
+                                Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                        message, result, SatelliteManager.SATELLITE_ERROR_NONE));
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("requestIsSatelliteCommunicationAllowedForCurrentLocation: RemoteException "
+                        + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestIsSatelliteCommunicationAllowedForCurrentLocation: "
+                    + "Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Request to get the time after which the satellite will be visible. This is an int
+     * representing the duration in seconds after which the satellite will be visible.
+     * This will return 0 if the satellite is currently visible.
+     *
+     * @param message The Message to send to result of the operation to.
+     */
+    public void requestTimeForNextSatelliteVisibility(@NonNull Message message) {
+        if (mSatelliteService != null) {
+            try {
+                mSatelliteService.requestTimeForNextSatelliteVisibility(
+                        new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                int error = SatelliteServiceUtils.fromSatelliteError(result);
+                                logd("requestTimeForNextSatelliteVisibility: " + error);
+                                Binder.withCleanCallingIdentity(() ->
+                                        sendMessageWithResult(message, null, error));
+                            }
+                        }, new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                // Convert for compatibility with SatelliteResponse
+                                // TODO: This should just report result instead.
+                                int[] time = new int[] {result};
+                                logd("requestTimeForNextSatelliteVisibility: "
+                                        + Arrays.toString(time));
+                                Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+                                        message, time, SatelliteManager.SATELLITE_ERROR_NONE));
+                            }
+                        });
+            } catch (RemoteException e) {
+                loge("requestTimeForNextSatelliteVisibility: RemoteException " + e);
+                sendMessageWithResult(message, null, SatelliteManager.SATELLITE_SERVICE_ERROR);
+            }
+        } else {
+            loge("requestTimeForNextSatelliteVisibility: Satellite service is unavailable.");
+            sendMessageWithResult(message, null, SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE);
+        }
+    }
+
+    public boolean isSatelliteServiceSupported() {
+        return mIsSatelliteServiceSupported;
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite vendor service package name.
+     *
+     * @param servicePackageName The package name of the satellite vendor service.
+     * @return {@code true} if the satellite vendor service is set successfully,
+     * {@code false} otherwise.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public boolean setSatelliteServicePackageName(@Nullable String servicePackageName) {
+        if (!shouldAllowModifyingSatelliteServicePackageName()) {
+            loge("setSatelliteServicePackageName: modifying satellite service package name "
+                    + "is not allowed");
+            return false;
+        }
+
+        logd("setSatelliteServicePackageName: config_satellite_service_package is "
+                + "updated, new packageName=" + servicePackageName);
+        mExponentialBackoff.stop();
+        if (mSatelliteServiceConnection != null) {
+            synchronized (mLock) {
+                mIsBound = false;
+                mIsBinding = false;
+            }
+            unbindService();
+        }
+
+        if (servicePackageName == null || servicePackageName.equals("null")) {
+            mVendorSatellitePackageName = "";
+        } else {
+            mVendorSatellitePackageName = servicePackageName;
+        }
+        mIsSatelliteServiceSupported = getSatelliteServiceSupport();
+        bindService();
+        mExponentialBackoff.start();
+
+        return true;
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected static void sendMessageWithResult(@NonNull Message message, @Nullable Object result,
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = error == SatelliteManager.SATELLITE_ERROR_NONE
+                ? null : new SatelliteException(error);
+        AsyncResult.forMessage(message, result, exception);
+        message.sendToTarget();
+    }
+
+    private boolean shouldAllowModifyingSatelliteServicePackageName() {
+        return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
new file mode 100644
index 0000000..25657b3
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_ERROR_NONE;
+
+import android.annotation.NonNull;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ResultReceiver;
+import android.provider.DeviceConfig;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telephony.Rlog;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.util.Pair;
+
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.metrics.SatelliteStats;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+/**
+ * This module is responsible for monitoring the cellular service state and IMS registration state
+ * during an emergency call and notify Dialer when Telephony is not able to find any network and
+ * the call likely will not get connected so that Dialer will prompt the user if they would like to
+ * switch to satellite messaging.
+ */
+public class SatelliteSOSMessageRecommender extends Handler {
+    private static final String TAG = "SatelliteSOSMessageRecommender";
+
+    /**
+     * Device config for the timeout duration in milliseconds to determine whether to recommend
+     * Dialer to show the SOS button to users.
+     * <p>
+     * The timer is started when there is an ongoing emergency call, and the IMS is not registered,
+     * and cellular service is not available. When the timer expires, SatelliteSOSMessageRecommender
+     * will send the event EVENT_DISPLAY_SOS_MESSAGE to Dialer, which will then prompt user to
+     * switch to using satellite SOS messaging.
+     */
+    public static final String EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS =
+            "emergency_call_to_sos_msg_hysteresis_timeout_millis";
+    /**
+     * The default value of {@link #EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS} when it is
+     * not provided in the device config.
+     */
+    public static final long DEFAULT_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 20000;
+
+    private static final int EVENT_EMERGENCY_CALL_STARTED = 1;
+    protected static final int EVENT_CELLULAR_SERVICE_STATE_CHANGED = 2;
+    private static final int EVENT_IMS_REGISTRATION_STATE_CHANGED = 3;
+    protected static final int EVENT_TIME_OUT = 4;
+    private static final int EVENT_SATELLITE_PROVISIONED_STATE_CHANGED = 5;
+    private static final int EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED = 6;
+
+    @NonNull
+    private final SatelliteController mSatelliteController;
+    private ImsManager mImsManager;
+
+    private Connection mEmergencyConnection = null;
+    /* The phone used for emergency call */
+    private Phone mPhone = null;
+    private final ISatelliteProvisionStateCallback mISatelliteProvisionStateCallback;
+    @ServiceState.RegState
+    private AtomicInteger mCellularServiceState = new AtomicInteger();
+    private AtomicBoolean mIsImsRegistered = new AtomicBoolean();
+    private AtomicBoolean mIsSatelliteAllowedInCurrentLocation = new AtomicBoolean();
+    private final ResultReceiver mReceiverForRequestIsSatelliteAllowedForCurrentLocation;
+    private final long mTimeoutMillis;
+    protected int mCountOfTimerStarted = 0;
+
+    private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
+            new RegistrationManager.RegistrationCallback() {
+                @Override
+                public void onRegistered(ImsRegistrationAttributes attributes) {
+                    sendMessage(obtainMessage(EVENT_IMS_REGISTRATION_STATE_CHANGED, true));
+                }
+
+                @Override
+                public void onUnregistered(ImsReasonInfo info) {
+                    sendMessage(obtainMessage(EVENT_IMS_REGISTRATION_STATE_CHANGED, false));
+                }
+            };
+
+    /**
+     * Create an instance of SatelliteSOSMessageRecommender.
+     *
+     * @param looper The looper used with the handler of this class.
+     */
+    public SatelliteSOSMessageRecommender(@NonNull Looper looper) {
+        this(looper, SatelliteController.getInstance(), null,
+                getEmergencyCallToSosMsgHysteresisTimeoutMillis());
+    }
+
+    /**
+     * Create an instance of SatelliteSOSMessageRecommender. This constructor should be used in
+     * only unit tests.
+     *
+     * @param looper The looper used with the handler of this class.
+     * @param satelliteController The SatelliteController singleton instance.
+     * @param imsManager The ImsManager instance associated with the phone, which is used for making
+     *                   the emergency call. This argument is not null only in unit tests.
+     * @param timeoutMillis The timeout duration of the timer.
+     */
+    @VisibleForTesting
+    protected SatelliteSOSMessageRecommender(@NonNull Looper looper,
+            @NonNull SatelliteController satelliteController, ImsManager imsManager,
+            long timeoutMillis) {
+        super(looper);
+        mSatelliteController = satelliteController;
+        mImsManager = imsManager;
+        mTimeoutMillis = timeoutMillis;
+        mISatelliteProvisionStateCallback = new ISatelliteProvisionStateCallback.Stub() {
+            @Override
+            public void onSatelliteProvisionStateChanged(boolean provisioned) {
+                logd("onSatelliteProvisionStateChanged: provisioned=" + provisioned);
+                sendMessage(obtainMessage(EVENT_SATELLITE_PROVISIONED_STATE_CHANGED, provisioned));
+            }
+        };
+        mReceiverForRequestIsSatelliteAllowedForCurrentLocation = new ResultReceiver(this) {
+            @Override
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                if (resultCode == SATELLITE_ERROR_NONE) {
+                    if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+                        boolean isSatelliteCommunicationAllowed =
+                                resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+                        mIsSatelliteAllowedInCurrentLocation.set(isSatelliteCommunicationAllowed);
+                        if (!isSatelliteCommunicationAllowed) {
+                            logd("Satellite is not allowed for current location.");
+                            cleanUpResources();
+                        }
+                    } else {
+                        loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+                        mIsSatelliteAllowedInCurrentLocation.set(false);
+                        cleanUpResources();
+                    }
+                } else {
+                    loge("requestIsSatelliteCommunicationAllowedForCurrentLocation() resultCode="
+                            + resultCode);
+                    mIsSatelliteAllowedInCurrentLocation.set(false);
+                    cleanUpResources();
+                }
+            }
+        };
+    }
+
+    @Override
+    public void handleMessage(@NonNull Message msg) {
+        switch (msg.what) {
+            case EVENT_EMERGENCY_CALL_STARTED:
+                handleEmergencyCallStartedEvent((Pair<Connection, Phone>) msg.obj);
+                break;
+            case EVENT_TIME_OUT:
+                handleTimeoutEvent();
+                break;
+            case EVENT_SATELLITE_PROVISIONED_STATE_CHANGED:
+                handleSatelliteProvisionStateChangedEvent((boolean) msg.obj);
+                break;
+            case EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED:
+                handleEmergencyCallConnectionStateChangedEvent((Pair<String, Integer>) msg.obj);
+                break;
+            case EVENT_IMS_REGISTRATION_STATE_CHANGED:
+                handleImsRegistrationStateChangedEvent((boolean) msg.obj);
+                break;
+            case EVENT_CELLULAR_SERVICE_STATE_CHANGED:
+                AsyncResult ar = (AsyncResult) msg.obj;
+                handleCellularServiceStateChangedEvent((ServiceState) ar.result);
+                break;
+            default:
+                logd("handleMessage: unexpected message code: " + msg.what);
+                break;
+        }
+    }
+
+    /**
+     * Inform SatelliteSOSMessageRecommender that an emergency call has just started.
+     *
+     * @param connection The connection created by TelephonyConnectionService for the emergency
+     *                   call.
+     * @param phone The phone used for the emergency call.
+     */
+    public void onEmergencyCallStarted(@NonNull Connection connection, @NonNull Phone phone) {
+        if (!mSatelliteController.isSatelliteSupported()) {
+            logd("onEmergencyCallStarted: satellite is not supported");
+            return;
+        }
+        Pair<Connection, Phone> argument = new Pair<>(connection, phone);
+        sendMessage(obtainMessage(EVENT_EMERGENCY_CALL_STARTED, argument));
+    }
+
+    /**
+     * Inform SatelliteSOSMessageRecommender that the state of the emergency call connection has
+     * changed.
+     *
+     * @param callId The ID of the emergency call.
+     * @param state The connection state of the emergency call.
+     */
+    public void onEmergencyCallConnectionStateChanged(
+            String callId, @Connection.ConnectionState int state) {
+        Pair<String, Integer> argument = new Pair<>(callId, state);
+        sendMessage(obtainMessage(EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED, argument));
+    }
+
+    private void handleEmergencyCallStartedEvent(@NonNull Pair<Connection, Phone> arg) {
+        mSatelliteController.requestIsSatelliteCommunicationAllowedForCurrentLocation(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                mReceiverForRequestIsSatelliteAllowedForCurrentLocation);
+        if (mPhone != null) {
+            logd("handleEmergencyCallStartedEvent: new emergency call started while there is "
+                    + " an ongoing call");
+            unregisterForInterestedStateChangedEvents(mPhone);
+        }
+        mPhone = arg.second;
+        mEmergencyConnection = arg.first;
+        mCellularServiceState.set(mPhone.getServiceState().getState());
+        mIsImsRegistered.set(mPhone.isImsRegistered());
+        handleStateChangedEventForHysteresisTimer();
+        registerForInterestedStateChangedEvents(mPhone);
+    }
+
+    private void handleSatelliteProvisionStateChangedEvent(boolean provisioned) {
+        if (!provisioned) {
+            cleanUpResources();
+        }
+    }
+
+    private void handleTimeoutEvent() {
+        boolean isDialerNotified = false;
+        if (!mIsImsRegistered.get() && !isCellularAvailable()
+                && mIsSatelliteAllowedInCurrentLocation.get()
+                && mSatelliteController.isSatelliteProvisioned()
+                && shouldTrackCall(mEmergencyConnection.getState())) {
+            logd("handleTimeoutEvent: Sending EVENT_DISPLAY_SOS_MESSAGE to Dialer...");
+            mEmergencyConnection.sendConnectionEvent(Call.EVENT_DISPLAY_SOS_MESSAGE, null);
+            isDialerNotified = true;
+        }
+        reportEsosRecommenderDecision(isDialerNotified);
+        cleanUpResources();
+    }
+
+    private void handleEmergencyCallConnectionStateChangedEvent(
+            @NonNull Pair<String, Integer> arg) {
+        if (mEmergencyConnection == null) {
+            // Either the call was not created or the timer already timed out.
+            return;
+        }
+
+        String callId = arg.first;
+        int state = arg.second;
+        if (!mEmergencyConnection.getTelecomCallId().equals(callId)) {
+            loge("handleEmergencyCallConnectionStateChangedEvent: unexpected state changed event "
+                    + ", mEmergencyConnection=" + mEmergencyConnection + ", callId=" + callId
+                    + ", state=" + state);
+            /**
+             * TelephonyConnectionService sent us a connection state changed event for a call that
+             * we're not tracking. There must be some unexpected things happened in
+             * TelephonyConnectionService. Thus, we need to clean up the resources.
+             */
+            cleanUpResources();
+            return;
+        }
+
+        if (!shouldTrackCall(state)) {
+            reportEsosRecommenderDecision(false);
+            cleanUpResources();
+        }
+    }
+
+    private void handleImsRegistrationStateChangedEvent(boolean registered) {
+        if (registered != mIsImsRegistered.get()) {
+            mIsImsRegistered.set(registered);
+            handleStateChangedEventForHysteresisTimer();
+        }
+    }
+
+    private void handleCellularServiceStateChangedEvent(@NonNull ServiceState serviceState) {
+        int state = serviceState.getState();
+        if (mCellularServiceState.get() != state) {
+            mCellularServiceState.set(state);
+            handleStateChangedEventForHysteresisTimer();
+        }
+    }
+
+    private void reportEsosRecommenderDecision(boolean isDialerNotified) {
+        SatelliteStats.getInstance().onSatelliteSosMessageRecommender(
+                new SatelliteStats.SatelliteSosMessageRecommenderParams.Builder()
+                        .setDisplaySosMessageSent(isDialerNotified)
+                        .setCountOfTimerStarted(mCountOfTimerStarted)
+                        .setImsRegistered(mIsImsRegistered.get())
+                        .setCellularServiceState(mCellularServiceState.get())
+                        .build());
+    }
+
+    private void cleanUpResources() {
+        stopTimer();
+        if (mPhone != null) {
+            unregisterForInterestedStateChangedEvents(mPhone);
+            mPhone = null;
+        }
+        mEmergencyConnection = null;
+        mCountOfTimerStarted = 0;
+    }
+
+    private void registerForInterestedStateChangedEvents(@NonNull Phone phone) {
+        mSatelliteController.registerForSatelliteProvisionStateChanged(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mISatelliteProvisionStateCallback);
+        phone.registerForServiceStateChanged(this, EVENT_CELLULAR_SERVICE_STATE_CHANGED, null);
+        registerForImsRegistrationStateChanged(phone);
+    }
+
+    private void registerForImsRegistrationStateChanged(@NonNull Phone phone) {
+        ImsManager imsManager = (mImsManager != null) ? mImsManager : ImsManager.getInstance(
+                phone.getContext(), phone.getPhoneId());
+        try {
+            imsManager.addRegistrationCallback(mImsRegistrationCallback, this::post);
+        } catch (ImsException ex) {
+            loge("registerForImsRegistrationStateChanged: ex=" + ex);
+        }
+    }
+
+    private void unregisterForInterestedStateChangedEvents(@NonNull Phone phone) {
+        mSatelliteController.unregisterForSatelliteProvisionStateChanged(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mISatelliteProvisionStateCallback);
+        phone.unregisterForServiceStateChanged(this);
+        unregisterForImsRegistrationStateChanged(phone);
+    }
+
+    private void unregisterForImsRegistrationStateChanged(@NonNull Phone phone) {
+        ImsManager imsManager = (mImsManager != null) ? mImsManager : ImsManager.getInstance(
+                phone.getContext(), phone.getPhoneId());
+        imsManager.removeRegistrationListener(mImsRegistrationCallback);
+    }
+
+    private boolean isCellularAvailable() {
+        return (mCellularServiceState.get() == ServiceState.STATE_IN_SERVICE
+                || mCellularServiceState.get() == ServiceState.STATE_EMERGENCY_ONLY);
+    }
+
+    private void handleStateChangedEventForHysteresisTimer() {
+        if (!mIsImsRegistered.get() && !isCellularAvailable()) {
+            startTimer();
+        } else {
+            stopTimer();
+        }
+    }
+
+    private void startTimer() {
+        if (hasMessages(EVENT_TIME_OUT)) {
+            return;
+        }
+        sendMessageDelayed(obtainMessage(EVENT_TIME_OUT), mTimeoutMillis);
+        mCountOfTimerStarted++;
+    }
+
+    private void stopTimer() {
+        removeMessages(EVENT_TIME_OUT);
+    }
+
+    private static long getEmergencyCallToSosMsgHysteresisTimeoutMillis() {
+        return DeviceConfig.getLong(DeviceConfig.NAMESPACE_TELEPHONY,
+                EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS,
+                DEFAULT_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+    }
+
+    private boolean shouldTrackCall(int connectionState) {
+        /**
+         * An active connection state means both parties are connected to the call and can actively
+         * communicate. A disconnected connection state means the emergency call has ended. In both
+         * cases, we don't need to track the call anymore.
+         */
+        return (connectionState != Connection.STATE_ACTIVE
+                && connectionState != Connection.STATE_DISCONNECTED);
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
new file mode 100644
index 0000000..f11ca66
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.PointingInfo;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.stub.NTRadioTechnology;
+import android.telephony.satellite.stub.SatelliteError;
+import android.telephony.satellite.stub.SatelliteModemState;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.RILUtils;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Utils class for satellite service <-> framework conversions
+ */
+public class SatelliteServiceUtils {
+    private static final String TAG = "SatelliteServiceUtils";
+
+    /**
+     * Convert radio technology from service definition to framework definition.
+     * @param radioTechnology The NTRadioTechnology from the satellite service.
+     * @return The converted NTRadioTechnology for the framework.
+     */
+    @SatelliteManager.NTRadioTechnology
+    public static int fromSatelliteRadioTechnology(int radioTechnology) {
+        switch (radioTechnology) {
+            case NTRadioTechnology.NB_IOT_NTN:
+                return SatelliteManager.NT_RADIO_TECHNOLOGY_NB_IOT_NTN;
+            case NTRadioTechnology.NR_NTN:
+                return SatelliteManager.NT_RADIO_TECHNOLOGY_NR_NTN;
+            case NTRadioTechnology.EMTC_NTN:
+                return SatelliteManager.NT_RADIO_TECHNOLOGY_EMTC_NTN;
+            case NTRadioTechnology.PROPRIETARY:
+                return SatelliteManager.NT_RADIO_TECHNOLOGY_PROPRIETARY;
+            default:
+                loge("Received invalid radio technology: " + radioTechnology);
+                return SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN;
+        }
+    }
+
+    /**
+     * Convert satellite error from service definition to framework definition.
+     * @param error The SatelliteError from the satellite service.
+     * @return The converted SatelliteError for the framework.
+     */
+    @SatelliteManager.SatelliteError public static int fromSatelliteError(int error) {
+        switch (error) {
+            case SatelliteError.ERROR_NONE:
+                return SatelliteManager.SATELLITE_ERROR_NONE;
+            case SatelliteError.SATELLITE_ERROR:
+                return SatelliteManager.SATELLITE_ERROR;
+            case SatelliteError.SERVER_ERROR:
+                return SatelliteManager.SATELLITE_SERVER_ERROR;
+            case SatelliteError.SERVICE_ERROR:
+                return SatelliteManager.SATELLITE_SERVICE_ERROR;
+            case SatelliteError.MODEM_ERROR:
+                return SatelliteManager.SATELLITE_MODEM_ERROR;
+            case SatelliteError.NETWORK_ERROR:
+                return SatelliteManager.SATELLITE_NETWORK_ERROR;
+            case SatelliteError.INVALID_TELEPHONY_STATE:
+                return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+            case SatelliteError.INVALID_MODEM_STATE:
+                return SatelliteManager.SATELLITE_INVALID_MODEM_STATE;
+            case SatelliteError.INVALID_ARGUMENTS:
+                return SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
+            case SatelliteError.REQUEST_FAILED:
+                return SatelliteManager.SATELLITE_REQUEST_FAILED;
+            case SatelliteError.RADIO_NOT_AVAILABLE:
+                return SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE;
+            case SatelliteError.REQUEST_NOT_SUPPORTED:
+                return SatelliteManager.SATELLITE_REQUEST_NOT_SUPPORTED;
+            case SatelliteError.NO_RESOURCES:
+                return SatelliteManager.SATELLITE_NO_RESOURCES;
+            case SatelliteError.SERVICE_NOT_PROVISIONED:
+                return SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
+            case SatelliteError.SERVICE_PROVISION_IN_PROGRESS:
+                return SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS;
+            case SatelliteError.REQUEST_ABORTED:
+                return SatelliteManager.SATELLITE_REQUEST_ABORTED;
+            case SatelliteError.SATELLITE_ACCESS_BARRED:
+                return SatelliteManager.SATELLITE_ACCESS_BARRED;
+            case SatelliteError.NETWORK_TIMEOUT:
+                return SatelliteManager.SATELLITE_NETWORK_TIMEOUT;
+            case SatelliteError.SATELLITE_NOT_REACHABLE:
+                return SatelliteManager.SATELLITE_NOT_REACHABLE;
+            case SatelliteError.NOT_AUTHORIZED:
+                return SatelliteManager.SATELLITE_NOT_AUTHORIZED;
+        }
+        loge("Received invalid satellite service error: " + error);
+        return SatelliteManager.SATELLITE_SERVICE_ERROR;
+    }
+
+    /**
+     * Convert satellite modem state from service definition to framework definition.
+     * @param modemState The SatelliteModemState from the satellite service.
+     * @return The converted SatelliteModemState for the framework.
+     */
+    @SatelliteManager.SatelliteModemState
+    public static int fromSatelliteModemState(int modemState) {
+        switch (modemState) {
+            case SatelliteModemState.SATELLITE_MODEM_STATE_IDLE:
+                return SatelliteManager.SATELLITE_MODEM_STATE_IDLE;
+            case SatelliteModemState.SATELLITE_MODEM_STATE_LISTENING:
+                return SatelliteManager.SATELLITE_MODEM_STATE_LISTENING;
+            case SatelliteModemState.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
+                return SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
+            case SatelliteModemState.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING:
+                return SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING;
+            case SatelliteModemState.SATELLITE_MODEM_STATE_OFF:
+                return SatelliteManager.SATELLITE_MODEM_STATE_OFF;
+            case SatelliteModemState.SATELLITE_MODEM_STATE_UNAVAILABLE:
+                return SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
+            default:
+                loge("Received invalid modem state: " + modemState);
+                return SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
+        }
+    }
+
+    /**
+     * Convert SatelliteCapabilities from service definition to framework definition.
+     * @param capabilities The SatelliteCapabilities from the satellite service.
+     * @return The converted SatelliteCapabilities for the framework.
+     */
+    @Nullable public static SatelliteCapabilities fromSatelliteCapabilities(
+            @Nullable android.telephony.satellite.stub.SatelliteCapabilities capabilities) {
+        if (capabilities == null) return null;
+        int[] radioTechnologies = capabilities.supportedRadioTechnologies == null
+                ? new int[0] : capabilities.supportedRadioTechnologies;
+
+        Map<Integer, AntennaPosition> antennaPositionMap = new HashMap<>();
+        int[] antennaPositionKeys = capabilities.antennaPositionKeys;
+        AntennaPosition[] antennaPositionValues = capabilities.antennaPositionValues;
+        if (antennaPositionKeys != null && antennaPositionValues != null &&
+                antennaPositionKeys.length == antennaPositionValues.length) {
+            for(int i = 0; i < antennaPositionKeys.length; i++) {
+                antennaPositionMap.put(antennaPositionKeys[i], antennaPositionValues[i]);
+            }
+        }
+
+        return new SatelliteCapabilities(
+                Arrays.stream(radioTechnologies)
+                        .map(SatelliteServiceUtils::fromSatelliteRadioTechnology)
+                        .boxed().collect(Collectors.toSet()),
+                capabilities.isPointingRequired, capabilities.maxBytesPerOutgoingDatagram,
+                antennaPositionMap);
+    }
+
+    /**
+     * Convert PointingInfo from service definition to framework definition.
+     * @param pointingInfo The PointingInfo from the satellite service.
+     * @return The converted PointingInfo for the framework.
+     */
+    @Nullable public static PointingInfo fromPointingInfo(
+            android.telephony.satellite.stub.PointingInfo pointingInfo) {
+        if (pointingInfo == null) return null;
+        return new PointingInfo(pointingInfo.satelliteAzimuth, pointingInfo.satelliteElevation);
+    }
+
+    /**
+     * Convert SatelliteDatagram from service definition to framework definition.
+     * @param datagram The SatelliteDatagram from the satellite service.
+     * @return The converted SatelliteDatagram for the framework.
+     */
+    @Nullable public static SatelliteDatagram fromSatelliteDatagram(
+            android.telephony.satellite.stub.SatelliteDatagram datagram) {
+        if (datagram == null) return null;
+        byte[] data = datagram.data == null ? new byte[0] : datagram.data;
+        return new SatelliteDatagram(data);
+    }
+
+    /**
+     * Convert SatelliteDatagram from framework definition to service definition.
+     * @param datagram The SatelliteDatagram from the framework.
+     * @return The converted SatelliteDatagram for the satellite service.
+     */
+    @Nullable public static android.telephony.satellite.stub.SatelliteDatagram toSatelliteDatagram(
+            @Nullable SatelliteDatagram datagram) {
+        android.telephony.satellite.stub.SatelliteDatagram converted =
+                new android.telephony.satellite.stub.SatelliteDatagram();
+        converted.data = datagram.getSatelliteDatagram();
+        return converted;
+    }
+
+    /**
+     * Get the {@link SatelliteManager.SatelliteError} from the provided result.
+     *
+     * @param ar AsyncResult used to determine the error code.
+     * @param caller The satellite request.
+     *
+     * @return The {@link SatelliteManager.SatelliteError} error code from the request.
+     */
+    @SatelliteManager.SatelliteError public static int getSatelliteError(@NonNull AsyncResult ar,
+            @NonNull String caller) {
+        int errorCode;
+        if (ar.exception == null) {
+            errorCode = SatelliteManager.SATELLITE_ERROR_NONE;
+        } else {
+            errorCode = SatelliteManager.SATELLITE_ERROR;
+            if (ar.exception instanceof CommandException) {
+                CommandException.Error error = ((CommandException) ar.exception).getCommandError();
+                errorCode = RILUtils.convertToSatelliteError(error);
+                loge(caller + " CommandException: " + ar.exception);
+            } else if (ar.exception instanceof SatelliteManager.SatelliteException) {
+                errorCode = ((SatelliteManager.SatelliteException) ar.exception).getErrorCode();
+                loge(caller + " SatelliteException: " + ar.exception);
+            } else {
+                loge(caller + " unknown exception: " + ar.exception);
+            }
+        }
+        logd(caller + " error: " + errorCode);
+        return errorCode;
+    }
+
+    /**
+     * Get valid subscription id for satellite communication.
+     *
+     * @param subId The subscription id.
+     * @return input subId if the subscription is active else return default subscription id.
+     */
+    public static int getValidSatelliteSubId(int subId, @NonNull Context context) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            boolean isActive = SubscriptionManagerService.getInstance().isActiveSubId(subId,
+                    context.getOpPackageName(), context.getAttributionTag());
+
+            if (isActive) {
+                return subId;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        logd("getValidSatelliteSubId: use DEFAULT_SUBSCRIPTION_ID for subId=" + subId);
+        return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+    }
+
+    /**
+     * Return phone associated with phoneId 0.
+     *
+     * @return phone associated with phoneId 0 or {@code null} if it doesn't exist.
+     */
+    public static @Nullable Phone getPhone() {
+        return PhoneFactory.getPhone(0);
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
new file mode 100644
index 0000000..36ad250
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.DeviceConfig;
+import android.telephony.Rlog;
+import android.telephony.satellite.ISatelliteStateCallback;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.stub.ISatelliteGateway;
+import android.telephony.satellite.stub.SatelliteGatewayService;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.ExponentialBackoff;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This module is responsible for managing session state transition and inform listeners of modem
+ * state changed events accordingly.
+ */
+public class SatelliteSessionController extends StateMachine {
+    private static final String TAG = "SatelliteSessionController";
+    private static final boolean DBG = true;
+    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
+    private static final boolean DEBUG = !"user".equals(Build.TYPE);
+
+    /**
+     * The time duration in millis that the satellite will stay at listening mode to wait for the
+     * next incoming page before disabling listening mode when transitioning from sending mode.
+     */
+    public static final String SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS =
+            "satellite_stay_at_listening_from_sending_millis";
+    /**
+     * The default value of {@link #SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS}.
+     */
+    public static final long DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS = 180000;
+    /**
+     * The time duration in millis that the satellite will stay at listening mode to wait for the
+     * next incoming page before disabling listening mode when transitioning from receiving mode.
+     */
+    public static final String SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS =
+            "satellite_stay_at_listening_from_receiving_millis";
+    /**
+     * The default value of {@link #SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS}
+     */
+    public static final long DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS = 30000;
+    /**
+     * The default value of {@link #SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS},
+     * and {@link #SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS} for demo mode
+     */
+    public static final long DEMO_MODE_SATELLITE_STAY_AT_LISTENING_MILLIS = 3000;
+
+    private static final int EVENT_DATAGRAM_TRANSFER_STATE_CHANGED = 1;
+    private static final int EVENT_LISTENING_TIMER_TIMEOUT = 2;
+    private static final int EVENT_SATELLITE_ENABLED_STATE_CHANGED = 3;
+
+    private static final long REBIND_INITIAL_DELAY = 2 * 1000; // 2 seconds
+    private static final long REBIND_MAXIMUM_DELAY = 64 * 1000; // 1 minute
+    private static final int REBIND_MULTIPLIER = 2;
+    @NonNull private final ExponentialBackoff mExponentialBackoff;
+    @NonNull private final Object mLock = new Object();
+    @Nullable
+    private ISatelliteGateway mSatelliteGatewayService;
+    private String mSatelliteGatewayServicePackageName = "";
+    @Nullable private SatelliteGatewayServiceConnection mSatelliteGatewayServiceConnection;
+    private boolean mIsBound;
+    private boolean mIsBinding;
+
+    @NonNull private static SatelliteSessionController sInstance;
+
+    @NonNull private final Context mContext;
+    @NonNull private final SatelliteModemInterface mSatelliteModemInterface;
+    @NonNull private final UnavailableState mUnavailableState = new UnavailableState();
+    @NonNull private final PowerOffState mPowerOffState = new PowerOffState();
+    @NonNull private final IdleState mIdleState = new IdleState();
+    @NonNull private final TransferringState mTransferringState = new TransferringState();
+    @NonNull private final ListeningState mListeningState = new ListeningState();
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected AtomicBoolean mIsSendingTriggeredDuringTransferringState;
+    private long mSatelliteStayAtListeningFromSendingMillis;
+    private long mSatelliteStayAtListeningFromReceivingMillis;
+    private final ConcurrentHashMap<IBinder, ISatelliteStateCallback> mListeners;
+    @SatelliteManager.SatelliteModemState private int mCurrentState;
+    final boolean mIsSatelliteSupported;
+    private boolean mIsDemoMode = false;
+
+    /**
+     * @return The singleton instance of SatelliteSessionController.
+     */
+    public static SatelliteSessionController getInstance() {
+        if (sInstance == null) {
+            Log.e(TAG, "SatelliteSessionController was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the SatelliteSessionController singleton instance.
+     *
+     * @param context The Context for the SatelliteSessionController.
+     * @param looper The looper associated with the handler of this class.
+     * @param isSatelliteSupported Whether satellite is supported on the device.
+     * @return The singleton instance of SatelliteSessionController.
+     */
+    public static SatelliteSessionController make(
+            @NonNull Context context, @NonNull Looper looper, boolean isSatelliteSupported) {
+        if (sInstance == null) {
+            sInstance = new SatelliteSessionController(context, looper, isSatelliteSupported,
+                    SatelliteModemInterface.getInstance(),
+                    getSatelliteStayAtListeningFromSendingMillis(),
+                    getSatelliteStayAtListeningFromReceivingMillis());
+        } else {
+            if (isSatelliteSupported != sInstance.mIsSatelliteSupported) {
+                Rlog.e(TAG, "New satellite support state " + isSatelliteSupported
+                        + " is different from existing state " + sInstance.mIsSatelliteSupported
+                        + ". Ignore the new state.");
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create a SatelliteSessionController to manage satellite session.
+     *
+     * @param context The Context for the SatelliteSessionController.
+     * @param looper The looper associated with the handler of this class.
+     * @param isSatelliteSupported Whether satellite is supported on the device.
+     * @param satelliteModemInterface The singleton of SatelliteModemInterface.
+     * @param satelliteStayAtListeningFromSendingMillis The duration to stay at listening mode when
+     *                                                    transitioning from sending mode.
+     * @param satelliteStayAtListeningFromReceivingMillis The duration to stay at listening mode
+     *                                                    when transitioning from receiving mode.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected SatelliteSessionController(@NonNull Context context, @NonNull Looper looper,
+            boolean isSatelliteSupported,
+            @NonNull SatelliteModemInterface satelliteModemInterface,
+            long satelliteStayAtListeningFromSendingMillis,
+            long satelliteStayAtListeningFromReceivingMillis) {
+        super(TAG, looper);
+
+        mContext = context;
+        mSatelliteModemInterface = satelliteModemInterface;
+        mSatelliteStayAtListeningFromSendingMillis = satelliteStayAtListeningFromSendingMillis;
+        mSatelliteStayAtListeningFromReceivingMillis = satelliteStayAtListeningFromReceivingMillis;
+        mListeners = new ConcurrentHashMap<>();
+        mIsSendingTriggeredDuringTransferringState = new AtomicBoolean(false);
+        mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
+        mIsSatelliteSupported = isSatelliteSupported;
+        mExponentialBackoff = new ExponentialBackoff(REBIND_INITIAL_DELAY, REBIND_MAXIMUM_DELAY,
+                REBIND_MULTIPLIER, looper, () -> {
+            synchronized (mLock) {
+                if ((mIsBound && mSatelliteGatewayService != null) || mIsBinding) {
+                    return;
+                }
+            }
+            if (mSatelliteGatewayServiceConnection != null) {
+                synchronized (mLock) {
+                    mIsBound = false;
+                    mIsBinding = false;
+                }
+                unbindService();
+            }
+            bindService();
+        });
+
+        addState(mUnavailableState);
+        addState(mPowerOffState);
+        addState(mIdleState);
+        addState(mTransferringState);
+        addState(mListeningState, mTransferringState);
+        setInitialState(isSatelliteSupported);
+        start();
+    }
+
+    /**
+     * {@link DatagramController} uses this function to notify {@link SatelliteSessionController}
+     * that its datagram transfer state has changed.
+     *
+     * @param sendState The current datagram send state of {@link DatagramController}.
+     * @param receiveState The current datagram receive state of {@link DatagramController}.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void onDatagramTransferStateChanged(
+            @SatelliteManager.SatelliteDatagramTransferState int sendState,
+            @SatelliteManager.SatelliteDatagramTransferState int receiveState) {
+        sendMessage(EVENT_DATAGRAM_TRANSFER_STATE_CHANGED,
+                new DatagramTransferState(sendState, receiveState));
+        if (sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING) {
+            mIsSendingTriggeredDuringTransferringState.set(true);
+        }
+    }
+
+    /**
+     * {@link SatelliteController} uses this function to notify {@link SatelliteSessionController}
+     * that the satellite enabled state has changed.
+     *
+     * @param enabled {@code true} means enabled and {@code false} means disabled.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void onSatelliteEnabledStateChanged(boolean enabled) {
+        sendMessage(EVENT_SATELLITE_ENABLED_STATE_CHANGED, enabled);
+    }
+
+    /**
+     * Registers for modem state changed from satellite modem.
+     *
+     * @param callback The callback to handle the satellite modem state changed event.
+     */
+    public void registerForSatelliteModemStateChanged(@NonNull ISatelliteStateCallback callback) {
+        try {
+            callback.onSatelliteModemStateChanged(mCurrentState);
+            mListeners.put(callback.asBinder(), callback);
+        } catch (RemoteException ex) {
+            loge("registerForSatelliteModemStateChanged: Got RemoteException ex=" + ex);
+        }
+    }
+
+    /**
+     * Unregisters for modem state changed from satellite modem.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteModemStateChanged(ISatelliteStateCallback)}.
+     */
+    public void unregisterForSatelliteModemStateChanged(@NonNull ISatelliteStateCallback callback) {
+        mListeners.remove(callback.asBinder());
+    }
+
+    /**
+     * This API can be used by only CTS to update the timeout duration in milliseconds that
+     * satellite should stay at listening mode to wait for the next incoming page before disabling
+     * listening mode.
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
+        if (!isMockModemAllowed()) {
+            loge("Updating listening timeout duration is not allowed");
+            return false;
+        }
+
+        logd("setSatelliteListeningTimeoutDuration: timeoutMillis=" + timeoutMillis);
+        if (timeoutMillis == 0) {
+            mSatelliteStayAtListeningFromSendingMillis =
+                    getSatelliteStayAtListeningFromSendingMillis();
+            mSatelliteStayAtListeningFromReceivingMillis =
+                    getSatelliteStayAtListeningFromReceivingMillis();
+        } else {
+            mSatelliteStayAtListeningFromSendingMillis = timeoutMillis;
+            mSatelliteStayAtListeningFromReceivingMillis = timeoutMillis;
+        }
+
+        return true;
+    }
+
+    /**
+     * This API can be used by only CTS to update satellite gateway service package name.
+     *
+     * @param servicePackageName The package name of the satellite gateway service.
+     * @return {@code true} if the satellite gateway service is set successfully,
+     * {@code false} otherwise.
+     */
+    boolean setSatelliteGatewayServicePackageName(@Nullable String servicePackageName) {
+        if (!isMockModemAllowed()) {
+            loge("setSatelliteGatewayServicePackageName: modifying satellite gateway service "
+                    + "package name is not allowed");
+            return false;
+        }
+
+        logd("setSatelliteGatewayServicePackageName: config_satellite_gateway_service_package is "
+                + "updated, new packageName=" + servicePackageName);
+
+        if (servicePackageName == null || servicePackageName.equals("null")) {
+            mSatelliteGatewayServicePackageName = "";
+        } else {
+            mSatelliteGatewayServicePackageName = servicePackageName;
+        }
+
+        if (mSatelliteGatewayServiceConnection != null) {
+            synchronized (mLock) {
+                mIsBound = false;
+                mIsBinding = false;
+            }
+            unbindService();
+            bindService();
+        }
+        return true;
+    }
+    /**
+     * Adjusts listening timeout duration when demo mode is on
+     *
+     * @param isDemoMode {@code true} : The listening timeout durations will be set to
+     *                   {@link #DEMO_MODE_SATELLITE_STAY_AT_LISTENING_MILLIS}
+     *                   {@code false} : The listening timeout durations will be restored to
+     *                   production mode
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void setDemoMode(boolean isDemoMode) {
+        mIsDemoMode = isDemoMode;
+    }
+
+    private boolean isDemoMode() {
+        return mIsDemoMode;
+    }
+
+    private static class DatagramTransferState {
+        @SatelliteManager.SatelliteDatagramTransferState public int sendState;
+        @SatelliteManager.SatelliteDatagramTransferState public int receiveState;
+
+        DatagramTransferState(@SatelliteManager.SatelliteDatagramTransferState int sendState,
+                @SatelliteManager.SatelliteDatagramTransferState int receiveState) {
+            this.sendState = sendState;
+            this.receiveState = receiveState;
+        }
+    }
+
+    private class UnavailableState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd("Entering UnavailableState");
+            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            loge("UnavailableState: receive msg " + getWhatToString(msg.what) + " unexpectedly");
+            return HANDLED;
+        }
+    }
+
+    private class PowerOffState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd("Entering PowerOffState");
+
+            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_OFF;
+            mIsSendingTriggeredDuringTransferringState.set(false);
+            unbindService();
+            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+        }
+
+        @Override
+        public void exit() {
+            if (DBG) logd("Exiting PowerOffState");
+            logd("Attempting to bind to SatelliteGatewayService.");
+            bindService();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (DBG) log("PowerOffState: processing " + getWhatToString(msg.what));
+            switch (msg.what) {
+                case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
+                    handleSatelliteEnabledStateChanged((boolean) msg.obj);
+                    break;
+            }
+            // Ignore all unexpected events.
+            return HANDLED;
+        }
+
+        private void handleSatelliteEnabledStateChanged(boolean on) {
+            if (on) {
+                transitionTo(mIdleState);
+            }
+        }
+    }
+
+    private class IdleState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd("Entering IdleState");
+            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_IDLE;
+            mIsSendingTriggeredDuringTransferringState.set(false);
+            //Enable Cellular Modem scanning
+            mSatelliteModemInterface.enableCellularModemWhileSatelliteModeIsOn(true, null);
+            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (DBG) log("IdleState: processing " + getWhatToString(msg.what));
+            switch (msg.what) {
+                case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED:
+                    handleEventDatagramTransferStateChanged((DatagramTransferState) msg.obj);
+                    break;
+                case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
+                    handleSatelliteEnabledStateChanged(!(boolean) msg.obj, "IdleState");
+                    break;
+            }
+            // Ignore all unexpected events.
+            return HANDLED;
+        }
+
+        private void handleEventDatagramTransferStateChanged(
+                @NonNull DatagramTransferState datagramTransferState) {
+            if ((datagramTransferState.sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING)
+                    || (datagramTransferState.receiveState
+                    == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING)) {
+                transitionTo(mTransferringState);
+            }
+        }
+
+        @Override
+        public void exit() {
+            if (DBG) logd("Exiting IdleState");
+            //Disable Cellular Modem Scanning
+            mSatelliteModemInterface.enableCellularModemWhileSatelliteModeIsOn(false, null);
+        }
+    }
+
+    private class TransferringState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd("Entering TransferringState");
+            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
+            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (DBG) log("TransferringState: processing " + getWhatToString(msg.what));
+            switch (msg.what) {
+                case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED:
+                    handleEventDatagramTransferStateChanged((DatagramTransferState) msg.obj);
+                    return HANDLED;
+                case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
+                    handleSatelliteEnabledStateChanged(!(boolean) msg.obj, "TransferringState");
+                    break;
+            }
+            // Ignore all unexpected events.
+            return HANDLED;
+        }
+
+        private void handleEventDatagramTransferStateChanged(
+                @NonNull DatagramTransferState datagramTransferState) {
+            if (isSending(datagramTransferState.sendState) || isReceiving(
+                    datagramTransferState.receiveState)) {
+                // Stay at transferring state.
+            } else if ((datagramTransferState.sendState
+                    == SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED)
+                    || (datagramTransferState.receiveState
+                    == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED)) {
+                transitionTo(mIdleState);
+            } else {
+                transitionTo(mListeningState);
+            }
+        }
+    }
+
+    private class ListeningState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd("Entering ListeningState");
+
+            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_LISTENING;
+            long timeoutMillis = updateListeningMode(true);
+            sendMessageDelayed(EVENT_LISTENING_TIMER_TIMEOUT, timeoutMillis);
+            mIsSendingTriggeredDuringTransferringState.set(false);
+            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+        }
+
+        @Override
+        public void exit() {
+            removeMessages(EVENT_LISTENING_TIMER_TIMEOUT);
+            updateListeningMode(false);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (DBG) log("ListeningState: processing " + getWhatToString(msg.what));
+            switch (msg.what) {
+                case EVENT_LISTENING_TIMER_TIMEOUT:
+                    transitionTo(mIdleState);
+                    break;
+                case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED:
+                    handleEventDatagramTransferStateChanged((DatagramTransferState) msg.obj);
+                    break;
+                case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
+                    handleSatelliteEnabledStateChanged(!(boolean) msg.obj, "ListeningState");
+                    break;
+            }
+            // Ignore all unexpected events.
+            return HANDLED;
+        }
+
+        private long updateListeningMode(boolean enabled) {
+            long timeoutMillis;
+            if (mIsSendingTriggeredDuringTransferringState.get()) {
+                timeoutMillis = mSatelliteStayAtListeningFromSendingMillis;
+            } else {
+                timeoutMillis = mSatelliteStayAtListeningFromReceivingMillis;
+            }
+            mSatelliteModemInterface.requestSatelliteListeningEnabled(
+                    enabled, (int) timeoutMillis, null);
+            return timeoutMillis;
+        }
+
+        private void handleEventDatagramTransferStateChanged(
+                @NonNull DatagramTransferState datagramTransferState) {
+            if (datagramTransferState.sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING
+                    || datagramTransferState.receiveState
+                    == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING) {
+                transitionTo(mTransferringState);
+            }
+        }
+    }
+
+    /**
+     * @return the string for msg.what
+     */
+    @Override
+    protected String getWhatToString(int what) {
+        String whatString;
+        switch (what) {
+            case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED:
+                whatString = "EVENT_DATAGRAM_TRANSFER_STATE_CHANGED";
+                break;
+            case EVENT_LISTENING_TIMER_TIMEOUT:
+                whatString = "EVENT_LISTENING_TIMER_TIMEOUT";
+                break;
+            case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
+                whatString = "EVENT_SATELLITE_ENABLED_STATE_CHANGED";
+                break;
+            default:
+                whatString = "UNKNOWN EVENT " + what;
+        }
+        return whatString;
+    }
+
+    private void setInitialState(boolean isSatelliteSupported) {
+        if (isSatelliteSupported) {
+            setInitialState(mPowerOffState);
+        } else {
+            setInitialState(mUnavailableState);
+        }
+    }
+
+    private void notifyStateChangedEvent(@SatelliteManager.SatelliteModemState int state) {
+        List<ISatelliteStateCallback> toBeRemoved = new ArrayList<>();
+        mListeners.values().forEach(listener -> {
+            try {
+                listener.onSatelliteModemStateChanged(state);
+            } catch (RemoteException e) {
+                logd("notifyStateChangedEvent RemoteException: " + e);
+                toBeRemoved.add(listener);
+            }
+        });
+
+        toBeRemoved.forEach(listener -> {
+            mListeners.remove(listener.asBinder());
+        });
+    }
+
+    private void handleSatelliteEnabledStateChanged(boolean off, String caller) {
+        if (off) {
+            transitionTo(mPowerOffState);
+        } else {
+            loge(caller + ": Unexpected satellite radio powered-on state changed event");
+        }
+    }
+
+    private boolean isSending(@SatelliteManager.SatelliteDatagramTransferState int sendState) {
+        return (sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING
+                || sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS);
+    }
+
+    private boolean isReceiving(@SatelliteManager.SatelliteDatagramTransferState int receiveState) {
+        return (receiveState == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING
+                || receiveState == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS
+                || receiveState == SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE);
+    }
+
+    @NonNull
+    private String getSatelliteGatewayPackageName() {
+        if (!TextUtils.isEmpty(mSatelliteGatewayServicePackageName)) {
+            return mSatelliteGatewayServicePackageName;
+        }
+        return TextUtils.emptyIfNull(mContext.getResources().getString(
+                R.string.config_satellite_gateway_service_package));
+    }
+
+    private void bindService() {
+        synchronized (mLock) {
+            if (mIsBinding || mIsBound) return;
+            mIsBinding = true;
+        }
+        mExponentialBackoff.start();
+
+        String packageName = getSatelliteGatewayPackageName();
+        if (TextUtils.isEmpty(packageName)) {
+            loge("Unable to bind to the satellite gateway service because the package is"
+                    + " undefined.");
+            // Since the package name comes from static device configs, stop retry because
+            // rebind will continue to fail without a valid package name.
+            synchronized (mLock) {
+                mIsBinding = false;
+            }
+            mExponentialBackoff.stop();
+            return;
+        }
+        Intent intent = new Intent(SatelliteGatewayService.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+
+        mSatelliteGatewayServiceConnection = new SatelliteGatewayServiceConnection();
+        try {
+            boolean success = mContext.bindService(
+                    intent, mSatelliteGatewayServiceConnection, Context.BIND_AUTO_CREATE);
+            if (success) {
+                logd("Successfully bound to the satellite gateway service.");
+            } else {
+                synchronized (mLock) {
+                    mIsBinding = false;
+                }
+                mExponentialBackoff.notifyFailed();
+                loge("Error binding to the satellite gateway service. Retrying in "
+                        + mExponentialBackoff.getCurrentDelay() + " ms.");
+            }
+        } catch (Exception e) {
+            synchronized (mLock) {
+                mIsBinding = false;
+            }
+            mExponentialBackoff.notifyFailed();
+            loge("Exception binding to the satellite gateway service. Retrying in "
+                    + mExponentialBackoff.getCurrentDelay() + " ms. Exception: " + e);
+        }
+    }
+
+    private void unbindService() {
+        logd("unbindService");
+        mExponentialBackoff.stop();
+        mSatelliteGatewayService = null;
+        synchronized (mLock) {
+            mIsBinding = false;
+            mIsBound = false;
+        }
+        if (mSatelliteGatewayServiceConnection != null) {
+            mContext.unbindService(mSatelliteGatewayServiceConnection);
+            mSatelliteGatewayServiceConnection = null;
+        }
+    }
+    private class SatelliteGatewayServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            logd("onServiceConnected: ComponentName=" + name);
+            synchronized (mLock) {
+                mIsBound = true;
+                mIsBinding = false;
+            }
+            mSatelliteGatewayService = ISatelliteGateway.Stub.asInterface(service);
+            mExponentialBackoff.stop();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            loge("onServiceDisconnected: Waiting for reconnect.");
+            synchronized (mLock) {
+                mIsBinding = false;
+                mIsBound = false;
+            }
+            mSatelliteGatewayService = null;
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            loge("onBindingDied: Unbinding and rebinding service.");
+            synchronized (mLock) {
+                mIsBound = false;
+                mIsBinding = false;
+            }
+            unbindService();
+            mExponentialBackoff.start();
+        }
+    }
+
+    private boolean isMockModemAllowed() {
+        return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
+    }
+
+    private static long getSatelliteStayAtListeningFromSendingMillis() {
+        if (sInstance != null && sInstance.isDemoMode()) {
+            return DEMO_MODE_SATELLITE_STAY_AT_LISTENING_MILLIS;
+        } else {
+            return DeviceConfig.getLong(DeviceConfig.NAMESPACE_TELEPHONY,
+                    SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS,
+                    DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_SENDING_MILLIS);
+        }
+    }
+
+    private static long getSatelliteStayAtListeningFromReceivingMillis() {
+        if (sInstance != null && sInstance.isDemoMode()) {
+            return DEMO_MODE_SATELLITE_STAY_AT_LISTENING_MILLIS;
+        } else {
+            return DeviceConfig.getLong(DeviceConfig.NAMESPACE_TELEPHONY,
+                    SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS,
+                    DEFAULT_SATELLITE_STAY_AT_LISTENING_FROM_RECEIVING_MILLIS);
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
new file mode 100644
index 0000000..7a1de7c
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2023 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.satellite.metrics;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.metrics.SatelliteStats;
+
+/**
+ * Stats to log to satellite metrics
+ */
+public class ControllerMetricsStats {
+    private static final int ADD_COUNT = 1;
+    private static final String TAG = ControllerMetricsStats.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    private static ControllerMetricsStats sInstance;
+
+    private final Context mContext;
+    private SatelliteStats mSatelliteStats;
+
+    private long mSatelliteOnTimeMillis;
+    private int mBatteryLevelWhenServiceOn;
+    private boolean mIsSatelliteModemOn;
+    private Boolean mIsBatteryCharged = null;
+    private int mBatteryChargedStartTimeSec;
+    private int mTotalBatteryChargeTimeSec;
+
+    /**
+     * @return The singleton instance of ControllerMetricsStats.
+     */
+    public static ControllerMetricsStats getInstance() {
+        if (sInstance == null) {
+            loge("ControllerMetricsStats was not yet initialized.");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the ControllerMetricsStats singleton instance.
+     *
+     * @param context   The Context for the ControllerMetricsStats.
+     * @return          The singleton instance of ControllerMetricsStats.
+     */
+    public static ControllerMetricsStats make(@NonNull Context context) {
+        if (sInstance == null) {
+            sInstance = new ControllerMetricsStats(context);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the ControllerMetricsStats singleton instance, testing purpose only.
+     *
+     * @param context   The Context for the ControllerMetricsStats.
+     * @param satelliteStats SatelliteStats instance to test
+     * @return          The singleton instance of ControllerMetricsStats.
+     */
+    @VisibleForTesting
+    public static ControllerMetricsStats make(@NonNull Context context,
+            @NonNull SatelliteStats satelliteStats) {
+        if (sInstance == null) {
+            sInstance = new ControllerMetricsStats(context, satelliteStats);
+        }
+        return sInstance;
+    }
+
+    /**
+     * Create the ControllerMetricsStats to manage metrics report for
+     * {@link SatelliteStats.SatelliteControllerParams}
+     * @param context The Context for the ControllerMetricsStats.
+     */
+    ControllerMetricsStats(@NonNull Context context) {
+        mContext = context;
+        mSatelliteStats = SatelliteStats.getInstance();
+    }
+
+    /**
+     * Create the ControllerMetricsStats to manage metrics report for
+     * {@link SatelliteStats.SatelliteControllerParams}
+     *
+     * @param context           The Context for the ControllerMetricsStats.
+     * @param satelliteStats    SatelliteStats object used for testing purpose
+     */
+    @VisibleForTesting
+    protected ControllerMetricsStats(@NonNull Context context,
+            @NonNull SatelliteStats satelliteStats) {
+        mContext = context;
+        mSatelliteStats = satelliteStats;
+    }
+
+
+    /** Report a counter when an attempt for satellite service on is successfully done */
+    public void reportServiceEnablementSuccessCount() {
+        logd("reportServiceEnablementSuccessCount()");
+        mSatelliteStats.onSatelliteControllerMetrics(
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setCountOfSatelliteServiceEnablementsSuccess(ADD_COUNT)
+                        .build());
+    }
+
+    /** Report a counter when an attempt for satellite service on is failed */
+    public void reportServiceEnablementFailCount() {
+        logd("reportServiceEnablementSuccessCount()");
+        mSatelliteStats.onSatelliteControllerMetrics(
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setCountOfSatelliteServiceEnablementsFail(ADD_COUNT)
+                        .build());
+    }
+
+    /** Report a counter when an attempt for outgoing datagram is successfully done */
+    public void reportOutgoingDatagramSuccessCount(
+            @NonNull @SatelliteManager.DatagramType int datagramType) {
+        SatelliteStats.SatelliteControllerParams controllerParam;
+        if (datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramSuccess(ADD_COUNT)
+                    .setCountOfDatagramTypeSosSmsSuccess(ADD_COUNT)
+                    .build();
+        } else if (datagramType == SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramSuccess(ADD_COUNT)
+                    .setCountOfDatagramTypeLocationSharingSuccess(ADD_COUNT)
+                    .build();
+        } else { // datagramType == SatelliteManager.DATAGRAM_TYPE_UNKNOWN
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramSuccess(ADD_COUNT)
+                    .build();
+        }
+        logd("reportServiceEnablementSuccessCount(): " + controllerParam);
+        mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+    }
+
+    /** Report a counter when an attempt for outgoing datagram is failed */
+    public void reportOutgoingDatagramFailCount(
+            @NonNull @SatelliteManager.DatagramType int datagramType) {
+        SatelliteStats.SatelliteControllerParams controllerParam;
+        if (datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramFail(ADD_COUNT)
+                    .setCountOfDatagramTypeSosSmsFail(ADD_COUNT)
+                    .build();
+        } else if (datagramType == SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramFail(ADD_COUNT)
+                    .setCountOfDatagramTypeLocationSharingFail(ADD_COUNT)
+                    .build();
+        } else { // datagramType == SatelliteManager.DATAGRAM_TYPE_UNKNOWN
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfOutgoingDatagramFail(ADD_COUNT)
+                    .build();
+        }
+        logd("reportOutgoingDatagramFailCount(): " + controllerParam);
+        mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+    }
+
+    /** Report a counter when an attempt for incoming datagram is failed */
+    public void reportIncomingDatagramCount(
+            @NonNull @SatelliteManager.SatelliteError int result) {
+        SatelliteStats.SatelliteControllerParams controllerParam;
+        if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfIncomingDatagramSuccess(ADD_COUNT)
+                    .build();
+        } else {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfIncomingDatagramFail(ADD_COUNT)
+                    .build();
+        }
+        logd("reportIncomingDatagramCount(): " + controllerParam);
+        mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+    }
+
+    /** Report a counter when an attempt for de-provision is success or not */
+    public void reportProvisionCount(@NonNull @SatelliteManager.SatelliteError int result) {
+        SatelliteStats.SatelliteControllerParams controllerParam;
+        if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfProvisionSuccess(ADD_COUNT)
+                    .build();
+        } else {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfProvisionFail(ADD_COUNT)
+                    .build();
+        }
+        logd("reportProvisionCount(): " + controllerParam);
+        mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+    }
+
+    /** Report a counter when an attempt for de-provision is success or not */
+    public void reportDeprovisionCount(@NonNull @SatelliteManager.SatelliteError int result) {
+        SatelliteStats.SatelliteControllerParams controllerParam;
+        if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfDeprovisionSuccess(ADD_COUNT)
+                    .build();
+        } else {
+            controllerParam = new SatelliteStats.SatelliteControllerParams.Builder()
+                    .setCountOfDeprovisionFail(ADD_COUNT)
+                    .build();
+        }
+        logd("reportDeprovisionCount(): " + controllerParam);
+        mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+    }
+
+    /** Return the total service up time for satellite service */
+    @VisibleForTesting
+    public int captureTotalServiceUpTimeSec() {
+        long totalTimeMillis = getCurrentTime() - mSatelliteOnTimeMillis;
+        mSatelliteOnTimeMillis = 0;
+        return (int) (totalTimeMillis / 1000);
+    }
+
+    /** Return the total battery charge time while satellite service is on */
+    @VisibleForTesting
+    public int captureTotalBatteryChargeTimeSec() {
+        int totalTime = mTotalBatteryChargeTimeSec;
+        mTotalBatteryChargeTimeSec = 0;
+        return totalTime;
+    }
+
+    /** Capture the satellite service on time and register battery monitor */
+    public void onSatelliteEnabled() {
+        if (!isSatelliteModemOn()) {
+            mIsSatelliteModemOn = true;
+
+            startCaptureBatteryLevel();
+
+            // log the timestamp of the satellite modem power on
+            mSatelliteOnTimeMillis = getCurrentTime();
+
+            // register broadcast receiver for monitoring battery status change
+            IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+
+            logd("register BatteryStatusReceiver");
+            mContext.registerReceiver(mBatteryStatusReceiver, filter);
+        }
+    }
+
+    /** Capture the satellite service off time and de-register battery monitor */
+    public void onSatelliteDisabled() {
+        if (isSatelliteModemOn()) {
+            mIsSatelliteModemOn = false;
+
+            logd("unregister BatteryStatusReceiver");
+            mContext.unregisterReceiver(mBatteryStatusReceiver);
+
+            int totalServiceUpTime = captureTotalServiceUpTimeSec();
+            int batteryConsumptionPercent = captureTotalBatteryConsumptionPercent(mContext);
+            int totalBatteryChargeTime = captureTotalBatteryChargeTimeSec();
+
+            // report metrics about service up time and battery
+            SatelliteStats.SatelliteControllerParams controllerParam =
+                    new SatelliteStats.SatelliteControllerParams.Builder()
+                            .setTotalServiceUptimeSec(totalServiceUpTime)
+                            .setTotalBatteryConsumptionPercent(batteryConsumptionPercent)
+                            .setTotalBatteryChargedTimeSec(totalBatteryChargeTime)
+                            .build();
+            logd("onSatelliteDisabled(): " + controllerParam);
+            mSatelliteStats.onSatelliteControllerMetrics(controllerParam);
+        }
+    }
+
+    /** Log the total battery charging time when satellite service is on */
+    private void updateSatelliteBatteryChargeTime(boolean isCharged) {
+        logd("updateSatelliteBatteryChargeTime(" + isCharged + ")");
+        // update only when the charge state has changed
+        if (mIsBatteryCharged == null || isCharged != mIsBatteryCharged) {
+            mIsBatteryCharged = isCharged;
+
+            // When charged, log the start time of battery charging
+            if (isCharged) {
+                mBatteryChargedStartTimeSec = (int) (getCurrentTime() / 1000);
+                // When discharged, log the accumulated total battery charging time.
+            } else {
+                mTotalBatteryChargeTimeSec +=
+                        (int) (getCurrentTime() / 1000)
+                                - mBatteryChargedStartTimeSec;
+                mBatteryChargedStartTimeSec = 0;
+            }
+        }
+    }
+
+    /** Capture the battery level when satellite service is on */
+    @VisibleForTesting
+    public void startCaptureBatteryLevel() {
+        try {
+            BatteryManager batteryManager = mContext.getSystemService(BatteryManager.class);
+            mBatteryLevelWhenServiceOn =
+                    batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
+            logd("sBatteryLevelWhenServiceOn = " + mBatteryLevelWhenServiceOn);
+        } catch (NullPointerException e) {
+            loge("BatteryManager is null");
+        }
+    }
+
+    /** Capture the total consumption level when service is off */
+    @VisibleForTesting
+    public int captureTotalBatteryConsumptionPercent(Context context) {
+        try {
+            BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
+            int currentLevel =
+                    batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
+            return Math.max((mBatteryLevelWhenServiceOn - currentLevel), 0);
+        } catch (NullPointerException e) {
+            loge("BatteryManager is null");
+            return 0;
+        }
+    }
+
+    /** Receives the battery status whether it is in charging or not, update interval is 60 sec. */
+    private final BroadcastReceiver mBatteryStatusReceiver = new BroadcastReceiver() {
+        private long mLastUpdatedTime = 0;
+        private static final long UPDATE_INTERVAL = 60 * 1000;
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            long currentTime = getCurrentTime();
+            if (currentTime - mLastUpdatedTime > UPDATE_INTERVAL) {
+                mLastUpdatedTime = currentTime;
+                int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+                boolean isCharged = (status == BatteryManager.BATTERY_STATUS_CHARGING);
+                logd("Battery is charged(" + isCharged + ")");
+                updateSatelliteBatteryChargeTime(isCharged);
+            }
+        }
+    };
+
+    @VisibleForTesting
+    public boolean isSatelliteModemOn() {
+        return mIsSatelliteModemOn;
+    }
+
+    @VisibleForTesting
+    public long getCurrentTime() {
+        return System.currentTimeMillis();
+    }
+
+    private static void logd(@NonNull String log) {
+        if (DBG) {
+            Log.d(TAG, log);
+        }
+    }
+
+    private static void loge(@NonNull String log) {
+        Log.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java
new file mode 100644
index 0000000..38696aa
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 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.satellite.metrics;
+
+import android.annotation.NonNull;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+
+import com.android.internal.telephony.metrics.SatelliteStats;
+
+/**
+ * Stats to log to satellite metrics
+ */
+public class ProvisionMetricsStats {
+    private static final String TAG = ProvisionMetricsStats.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    private static ProvisionMetricsStats sInstance = null;
+
+    public static final int INVALID_TIME = -1;
+
+    private int mResultCode;
+    private int mProvisioningStartTimeSec;
+    private boolean mIsProvisionRequest;
+    private boolean mIsCanceled;
+
+    private ProvisionMetricsStats() {
+        initializeProvisionParams();
+    }
+
+    /**
+     * Returns the Singleton instance of ProvisionMetricsStats class.
+     * If an instance of the Singleton class has not been created,
+     * it creates a new instance and returns it. Otherwise, it returns
+     * the existing instance.
+     * @return the Singleton instance of ProvisionMetricsStats
+     */
+    public static ProvisionMetricsStats getOrCreateInstance() {
+        if (sInstance == null) {
+            logd("Create new ProvisionMetricsStats.");
+            sInstance = new ProvisionMetricsStats();
+        }
+        return sInstance;
+    }
+
+    /** Sets the resultCode for provision metrics */
+    public ProvisionMetricsStats setResultCode(@SatelliteManager.SatelliteError int error) {
+        mResultCode = error;
+        return this;
+    }
+
+    /** Sets the start time of provisioning */
+    public void setProvisioningStartTime() {
+        mProvisioningStartTimeSec = (int) (System.currentTimeMillis() / 1000);
+    }
+
+    /** Sets the isProvisionRequest to indicate whether provision or de-provision */
+    public ProvisionMetricsStats setIsProvisionRequest(boolean isProvisionRequest) {
+        mIsProvisionRequest = isProvisionRequest;
+        return this;
+    }
+
+    /** Sets the isCanceled to know whether the provision is canceled */
+    public ProvisionMetricsStats setIsCanceled(boolean isCanceled) {
+        mIsCanceled = isCanceled;
+        return this;
+    }
+
+    /** Report the provision metrics atoms to PersistAtomsStorage in telephony */
+    public void reportProvisionMetrics() {
+        SatelliteStats.SatelliteProvisionParams provisionParams =
+                new SatelliteStats.SatelliteProvisionParams.Builder()
+                        .setResultCode(mResultCode)
+                        .setProvisioningTimeSec((int)
+                                (System.currentTimeMillis() / 1000) - mProvisioningStartTimeSec)
+                        .setIsProvisionRequest(mIsProvisionRequest)
+                        .setIsCanceled(mIsCanceled)
+                        .build();
+        SatelliteStats.getInstance().onSatelliteProvisionMetrics(provisionParams);
+        logd(provisionParams.toString());
+        initializeProvisionParams();
+    }
+
+    private void initializeProvisionParams() {
+        mResultCode = -1;
+        mProvisioningStartTimeSec = INVALID_TIME;
+        mIsProvisionRequest = false;
+        mIsCanceled = false;
+    }
+
+    private static void logd(@NonNull String log) {
+        if (DBG) {
+            Log.d(TAG, log);
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
new file mode 100644
index 0000000..776ba64
--- /dev/null
+++ b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 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.satellite.metrics;
+
+import android.annotation.NonNull;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Log;
+
+import com.android.internal.telephony.metrics.SatelliteStats;
+
+/**
+ * Stats to log to satellite session metrics
+ */
+public class SessionMetricsStats {
+    private static final String TAG = SessionMetricsStats.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    private static SessionMetricsStats sInstance = null;
+    private @SatelliteManager.SatelliteError int mInitializationResult;
+    private @SatelliteManager.NTRadioTechnology int mRadioTechnology;
+
+    private SessionMetricsStats() {
+        initializeSessionMetricsParam();
+    }
+
+    /**
+     * Returns the Singleton instance of SessionMetricsStats class.
+     * If an instance of the Singleton class has not been created,
+     * it creates a new instance and returns it. Otherwise, it returns
+     * the existing instance.
+     * @return the Singleton instance of SessionMetricsStats
+     */
+    public static SessionMetricsStats getInstance() {
+        if (sInstance == null) {
+            loge("create new SessionMetricsStats.");
+            sInstance = new SessionMetricsStats();
+        }
+        return sInstance;
+    }
+
+    /** Sets the satellite initialization result */
+    public SessionMetricsStats setInitializationResult(
+            @SatelliteManager.SatelliteError int result) {
+        logd("setInitializationResult(" + result + ")");
+        mInitializationResult = result;
+        return this;
+    }
+
+    /** Sets the satellite ratio technology */
+    public SessionMetricsStats setRadioTechnology(
+            @SatelliteManager.NTRadioTechnology int radioTechnology) {
+        logd("setRadioTechnology(" + radioTechnology + ")");
+        mRadioTechnology = radioTechnology;
+        return this;
+    }
+
+    /** Report the session metrics atoms to PersistAtomsStorage in telephony */
+    public void reportSessionMetrics() {
+        SatelliteStats.SatelliteSessionParams sessionParams =
+                new SatelliteStats.SatelliteSessionParams.Builder()
+                        .setSatelliteServiceInitializationResult(mInitializationResult)
+                        .setSatelliteTechnology(mRadioTechnology)
+                        .build();
+        logd(sessionParams.toString());
+        SatelliteStats.getInstance().onSatelliteSessionMetrics(sessionParams);
+        initializeSessionMetricsParam();
+    }
+
+    private void initializeSessionMetricsParam() {
+        mInitializationResult = SatelliteManager.SATELLITE_ERROR_NONE;
+        mRadioTechnology = SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN;
+    }
+
+    private static void logd(@NonNull String log) {
+        if (DBG) {
+            Log.d(TAG, log);
+        }
+    }
+
+    private static void loge(@NonNull String log) {
+        Log.e(TAG, log);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
index 665ba97..b90dc5e 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
@@ -81,7 +81,7 @@
  * to the database should go through {@link SubscriptionManagerService}.
  */
 public class SubscriptionDatabaseManager extends Handler {
-    private static final String LOG_TAG = "SDM";
+    private static final String LOG_TAG = "SDMGR";
 
     /** Whether enabling verbose debugging message or not. */
     private static final boolean VDBG = false;
@@ -91,7 +91,6 @@
 
     /** The mapping from {@link SimInfo} table to {@link SubscriptionInfoInternal} get methods. */
     private static final Map<String, Function<SubscriptionInfoInternal, ?>>
-            // TODO: Support SimInfo.COLUMN_CB_XXX which are still used by wear.
             SUBSCRIPTION_GET_METHOD_MAP = Map.ofEntries(
             new AbstractMap.SimpleImmutableEntry<>(
                     SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
@@ -148,6 +147,42 @@
                     SimInfo.COLUMN_IS_REMOVABLE,
                     SubscriptionInfoInternal::getRemovableEmbedded),
             new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastExtremeThreatAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastSevereThreatAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_AMBER_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastAmberAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_EMERGENCY_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastEmergencyAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_SOUND_DURATION,
+                    SubscriptionInfoInternal::getCellBroadcastAlertSoundDuration),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL,
+                    SubscriptionInfoInternal::getCellBroadcastAlertReminderInterval),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_VIBRATE,
+                    SubscriptionInfoInternal::getCellBroadcastAlertVibrationEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_SPEECH,
+                    SubscriptionInfoInternal::getCellBroadcastAlertSpeechEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ETWS_TEST_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastEtwsTestAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_CHANNEL_50_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastAreaInfoMessageEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_CMAS_TEST_ALERT,
+                    SubscriptionInfoInternal::getCellBroadcastTestAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_OPT_OUT_DIALOG,
+                    SubscriptionInfoInternal::getCellBroadcastOptOutDialogEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
                     SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
                     SubscriptionInfoInternal::getEnhanced4GModeEnabled),
             new AbstractMap.SimpleImmutableEntry<>(
@@ -267,6 +302,42 @@
                     SimInfo.COLUMN_IS_REMOVABLE,
                     SubscriptionDatabaseManager::setRemovableEmbedded),
             new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastExtremeThreatAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastSevereThreatAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_AMBER_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastAmberAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_EMERGENCY_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastEmergencyAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_SOUND_DURATION,
+                    SubscriptionDatabaseManager::setCellBroadcastAlertSoundDuration),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL,
+                    SubscriptionDatabaseManager::setCellBroadcastAlertReminderInterval),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_VIBRATE,
+                    SubscriptionDatabaseManager::setCellBroadcastAlertVibrationEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ALERT_SPEECH,
+                    SubscriptionDatabaseManager::setCellBroadcastAlertSpeechEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_ETWS_TEST_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastEtwsTestAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_CHANNEL_50_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastAreaInfoMessageEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_CMAS_TEST_ALERT,
+                    SubscriptionDatabaseManager::setCellBroadcastTestAlertEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
+                    SimInfo.COLUMN_CB_OPT_OUT_DIALOG,
+                    SubscriptionDatabaseManager::setCellBroadcastOptOutDialogEnabled),
+            new AbstractMap.SimpleImmutableEntry<>(
                     SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
                     SubscriptionDatabaseManager::setEnhanced4GModeEnabled),
             new AbstractMap.SimpleImmutableEntry<>(
@@ -449,18 +520,6 @@
             SimInfo.COLUMN_MCC,
             SimInfo.COLUMN_MNC,
             SimInfo.COLUMN_SIM_PROVISIONING_STATUS,
-            SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT,
-            SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT,
-            SimInfo.COLUMN_CB_AMBER_ALERT,
-            SimInfo.COLUMN_CB_EMERGENCY_ALERT,
-            SimInfo.COLUMN_CB_ALERT_SOUND_DURATION,
-            SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL,
-            SimInfo.COLUMN_CB_ALERT_VIBRATE,
-            SimInfo.COLUMN_CB_ALERT_SPEECH,
-            SimInfo.COLUMN_CB_ETWS_TEST_ALERT,
-            SimInfo.COLUMN_CB_CHANNEL_50_ALERT,
-            SimInfo.COLUMN_CB_CMAS_TEST_ALERT,
-            SimInfo.COLUMN_CB_OPT_OUT_DIALOG,
             SimInfo.COLUMN_IS_METERED,
             SimInfo.COLUMN_DATA_ENABLED_OVERRIDE_RULES,
             SimInfo.COLUMN_ALLOWED_NETWORK_TYPES
@@ -505,8 +564,9 @@
     private final Map<Integer, SubscriptionInfoInternal> mAllSubscriptionInfoInternalCache =
             new HashMap<>(16);
 
-    /** Whether database has been loaded into the cache after boot up. */
-    private boolean mDatabaseLoaded = false;
+    /** Whether database has been initialized after boot up. */
+    @GuardedBy("this")
+    private boolean mDatabaseInitialized = false;
 
     /**
      * This is the callback used for listening events from {@link SubscriptionDatabaseManager}.
@@ -542,9 +602,9 @@
         }
 
         /**
-         * Called when database has been loaded into the cache.
+         * Called when database has been initialized.
          */
-        public abstract void onDatabaseLoaded();
+        public abstract void onInitialized();
 
         /**
          * Called when subscription changed.
@@ -552,14 +612,6 @@
          * @param subId The subscription id.
          */
         public abstract void onSubscriptionChanged(int subId);
-
-        /**
-         * Called when {@link SubscriptionInfoInternal#areUiccApplicationsEnabled()}
-         * changed.
-         *
-         * @param subId The subscription id.
-         */
-        public abstract void onUiccApplicationsEnabled(int subId);
     }
 
     /**
@@ -578,7 +630,7 @@
         mUiccController = UiccController.getInstance();
         mAsyncMode = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_subscription_database_async_update);
-        loadFromDatabase();
+        initializeDatabase();
     }
 
     /**
@@ -728,6 +780,7 @@
         if (uri != null && uri.getLastPathSegment() != null) {
             int subId = Integer.parseInt(uri.getLastPathSegment());
             if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                logv("insertNewRecordIntoDatabaseSync: contentValues=" + contentValues);
                 logl("insertNewRecordIntoDatabaseSync: Successfully added subscription. subId="
                         + uri.getLastPathSegment());
                 return subId;
@@ -757,9 +810,12 @@
                     + "insert. subInfo=" + subInfo);
         }
 
-        if (!mDatabaseLoaded) {
-            throw new IllegalStateException("Database has not been loaded. Can't insert new "
-                    + "record at this point.");
+        synchronized (this) {
+            if (!mDatabaseInitialized) {
+                throw new IllegalStateException(
+                        "Database has not been initialized. Can't insert new "
+                                + "record at this point.");
+            }
         }
 
         int subId;
@@ -826,10 +882,12 @@
     private int updateDatabase(int subId, @NonNull ContentValues contentValues) {
         logv("updateDatabase: prepare to update sub " + subId);
 
-        if (!mDatabaseLoaded) {
-            logel("updateDatabase: Database has not been loaded. Can't update database at this "
-                    + "point. contentValues=" + contentValues);
-            return 0;
+        synchronized (this) {
+            if (!mDatabaseInitialized) {
+                logel("updateDatabase: Database has not been initialized. Can't update database at "
+                        + "this point. contentValues=" + contentValues);
+                return 0;
+            }
         }
 
         if (mAsyncMode) {
@@ -911,10 +969,6 @@
                             mAllSubscriptionInfoInternalCache.put(id, builder.build());
                             mCallback.invokeFromExecutor(()
                                     -> mCallback.onSubscriptionChanged(subId));
-                            if (columnName.equals(SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED)) {
-                                mCallback.invokeFromExecutor(()
-                                        -> mCallback.onUiccApplicationsEnabled(subId));
-                            }
                         }
                     }
                 }
@@ -949,10 +1003,6 @@
             if (updateDatabase(subId, createDeltaContentValues(oldSubInfo, newSubInfo)) > 0) {
                 mAllSubscriptionInfoInternalCache.put(subId, newSubInfo);
                 mCallback.invokeFromExecutor(() -> mCallback.onSubscriptionChanged(subId));
-                if (oldSubInfo.areUiccApplicationsEnabled()
-                        != newSubInfo.areUiccApplicationsEnabled()) {
-                    mCallback.invokeFromExecutor(() -> mCallback.onUiccApplicationsEnabled(subId));
-                }
             }
         } finally {
             mReadWriteLock.writeLock().unlock();
@@ -1221,8 +1271,8 @@
         try {
             SubscriptionInfoInternal subInfoCache = mAllSubscriptionInfoInternalCache.get(subId);
             if (subInfoCache == null) {
-                throw new IllegalArgumentException("Subscription doesn't exist. subId=" + subId
-                        + ", columnName=cardId");
+                throw new IllegalArgumentException("setCardId: Subscription doesn't exist. subId="
+                        + subId);
             }
             mAllSubscriptionInfoInternalCache.put(subId,
                     new SubscriptionInfoInternal.Builder(subInfoCache)
@@ -1297,6 +1347,180 @@
     }
 
     /**
+     * Set whether cell broadcast extreme threat alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isExtremeThreatAlertEnabled whether cell broadcast extreme threat alert is enabled by
+     * the user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastExtremeThreatAlertEnabled(int subId,
+            int isExtremeThreatAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT,
+                isExtremeThreatAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastExtremeThreatAlertEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast severe threat alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isSevereThreatAlertEnabled whether cell broadcast severe threat alert is enabled by
+     * the user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastSevereThreatAlertEnabled(int subId,
+            int isSevereThreatAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT,
+                isSevereThreatAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastSevereThreatAlertEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast amber alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isAmberAlertEnabled whether cell broadcast amber alert is enabled by
+     * the user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAmberAlertEnabled(int subId, int isAmberAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_AMBER_ALERT, isAmberAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAmberAlertEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast emergency alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isEmergencyAlertEnabled whether cell broadcast emergency alert is enabled by
+     * the user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastEmergencyAlertEnabled(int subId,
+            int isEmergencyAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_EMERGENCY_ALERT,
+                isEmergencyAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastEmergencyAlertEnabled);
+    }
+
+    /**
+     * Set cell broadcast alert sound duration.
+     *
+     * @param subId Subscription id.
+     * @param alertSoundDuration Alert sound duration in seconds.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAlertSoundDuration(int subId, int alertSoundDuration) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_ALERT_SOUND_DURATION,
+                alertSoundDuration,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAlertSoundDuration);
+    }
+
+    /**
+     * Set cell broadcast alert reminder interval.
+     *
+     * @param subId Subscription id.
+     * @param reminderInterval Alert reminder interval in milliseconds.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAlertReminderInterval(int subId, int reminderInterval) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL,
+                reminderInterval,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAlertReminderInterval);
+    }
+
+    /**
+     * Set whether cell broadcast alert vibration is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isAlertVibrationEnabled whether cell broadcast alert vibration is enabled by the user
+     * or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAlertVibrationEnabled(int subId, int isAlertVibrationEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_ALERT_VIBRATE, isAlertVibrationEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAlertVibrationEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast alert speech is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isAlertSpeechEnabled whether cell broadcast alert speech is enabled by the user or
+     * not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAlertSpeechEnabled(int subId, int isAlertSpeechEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_ALERT_SPEECH, isAlertSpeechEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAlertSpeechEnabled);
+    }
+
+    /**
+     * Set whether ETWS test alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isEtwsTestAlertEnabled whether cell broadcast ETWS test alert is enabled by the user
+     * or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastEtwsTestAlertEnabled(int subId, int isEtwsTestAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_ETWS_TEST_ALERT,
+                isEtwsTestAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastEtwsTestAlertEnabled);
+    }
+
+    /**
+     * Set whether area info message is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isAreaInfoMessageEnabled whether cell broadcast area info message is enabled by the
+     * user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastAreaInfoMessageEnabled(int subId, int isAreaInfoMessageEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_CHANNEL_50_ALERT,
+                isAreaInfoMessageEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastAreaInfoMessageEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast test alert is enabled by the user or not.
+     *
+     * @param subId Subscription id.
+     * @param isTestAlertEnabled whether cell broadcast test alert is enabled by the user or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastTestAlertEnabled(int subId, int isTestAlertEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_CMAS_TEST_ALERT, isTestAlertEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastTestAlertEnabled);
+    }
+
+    /**
+     * Set whether cell broadcast opt-out dialog should be shown or not.
+     *
+     * @param subId Subscription id.
+     * @param isOptOutDialogEnabled whether cell broadcast opt-out dialog should be shown or not.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
+     */
+    public void setCellBroadcastOptOutDialogEnabled(int subId, int isOptOutDialogEnabled) {
+        writeDatabaseAndCacheHelper(subId, SimInfo.COLUMN_CB_OPT_OUT_DIALOG, isOptOutDialogEnabled,
+                SubscriptionInfoInternal.Builder::setCellBroadcastOptOutDialogEnabled);
+    }
+
+    /**
      * Set whether enhanced 4G mode is enabled by the user or not.
      *
      * @param subId Subscription id.
@@ -1764,39 +1988,104 @@
     }
 
     /**
-     * Load the entire database into the cache.
+     * Set whether group of the subscription is disabled. This is only useful if it's a grouped
+     * opportunistic subscription. In this case, if all primary (non-opportunistic)
+     * subscriptions in the group are deactivated (unplugged pSIM or deactivated eSIM profile),
+     * we should disable this opportunistic subscription.
+     *
+     * @param subId Subscription id.
+     * @param isGroupDisabled if group of the subscription is disabled.
+     *
+     * @throws IllegalArgumentException if the subscription does not exist.
      */
-    private void loadFromDatabase() {
-        // Perform the task in the handler thread.
-        Runnable r = () -> {
-            try (Cursor cursor = mContext.getContentResolver().query(
-                    SimInfo.CONTENT_URI, null, null, null, null)) {
-                mReadWriteLock.writeLock().lock();
-                try {
-                    mAllSubscriptionInfoInternalCache.clear();
-                    while (cursor != null && cursor.moveToNext()) {
-                        SubscriptionInfoInternal subInfo = createSubscriptionInfoFromCursor(cursor);
-                        if (subInfo != null) {
-                            mAllSubscriptionInfoInternalCache
-                                    .put(subInfo.getSubscriptionId(), subInfo);
-                        }
-                    }
-                    mDatabaseLoaded = true;
-                    mCallback.invokeFromExecutor(mCallback::onDatabaseLoaded);
-                    log("Loaded " + mAllSubscriptionInfoInternalCache.size()
-                            + " records from the subscription database.");
-                } finally {
-                    mReadWriteLock.writeLock().unlock();
-                }
-            }
-        };
+    public void setGroupDisabled(int subId, boolean isGroupDisabled) {
+        // group disabled does not have a corresponding SimInfo column. So we only update the cache.
 
+        // Grab the write lock so no other threads can read or write the cache.
+        mReadWriteLock.writeLock().lock();
+        try {
+            SubscriptionInfoInternal subInfoCache = mAllSubscriptionInfoInternalCache.get(subId);
+            if (subInfoCache == null) {
+                throw new IllegalArgumentException("setGroupDisabled: Subscription doesn't exist. "
+                        + "subId=" + subId);
+            }
+            mAllSubscriptionInfoInternalCache.put(subId,
+                    new SubscriptionInfoInternal.Builder(subInfoCache)
+                            .setGroupDisabled(isGroupDisabled).build());
+        } finally {
+            mReadWriteLock.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Reload the database from content provider to the cache.
+     */
+    public void reloadDatabase() {
+        if (mAsyncMode) {
+            post(this::loadDatabaseInternal);
+        } else {
+            loadDatabaseInternal();
+        }
+    }
+
+    /**
+     * Load the database from content provider to the cache.
+     */
+    private void loadDatabaseInternal() {
+        log("loadDatabaseInternal");
+        try (Cursor cursor = mContext.getContentResolver().query(
+                SimInfo.CONTENT_URI, null, null, null, null)) {
+            mReadWriteLock.writeLock().lock();
+            try {
+                Map<Integer, SubscriptionInfoInternal> newAllSubscriptionInfoInternalCache =
+                        new HashMap<>();
+                boolean changed = false;
+                while (cursor != null && cursor.moveToNext()) {
+                    SubscriptionInfoInternal subInfo = createSubscriptionInfoFromCursor(cursor);
+                    newAllSubscriptionInfoInternalCache.put(subInfo.getSubscriptionId(), subInfo);
+                    if (!Objects.equals(mAllSubscriptionInfoInternalCache
+                            .get(subInfo.getSubscriptionId()), subInfo)) {
+                        mCallback.invokeFromExecutor(() -> mCallback.onSubscriptionChanged(
+                                subInfo.getSubscriptionId()));
+                        changed = true;
+                    }
+                }
+
+                if (changed) {
+                    mAllSubscriptionInfoInternalCache.clear();
+                    mAllSubscriptionInfoInternalCache.putAll(newAllSubscriptionInfoInternalCache);
+
+                    logl("Loaded " + mAllSubscriptionInfoInternalCache.size()
+                            + " records from the subscription database.");
+                    mAllSubscriptionInfoInternalCache.forEach(
+                            (subId, subInfo) -> log("  " + subInfo.toString()));
+                }
+            } finally {
+                mReadWriteLock.writeLock().unlock();
+            }
+        }
+    }
+
+    /**
+     * Initialize the database cache. Load the entire database into the cache.
+     */
+    private void initializeDatabase() {
         if (mAsyncMode) {
             // Load the database asynchronously.
-            post(r);
+            post(() -> {
+                synchronized (this) {
+                    loadDatabaseInternal();
+                    mDatabaseInitialized = true;
+                    mCallback.invokeFromExecutor(mCallback::onInitialized);
+                }
+            });
         } else {
             // Load the database synchronously.
-            r.run();
+            synchronized (this) {
+                loadDatabaseInternal();
+                mDatabaseInitialized = true;
+                mCallback.invokeFromExecutor(mCallback::onInitialized);
+            }
         }
     }
 
@@ -1807,7 +2096,7 @@
      *
      * @return The subscription info from a single database record.
      */
-    @Nullable
+    @NonNull
     private SubscriptionInfoInternal createSubscriptionInfoFromCursor(@NonNull Cursor cursor) {
         SubscriptionInfoInternal.Builder builder = new SubscriptionInfoInternal.Builder();
         int id = cursor.getInt(cursor.getColumnIndexOrThrow(
@@ -1865,6 +2154,30 @@
         builder.setCardId(publicCardId)
                 .setRemovableEmbedded(cursor.getInt(cursor.getColumnIndexOrThrow(
                         SimInfo.COLUMN_IS_REMOVABLE)))
+                .setCellBroadcastExtremeThreatAlertEnabled(cursor.getInt(cursor
+                        .getColumnIndexOrThrow(SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT)))
+                .setCellBroadcastSevereThreatAlertEnabled(cursor.getInt(cursor
+                        .getColumnIndexOrThrow(SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT)))
+                .setCellBroadcastAmberAlertEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_AMBER_ALERT)))
+                .setCellBroadcastEmergencyAlertEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_EMERGENCY_ALERT)))
+                .setCellBroadcastAlertSoundDuration(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_ALERT_SOUND_DURATION)))
+                .setCellBroadcastAlertReminderInterval(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL)))
+                .setCellBroadcastAlertVibrationEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_ALERT_VIBRATE)))
+                .setCellBroadcastAlertSpeechEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_ALERT_SPEECH)))
+                .setCellBroadcastEtwsTestAlertEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_ETWS_TEST_ALERT)))
+                .setCellBroadcastAreaInfoMessageEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_CHANNEL_50_ALERT)))
+                .setCellBroadcastTestAlertEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_CMAS_TEST_ALERT)))
+                .setCellBroadcastOptOutDialogEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
+                        SimInfo.COLUMN_CB_OPT_OUT_DIALOG)))
                 .setEnhanced4GModeEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
                         SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED)))
                 .setVideoTelephonyEnabled(cursor.getInt(cursor.getColumnIndexOrThrow(
@@ -2005,12 +2318,6 @@
     }
 
     /**
-     * @return {@code true} if the database has been loaded into the cache.
-     */
-    public boolean isDatabaseLoaded() {
-        return mDatabaseLoaded;
-    }
-    /**
      * Log debug messages.
      *
      * @param s debug messages
@@ -2058,7 +2365,7 @@
     }
 
     /**
-     * Dump the state of {@link SubscriptionManagerService}.
+     * Dump the state of {@link SubscriptionDatabaseManager}.
      *
      * @param fd File descriptor
      * @param printWriter Print writer
@@ -2067,11 +2374,27 @@
     public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter printWriter,
             @NonNull String[] args) {
         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(SubscriptionManagerService.class.getSimpleName() + ":");
+        pw.println(SubscriptionDatabaseManager.class.getSimpleName() + ":");
         pw.increaseIndent();
         pw.println("All subscriptions:");
         pw.increaseIndent();
-        mAllSubscriptionInfoInternalCache.forEach((subId, subInfo) -> pw.println(subInfo));
+        mReadWriteLock.readLock().lock();
+        try {
+            mAllSubscriptionInfoInternalCache.forEach((subId, subInfo) -> pw.println(subInfo));
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+        pw.decreaseIndent();
+        pw.println();
+        pw.println("mAsyncMode=" + mAsyncMode);
+        synchronized (this) {
+            pw.println("mDatabaseInitialized=" + mDatabaseInitialized);
+        }
+        pw.println("mReadWriteLock=" + mReadWriteLock);
+        pw.println();
+        pw.println("Local log:");
+        pw.increaseIndent();
+        mLocalLog.dump(fd, printWriter, args);
         pw.decreaseIndent();
         pw.decreaseIndent();
     }
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
index 0616c14..b917698 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
@@ -191,6 +191,66 @@
     private final int mIsRemovableEmbedded;
 
     /**
+     * Whether cell broadcast extreme threat alert is enabled by the user or not.
+     */
+    private int mIsExtremeThreatAlertEnabled;
+
+    /**
+     * Whether cell broadcast severe threat alert is enabled by the user or not.
+     */
+    private int mIsSevereThreatAlertEnabled;
+
+    /**
+     * Whether cell broadcast amber alert is enabled by the user or not.
+     */
+    private int mIsAmberAlertEnabled;
+
+    /**
+     * Whether cell broadcast emergency alert is enabled by the user or not.
+     */
+    private int mIsEmergencyAlertEnabled;
+
+    /**
+     * Cell broadcast alert sound duration in seconds.
+     */
+    private int mAlertSoundDuration;
+
+    /**
+     * Cell broadcast alert reminder interval in minutes.
+     */
+    private int mReminderInterval;
+
+    /**
+     * Whether cell broadcast alert vibration is enabled by the user or not.
+     */
+    private int mIsAlertVibrationEnabled;
+
+    /**
+     * Whether cell broadcast alert speech is enabled by the user or not.
+     */
+    private int mIsAlertSpeechEnabled;
+
+    /**
+     * Whether ETWS test alert is enabled by the user or not.
+     */
+    private int mIsEtwsTestAlertEnabled;
+
+    /**
+     * Whether area info message is enabled by the user or not.
+     */
+    private int mIsAreaInfoMessageEnabled;
+
+    /**
+     * Whether cell broadcast test alert is enabled by the user or not.
+     */
+    private int mIsTestAlertEnabled;
+
+    /**
+     * Whether cell broadcast opt-out dialog should be shown or not.
+     */
+    private int mIsOptOutDialogEnabled;
+
+    /**
      * Whether enhanced 4G mode is enabled by the user or not. It is intended to use integer to fit
      * the database format.
      */
@@ -420,6 +480,18 @@
         this.mNativeAccessRules = builder.mNativeAccessRules;
         this.mCarrierConfigAccessRules = builder.mCarrierConfigAccessRules;
         this.mIsRemovableEmbedded = builder.mIsRemovableEmbedded;
+        this.mIsExtremeThreatAlertEnabled = builder.mIsExtremeThreatAlertEnabled;
+        this.mIsSevereThreatAlertEnabled = builder.mIsSevereThreatAlertEnabled;
+        this.mIsAmberAlertEnabled = builder.mIsAmberAlertEnabled;
+        this.mIsEmergencyAlertEnabled = builder.mIsEmergencyAlertEnabled;
+        this.mAlertSoundDuration = builder.mAlertSoundDuration;
+        this.mReminderInterval = builder.mReminderInterval;
+        this.mIsAlertVibrationEnabled = builder.mIsAlertVibrationEnabled;
+        this.mIsAlertSpeechEnabled = builder.mIsAlertSpeechEnabled;
+        this.mIsEtwsTestAlertEnabled = builder.mIsEtwsTestAlertEnabled;
+        this.mIsAreaInfoMessageEnabled = builder.mIsAreaInfoMessageEnabled;
+        this.mIsTestAlertEnabled = builder.mIsTestAlertEnabled;
+        this.mIsOptOutDialogEnabled = builder.mIsOptOutDialogEnabled;
         this.mIsEnhanced4GModeEnabled = builder.mIsEnhanced4GModeEnabled;
         this.mIsVideoTelephonyEnabled = builder.mIsVideoTelephonyEnabled;
         this.mIsWifiCallingEnabled = builder.mIsWifiCallingEnabled;
@@ -618,8 +690,8 @@
     }
 
     /**
-     * @return {@code 1} if an embedded subscription is on a removable card. Such subscriptions are
-     * marked inaccessible as soon as the current card is removed. Otherwise, they will remain
+     * @return {@code true} if an embedded subscription is on a removable card. Such subscriptions
+     * are marked inaccessible as soon as the current card is removed. Otherwise, they will remain
      * accessible unless explicitly deleted. Only meaningful when {@link #getEmbedded()} is 1.
      */
     public boolean isRemovableEmbedded() {
@@ -636,6 +708,90 @@
     }
 
     /**
+     * @return {@code 1} if cell broadcast extreme threat alert is enabled by the user.
+     */
+    public int getCellBroadcastExtremeThreatAlertEnabled() {
+        return mIsExtremeThreatAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast amber alert is enabled by the user.
+     */
+    public int getCellBroadcastSevereThreatAlertEnabled() {
+        return mIsSevereThreatAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast emergency alert is enabled by the user.
+     */
+    public int getCellBroadcastAmberAlertEnabled() {
+        return mIsAmberAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast emergency alert is enabled by the user.
+     */
+    public int getCellBroadcastEmergencyAlertEnabled() {
+        return mIsEmergencyAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast alert sound duration in seconds.
+     */
+    public int getCellBroadcastAlertSoundDuration() {
+        return mAlertSoundDuration;
+    }
+
+    /**
+     * @return Cell broadcast alert reminder interval in minutes.
+     */
+    public int getCellBroadcastAlertReminderInterval() {
+        return mReminderInterval;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast alert vibration is enabled by the user.
+     */
+    public int getCellBroadcastAlertVibrationEnabled() {
+        return mIsAlertVibrationEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast alert speech is enabled by the user.
+     */
+    public int getCellBroadcastAlertSpeechEnabled() {
+        return mIsAlertSpeechEnabled;
+    }
+
+    /**
+     * @return {@code 1} if ETWS test alert is enabled by the user.
+     */
+    public int getCellBroadcastEtwsTestAlertEnabled() {
+        return mIsEtwsTestAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if area info message is enabled by the user.
+     */
+    public int getCellBroadcastAreaInfoMessageEnabled() {
+        return mIsAreaInfoMessageEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast test alert is enabled by the user.
+     */
+    public int getCellBroadcastTestAlertEnabled() {
+        return mIsTestAlertEnabled;
+    }
+
+    /**
+     * @return {@code 1} if cell broadcast opt-out dialog should be shown.
+     */
+    public int getCellBroadcastOptOutDialogEnabled() {
+        return mIsOptOutDialogEnabled;
+    }
+
+    /**
      * @return {@code true} if enhanced 4G mode is enabled by the user or not.
      */
     public boolean isEnhanced4GModeEnabled() {
@@ -1044,30 +1200,10 @@
                 .build();
     }
 
-    /**
-     * Get ID stripped PII information on user build.
-     *
-     * @param id The PII id.
-     *
-     * @return The stripped string.
-     */
-    public static String givePrintableId(String id) {
-        String idToPrint = null;
-        if (id != null) {
-            int len = id.length();
-            if (len > 6 && !TelephonyUtils.IS_DEBUGGABLE) {
-                idToPrint = id.substring(0, len - 6) + Rlog.pii(false, id.substring(len - 6));
-            } else {
-                idToPrint = id;
-            }
-        }
-        return idToPrint;
-    }
-
     @Override
     public String toString() {
         return "[SubscriptionInfoInternal: id=" + mId
-                + " iccId=" + givePrintableId(mIccId)
+                + " iccId=" + SubscriptionInfo.getPrintableId(mIccId)
                 + " simSlotIndex=" + mSimSlotIndex
                 + " portIndex=" + mPortIndex
                 + " isEmbedded=" + mIsEmbedded
@@ -1087,7 +1223,7 @@
                 + " mnc=" + mMnc
                 + " ehplmns=" + mEhplmns
                 + " hplmns=" + mHplmns
-                + " cardString=" + givePrintableId(mCardString)
+                + " cardString=" + SubscriptionInfo.getPrintableId(mCardString)
                 + " cardId=" + mCardId
                 + " nativeAccessRules=" + IccUtils.bytesToHexString(mNativeAccessRules)
                 + " carrierConfigAccessRules=" + IccUtils.bytesToHexString(
@@ -1105,7 +1241,7 @@
                 + " wifiCallingModeForRoaming="
                 + ImsMmTelManager.wifiCallingModeToString(mWifiCallingModeForRoaming)
                 + " enabledMobileDataPolicies=" + mEnabledMobileDataPolicies
-                + " imsi=" + givePrintableId(mImsi)
+                + " imsi=" + SubscriptionInfo.getPrintableId(mImsi)
                 + " rcsUceEnabled=" + mIsRcsUceEnabled
                 + " crossSimCallingEnabled=" + mIsCrossSimCallingEnabled
                 + " rcsConfig=" + IccUtils.bytesToHexString(mRcsConfig)
@@ -1113,8 +1249,8 @@
                 + " deviceToDeviceStatusSharingPreference=" + mDeviceToDeviceStatusSharingPreference
                 + " isVoImsOptInEnabled=" + mIsVoImsOptInEnabled
                 + " deviceToDeviceStatusSharingContacts=" + mDeviceToDeviceStatusSharingContacts
-                + " numberFromCarrier=" + mNumberFromCarrier
-                + " numberFromIms=" + mNumberFromIms
+                + " numberFromCarrier=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mNumberFromCarrier)
+                + " numberFromIms=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mNumberFromIms)
                 + " userId=" + mUserId
                 + " isSatelliteEnabled=" + mIsSatelliteEnabled
                 + " isGroupDisabled=" + mIsGroupDisabled
@@ -1130,6 +1266,16 @@
                 && mDisplayNameSource == that.mDisplayNameSource && mIconTint == that.mIconTint
                 && mDataRoaming == that.mDataRoaming && mIsEmbedded == that.mIsEmbedded
                 && mIsRemovableEmbedded == that.mIsRemovableEmbedded
+                && mIsExtremeThreatAlertEnabled == that.mIsExtremeThreatAlertEnabled
+                && mIsSevereThreatAlertEnabled == that.mIsSevereThreatAlertEnabled
+                && mIsAmberAlertEnabled == that.mIsAmberAlertEnabled
+                && mIsEmergencyAlertEnabled == that.mIsEmergencyAlertEnabled
+                && mAlertSoundDuration == that.mAlertSoundDuration
+                && mReminderInterval == that.mReminderInterval
+                && mIsAlertVibrationEnabled == that.mIsAlertVibrationEnabled
+                && mIsAlertSpeechEnabled == that.mIsAlertSpeechEnabled
+                && mIsEtwsTestAlertEnabled == that.mIsEtwsTestAlertEnabled
+                && mIsAreaInfoMessageEnabled == that.mIsAreaInfoMessageEnabled
                 && mIsEnhanced4GModeEnabled == that.mIsEnhanced4GModeEnabled
                 && mIsVideoTelephonyEnabled == that.mIsVideoTelephonyEnabled
                 && mIsWifiCallingEnabled == that.mIsWifiCallingEnabled
@@ -1147,31 +1293,33 @@
                 && mIsNrAdvancedCallingEnabled == that.mIsNrAdvancedCallingEnabled
                 && mPortIndex == that.mPortIndex && mUsageSetting == that.mUsageSetting
                 && mLastUsedTPMessageReference == that.mLastUsedTPMessageReference
-                && mUserId == that.mUserId && mCardId == that.mCardId
-                && mIsGroupDisabled == that.mIsGroupDisabled && mIccId.equals(that.mIccId)
-                && mDisplayName.equals(that.mDisplayName) && mCarrierName.equals(that.mCarrierName)
-                && mNumber.equals(that.mNumber) && mMcc.equals(that.mMcc) && mMnc.equals(that.mMnc)
-                && mEhplmns.equals(that.mEhplmns) && mHplmns.equals(that.mHplmns)
-                && mCardString.equals(
-                that.mCardString) && Arrays.equals(mNativeAccessRules,
-                that.mNativeAccessRules) && Arrays.equals(mCarrierConfigAccessRules,
-                that.mCarrierConfigAccessRules) && mGroupUuid.equals(that.mGroupUuid)
-                && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner)
-                && mEnabledMobileDataPolicies.equals(that.mEnabledMobileDataPolicies)
-                && mImsi.equals(
-                that.mImsi) && Arrays.equals(mRcsConfig, that.mRcsConfig)
-                && mAllowedNetworkTypesForReasons.equals(that.mAllowedNetworkTypesForReasons)
-                && mDeviceToDeviceStatusSharingContacts.equals(
+                && mUserId == that.mUserId && mIsSatelliteEnabled == that.mIsSatelliteEnabled
+                && mCardId == that.mCardId && mIsGroupDisabled == that.mIsGroupDisabled
+                && mIccId.equals(that.mIccId) && mDisplayName.equals(that.mDisplayName)
+                && mCarrierName.equals(that.mCarrierName) && mNumber.equals(that.mNumber)
+                && mMcc.equals(that.mMcc) && mMnc.equals(that.mMnc) && mEhplmns.equals(
+                that.mEhplmns)
+                && mHplmns.equals(that.mHplmns) && mCardString.equals(that.mCardString)
+                && Arrays.equals(mNativeAccessRules, that.mNativeAccessRules)
+                && Arrays.equals(mCarrierConfigAccessRules, that.mCarrierConfigAccessRules)
+                && mGroupUuid.equals(that.mGroupUuid) && mCountryIso.equals(that.mCountryIso)
+                && mGroupOwner.equals(that.mGroupOwner) && mEnabledMobileDataPolicies.equals(
+                that.mEnabledMobileDataPolicies) && mImsi.equals(that.mImsi) && Arrays.equals(
+                mRcsConfig, that.mRcsConfig) && mAllowedNetworkTypesForReasons.equals(
+                that.mAllowedNetworkTypesForReasons) && mDeviceToDeviceStatusSharingContacts.equals(
                 that.mDeviceToDeviceStatusSharingContacts) && mNumberFromCarrier.equals(
-                that.mNumberFromCarrier) && mNumberFromIms.equals(that.mNumberFromIms)
-                && mIsSatelliteEnabled == that.mIsSatelliteEnabled;
+                that.mNumberFromCarrier) && mNumberFromIms.equals(that.mNumberFromIms);
     }
 
     @Override
     public int hashCode() {
         int result = Objects.hash(mId, mIccId, mSimSlotIndex, mDisplayName, mCarrierName,
                 mDisplayNameSource, mIconTint, mNumber, mDataRoaming, mMcc, mMnc, mEhplmns, mHplmns,
-                mIsEmbedded, mCardString, mIsRemovableEmbedded, mIsEnhanced4GModeEnabled,
+                mIsEmbedded, mCardString, mIsRemovableEmbedded, mIsExtremeThreatAlertEnabled,
+                mIsSevereThreatAlertEnabled, mIsAmberAlertEnabled, mIsEmergencyAlertEnabled,
+                mAlertSoundDuration, mReminderInterval, mIsAlertVibrationEnabled,
+                mIsAlertSpeechEnabled,
+                mIsEtwsTestAlertEnabled, mIsAreaInfoMessageEnabled, mIsEnhanced4GModeEnabled,
                 mIsVideoTelephonyEnabled, mIsWifiCallingEnabled, mWifiCallingMode,
                 mWifiCallingModeForRoaming, mIsWifiCallingEnabledForRoaming, mIsOpportunistic,
                 mGroupUuid, mCountryIso, mCarrierId, mProfileClass, mType, mGroupOwner,
@@ -1306,6 +1454,66 @@
         private int mIsRemovableEmbedded = 0;
 
         /**
+         * Whether cell broadcast extreme threat alert is enabled by the user or not.
+         */
+        private int mIsExtremeThreatAlertEnabled = 1;
+
+        /**
+         * Whether cell broadcast severe threat alert is enabled by the user or not.
+         */
+        private int mIsSevereThreatAlertEnabled = 1;
+
+        /**
+         * Whether cell broadcast amber alert is enabled by the user or not.
+         */
+        private int mIsAmberAlertEnabled = 1;
+
+        /**
+         * Whether cell broadcast emergency alert is enabled by the user or not.
+         */
+        private int mIsEmergencyAlertEnabled = 1;
+
+        /**
+         * Cell broadcast alert sound duration in seconds.
+         */
+        private int mAlertSoundDuration = 4;
+
+        /**
+         * Cell broadcast alert reminder interval in minutes.
+         */
+        private int mReminderInterval = 0;
+
+        /**
+         * Whether cell broadcast alert vibration is enabled by the user or not.
+         */
+        private int mIsAlertVibrationEnabled = 1;
+
+        /**
+         * Whether cell broadcast alert speech is enabled by the user or not.
+         */
+        private int mIsAlertSpeechEnabled = 1;
+
+        /**
+         * Whether ETWS test alert is enabled by the user or not.
+         */
+        private int mIsEtwsTestAlertEnabled = 0;
+
+        /**
+         * Whether area info message is enabled by the user or not.
+         */
+        private int mIsAreaInfoMessageEnabled = 1;
+
+        /**
+         * Whether cell broadcast test alert is enabled by the user or not.
+         */
+        private int mIsTestAlertEnabled = 0;
+
+        /**
+         * Whether cell broadcast opt-out dialog should be shown or not.
+         */
+        private int mIsOptOutDialogEnabled = 1;
+
+        /**
          * Whether enhanced 4G mode is enabled by the user or not.
          */
         private int mIsEnhanced4GModeEnabled = -1;
@@ -1528,6 +1736,18 @@
             mNativeAccessRules = info.mNativeAccessRules;
             mCarrierConfigAccessRules = info.mCarrierConfigAccessRules;
             mIsRemovableEmbedded = info.mIsRemovableEmbedded;
+            mIsExtremeThreatAlertEnabled = info.mIsExtremeThreatAlertEnabled;
+            mIsSevereThreatAlertEnabled = info.mIsSevereThreatAlertEnabled;
+            mIsAmberAlertEnabled = info.mIsAmberAlertEnabled;
+            mIsEmergencyAlertEnabled = info.mIsEmergencyAlertEnabled;
+            mAlertSoundDuration = info.mAlertSoundDuration;
+            mReminderInterval = info.mReminderInterval;
+            mIsAlertVibrationEnabled = info.mIsAlertVibrationEnabled;
+            mIsAlertSpeechEnabled = info.mIsAlertSpeechEnabled;
+            mIsEtwsTestAlertEnabled = info.mIsEtwsTestAlertEnabled;
+            mIsAreaInfoMessageEnabled = info.mIsAreaInfoMessageEnabled;
+            mIsTestAlertEnabled = info.mIsTestAlertEnabled;
+            mIsOptOutDialogEnabled = info.mIsOptOutDialogEnabled;
             mIsEnhanced4GModeEnabled = info.mIsEnhanced4GModeEnabled;
             mIsVideoTelephonyEnabled = info.mIsVideoTelephonyEnabled;
             mIsWifiCallingEnabled = info.mIsWifiCallingEnabled;
@@ -1859,6 +2079,171 @@
         }
 
         /**
+         * Set whether cell broadcast extreme threat alert is enabled by the user or not.
+         *
+         * @param isExtremeThreatAlertEnabled whether cell broadcast extreme threat alert is enabled
+         * by the user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastExtremeThreatAlertEnabled(int isExtremeThreatAlertEnabled) {
+            mIsExtremeThreatAlertEnabled = isExtremeThreatAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast severe threat alert is enabled by the user or not.
+         *
+         * @param isSevereThreatAlertEnabled whether cell broadcast severe threat alert is enabled
+         * by the user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastSevereThreatAlertEnabled(int isSevereThreatAlertEnabled) {
+            mIsSevereThreatAlertEnabled = isSevereThreatAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast amber alert is enabled by the user or not.
+         *
+         * @param isAmberAlertEnabled whether cell broadcast amber alert is enabled by the user or
+         * not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastAmberAlertEnabled(int isAmberAlertEnabled) {
+            mIsAmberAlertEnabled = isAmberAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast emergency alert is enabled by the user or not.
+         *
+         * @param isEmergencyAlertEnabled whether cell broadcast emergency alert is enabled by the
+         * user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastEmergencyAlertEnabled(int isEmergencyAlertEnabled) {
+            mIsEmergencyAlertEnabled = isEmergencyAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set cell broadcast alert sound duration.
+         *
+         * @param alertSoundDuration Alert sound duration in seconds.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastAlertSoundDuration(int alertSoundDuration) {
+            mAlertSoundDuration = alertSoundDuration;
+            return this;
+        }
+
+        /**
+         * Set cell broadcast alert reminder interval in minutes.
+         *
+         * @param reminderInterval Alert reminder interval in minutes.
+         *
+         * @return The builder.
+         */
+        public Builder setCellBroadcastAlertReminderInterval(int reminderInterval) {
+            mReminderInterval = reminderInterval;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast alert vibration is enabled by the user or not.
+         *
+         * @param isAlertVibrationEnabled whether cell broadcast alert vibration is enabled by the
+         * user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastAlertVibrationEnabled(int isAlertVibrationEnabled) {
+            mIsAlertVibrationEnabled = isAlertVibrationEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast alert speech is enabled by the user or not.
+         *
+         * @param isAlertSpeechEnabled whether cell broadcast alert speech is enabled by the user or
+         * not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastAlertSpeechEnabled(int isAlertSpeechEnabled) {
+            mIsAlertSpeechEnabled = isAlertSpeechEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether ETWS test alert is enabled by the user or not.
+         *
+         * @param isEtwsTestAlertEnabled whether cell broadcast ETWS test alert is enabled by the
+         * user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastEtwsTestAlertEnabled(int isEtwsTestAlertEnabled) {
+            mIsEtwsTestAlertEnabled = isEtwsTestAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether area info message is enabled by the user or not.
+         *
+         * @param isAreaInfoMessageEnabled whether cell broadcast area info message is enabled by
+         * the user or not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastAreaInfoMessageEnabled(int isAreaInfoMessageEnabled) {
+            mIsAreaInfoMessageEnabled = isAreaInfoMessageEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast test alert is enabled by the user or not.
+         *
+         * @param isTestAlertEnabled whether cell broadcast test alert is enabled by the user or
+         * not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastTestAlertEnabled(int isTestAlertEnabled) {
+            mIsTestAlertEnabled = isTestAlertEnabled;
+            return this;
+        }
+
+        /**
+         * Set whether cell broadcast opt-out dialog should be shown or not.
+         *
+         * @param isOptOutDialogEnabled whether cell broadcast opt-out dialog should be shown or
+         * not.
+         *
+         * @return The builder.
+         */
+        @NonNull
+        public Builder setCellBroadcastOptOutDialogEnabled(int isOptOutDialogEnabled) {
+            mIsOptOutDialogEnabled = isOptOutDialogEnabled;
+            return this;
+        }
+
+        /**
          * Set whether enhanced 4G mode is enabled by the user or not.
          *
          * @param isEnhanced4GModeEnabled whether enhanced 4G mode is enabled by the user or not.
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 0f499d3..f9720df 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -33,13 +33,16 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.TelephonyServiceManager;
 import android.os.UserHandle;
@@ -51,7 +54,9 @@
 import android.service.euicc.GetEuiccProfileInfoListResult;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
+import android.telephony.RadioAccessFamily;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.DataRoamingMode;
@@ -83,7 +88,7 @@
 import com.android.internal.telephony.MultiSimSettingController;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
+import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.data.PhoneSwitcher;
@@ -96,12 +101,14 @@
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.internal.telephony.util.ArrayUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
 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.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -137,6 +144,18 @@
      * that requires higher permission to access.
      */
     private static final Set<String> DIRECT_ACCESS_SUBSCRIPTION_COLUMNS = Set.of(
+            SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT,
+            SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT,
+            SimInfo.COLUMN_CB_AMBER_ALERT,
+            SimInfo.COLUMN_CB_EMERGENCY_ALERT,
+            SimInfo.COLUMN_CB_ALERT_SOUND_DURATION,
+            SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL,
+            SimInfo.COLUMN_CB_ALERT_VIBRATE,
+            SimInfo.COLUMN_CB_ALERT_SPEECH,
+            SimInfo.COLUMN_CB_ETWS_TEST_ALERT,
+            SimInfo.COLUMN_CB_CHANNEL_50_ALERT,
+            SimInfo.COLUMN_CB_CMAS_TEST_ALERT,
+            SimInfo.COLUMN_CB_OPT_OUT_DIALOG,
             SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
             SimInfo.COLUMN_VT_IMS_ENABLED,
             SimInfo.COLUMN_WFC_IMS_ENABLED,
@@ -217,7 +236,7 @@
 
     /** Local log for most important debug messages. */
     @NonNull
-    private final LocalLog mLocalLog = new LocalLog(128);
+    private final LocalLog mLocalLog = new LocalLog(256);
 
     /** The subscription database manager. */
     @NonNull
@@ -225,7 +244,7 @@
 
     /** The slot index subscription id map. Key is the slot index, and the value is sub id. */
     @NonNull
-    private final WatchedMap<Integer, Integer> mSlotIndexToSubId = new WatchedMap<>();
+    private final SubscriptionMap<Integer, Integer> mSlotIndexToSubId = new SubscriptionMap<>();
 
     /** Subscription manager service callbacks. */
     @NonNull
@@ -256,9 +275,14 @@
     private final int[] mSimState;
 
     /**
-     * Watched map that automatically invalidate cache in {@link SubscriptionManager}.
+     * Slot index/subscription map that automatically invalidate cache in
+     * {@link SubscriptionManager}.
+     *
+     * @param <K> The type of the key.
+     * @param <V> The type of the value.
      */
-    private static class WatchedMap<K, V> extends ConcurrentHashMap<K, V> {
+    @VisibleForTesting
+    public static class SubscriptionMap<K, V> extends ConcurrentHashMap<K, V> {
         @Override
         public void clear() {
             super.clear();
@@ -370,7 +394,7 @@
          *
          * @param subId The subscription id.
          */
-        public void onUiccApplicationsEnabled(int subId) {}
+        public void onUiccApplicationsEnabledChanged(int subId) {}
     }
 
     /**
@@ -380,6 +404,7 @@
      * @param looper The looper for the handler.
      */
     public SubscriptionManagerService(@NonNull Context context, @NonNull Looper looper) {
+        logl("Created SubscriptionManagerService");
         sInstance = this;
         mContext = context;
         mTelephonyManager = context.getSystemService(TelephonyManager.class);
@@ -395,14 +420,6 @@
 
         mBackgroundHandler = new Handler(backgroundThread.getLooper());
 
-        TelephonyServiceManager.ServiceRegisterer subscriptionServiceRegisterer =
-                TelephonyFrameworkInitializer
-                        .getTelephonyServiceManager()
-                        .getSubscriptionServiceRegisterer();
-        if (subscriptionServiceRegisterer.get() == null) {
-            subscriptionServiceRegisterer.register(this);
-        }
-
         mDefaultVoiceSubId = new WatchedInt(Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID)) {
@@ -466,8 +483,8 @@
                      * Called when database has been loaded into the cache.
                      */
                     @Override
-                    public void onDatabaseLoaded() {
-                        log("Subscription database has been loaded.");
+                    public void onInitialized() {
+                        log("Subscription database has been initialized.");
                         for (int phoneId = 0; phoneId < mTelephonyManager.getActiveModemCount()
                                 ; phoneId++) {
                             markSubscriptionsInactive(phoneId);
@@ -499,28 +516,26 @@
                                 && telephonyRegistryManager != null) {
                             telephonyRegistryManager.notifyOpportunisticSubscriptionInfoChanged();
                         }
-
-                        // TODO: Call TelephonyMetrics.updateActiveSubscriptionInfoList when active
-                        //  subscription changes.
-                    }
-
-                    /**
-                     * Called when {@link SubscriptionInfoInternal#areUiccApplicationsEnabled()}
-                     * changed.
-                     *
-                     * @param subId The subscription id.
-                     */
-                    @Override
-                    public void onUiccApplicationsEnabled(int subId) {
-                        log("onUiccApplicationsEnabled: subId=" + subId);
-                        mSubscriptionManagerServiceCallbacks.forEach(
-                                callback -> callback.invokeFromExecutor(
-                                        () -> callback.onUiccApplicationsEnabled(subId)));
                     }
                 });
 
+        // Broadcast sub Id on service initialized.
+        broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
+                getDefaultDataSubId());
+        broadcastSubId(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED,
+                getDefaultVoiceSubId());
+        broadcastSubId(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED,
+                getDefaultSmsSubId());
         updateDefaultSubId();
 
+        TelephonyServiceManager.ServiceRegisterer subscriptionServiceRegisterer =
+                TelephonyFrameworkInitializer
+                        .getTelephonyServiceManager()
+                        .getSubscriptionServiceRegisterer();
+        if (subscriptionServiceRegisterer.get() == null) {
+            subscriptionServiceRegisterer.register(this);
+        }
+
         mHandler.post(() -> {
             // EuiccController is created after SubscriptionManagerService. So we need to get
             // the instance later in the handler.
@@ -530,15 +545,15 @@
             }
         });
 
+        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
+
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 updateEmbeddedSubscriptions();
             }
         }, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-
-        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
-        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
+        logl("Registered iSub service");
     }
 
     /**
@@ -891,8 +906,13 @@
                 .forEach(subInfo -> {
                     mSubscriptionDatabaseManager.setSimSlotIndex(subInfo.getSubscriptionId(),
                             SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-                    mSlotIndexToSubId.remove(simSlotIndex);
+                    // Sometime even though slot-port is inactive, proper iccid will be present,
+                    // hence retry the port index from UiccSlot. (Pre-U behavior)
+                    mSubscriptionDatabaseManager.setPortIndex(subInfo.getSubscriptionId(),
+                            getPortIndex(subInfo.getIccId()));
                 });
+        updateGroupDisabled();
+        logl("markSubscriptionsInactive: current mapping " + slotMappingToString());
     }
 
     /**
@@ -928,23 +948,59 @@
     }
 
     /**
-     * Get the embedded profile port index by ICCID.
+     * Get the port index by ICCID.
      *
      * @param iccId The ICCID.
      * @return The port index.
      */
-    private int getEmbeddedProfilePortIndex(String iccId) {
-        UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
+    private int getPortIndex(@NonNull String iccId) {
+        UiccSlot[] slots = mUiccController.getUiccSlots();
         for (UiccSlot slot : slots) {
-            if (slot != null && slot.isEuicc()
-                    && slot.getPortIndexFromIccId(iccId) != TelephonyManager.INVALID_PORT_INDEX) {
-                return slot.getPortIndexFromIccId(iccId);
+            if (slot != null) {
+                int portIndex = slot.getPortIndexFromIccId(iccId);
+                if (portIndex != TelephonyManager.INVALID_PORT_INDEX) {
+                    return portIndex;
+                }
             }
         }
         return TelephonyManager.INVALID_PORT_INDEX;
     }
 
     /**
+     * Insert a new subscription into the database.
+     *
+     * @param iccId The ICCID.
+     * @param slotIndex The logical SIM slot index (i.e. phone id).
+     * @param displayName The display name.
+     * @param subscriptionType The subscription type.
+     *
+     * @return The subscription id.
+     */
+    private int insertSubscriptionInfo(@NonNull String iccId, int slotIndex,
+            @Nullable String displayName, @SubscriptionType int subscriptionType) {
+        String defaultAllowNetworkTypes = Phone.convertAllowedNetworkTypeMapIndexToDbName(
+                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER) + "="
+                + RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE);
+        SubscriptionInfoInternal.Builder builder = new SubscriptionInfoInternal.Builder()
+                .setIccId(iccId)
+                .setCardString(iccId)
+                .setSimSlotIndex(slotIndex)
+                .setType(subscriptionType)
+                .setIconTint(getColor())
+                .setAllowedNetworkTypesForReasons(defaultAllowNetworkTypes);
+        if (displayName != null) {
+            builder.setDisplayName(displayName);
+        }
+
+        int subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(builder.build());
+        logl("insertSubscriptionInfo: Inserted a new subscription. subId=" + subId
+                + ", slotIndex=" + slotIndex + ", iccId=" + SubscriptionInfo.getPrintableId(iccId)
+                + ", displayName=" + displayName + ", type="
+                + SubscriptionManager.subscriptionTypeToString(subscriptionType));
+        return subId;
+    }
+
+    /**
      * Pull the embedded subscription from {@link EuiccController} for the eUICC with the given list
      * of card IDs {@code cardIds}.
      *
@@ -957,7 +1013,7 @@
         mBackgroundHandler.post(() -> {
             // 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 == null || !mEuiccManager.isEnabled()) {
+            if (mEuiccManager == null || !mEuiccManager.isEnabled() || mEuiccController == null) {
                 loge("updateEmbeddedSubscriptions: eUICC not enabled");
                 if (callback != null) {
                     callback.run();
@@ -965,11 +1021,27 @@
                 return;
             }
 
+            Set<Integer> embeddedSubs = new ArraySet<>();
             log("updateEmbeddedSubscriptions: start to get euicc profiles.");
+
+            for (UiccSlot slot : mUiccController.getUiccSlots()) {
+                if (slot != null) {
+                    log("  " + slot);
+                }
+            }
+
+            // The flag indicating getting successful result from EuiccController.
+            boolean isProfileUpdateSuccessful = false;
+
             for (int cardId : cardIds) {
                 GetEuiccProfileInfoListResult result = mEuiccController
                         .blockingGetEuiccProfileInfoList(cardId);
                 logl("updateEmbeddedSubscriptions: cardId=" + cardId + ", result=" + result);
+                if (result == null) {
+                    //TODO: Add back-off retry in the future if needed.
+                    loge("Failed to get euicc profiles.");
+                    continue;
+                }
 
                 if (result.getResult() != EuiccService.RESULT_OK) {
                     loge("Failed to get euicc profile info. result="
@@ -977,6 +1049,8 @@
                     continue;
                 }
 
+                isProfileUpdateSuccessful = true;
+
                 if (result.getProfiles() == null || result.getProfiles().isEmpty()) {
                     loge("No profiles returned.");
                     continue;
@@ -990,13 +1064,10 @@
 
                     // The subscription does not exist in the database. Insert a new one here.
                     if (subInfo == null) {
-                        subInfo = new SubscriptionInfoInternal.Builder()
-                                .setIccId(embeddedProfile.getIccid())
-                                .setIconTint(getColor())
-                                .build();
-                        int subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(subInfo);
-                        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
-                                .setId(subId).build();
+                        int subId = insertSubscriptionInfo(embeddedProfile.getIccid(),
+                                SubscriptionManager.INVALID_SIM_SLOT_INDEX,
+                                null, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
+                        subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternal(subId);
                     }
 
                     int nameSource = subInfo.getDisplayNameSource();
@@ -1014,13 +1085,15 @@
                     builder.setRemovableEmbedded(isRemovable);
 
                     // override DISPLAY_NAME if the priority of existing nameSource is <= carrier
-                    if (getNameSourcePriority(nameSource) <= getNameSourcePriority(
-                            SubscriptionManager.NAME_SOURCE_CARRIER)) {
-                        builder.setDisplayName(embeddedProfile.getNickname());
+                    String nickName = embeddedProfile.getNickname();
+                    if (nickName != null
+                            && getNameSourcePriority(nameSource) <= getNameSourcePriority(
+                                    SubscriptionManager.NAME_SOURCE_CARRIER)) {
+                        builder.setDisplayName(nickName);
                         builder.setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER);
                     }
                     builder.setProfileClass(embeddedProfile.getProfileClass());
-                    builder.setPortIndex(getEmbeddedProfilePortIndex(embeddedProfile.getIccid()));
+                    builder.setPortIndex(getPortIndex(embeddedProfile.getIccid()));
 
                     CarrierIdentifier cid = embeddedProfile.getCarrierIdentifier();
                     if (cid != null) {
@@ -1044,16 +1117,54 @@
                         builder.setCardString(mUiccController.convertToCardString(cardId));
                     }
 
+                    embeddedSubs.add(subInfo.getSubscriptionId());
                     subInfo = builder.build();
                     log("updateEmbeddedSubscriptions: update subscription " + subInfo);
                     mSubscriptionDatabaseManager.updateSubscription(subInfo);
                 }
             }
+
+            // Marked the previous embedded subscriptions non-embedded if the latest profiles do
+            // not include them anymore.
+            if (isProfileUpdateSuccessful) {
+                // embeddedSubs contains all the existing embedded subs queried from EuiccManager,
+                // including active or inactive. If there are any embedded subscription in the
+                // database that is not in embeddedSubs, mark them as non-embedded. These were
+                // deleted embedded subscriptions, so we treated them as non-embedded (pre-U
+                // behavior) and they don't show up in Settings SIM page.
+                mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                        .filter(SubscriptionInfoInternal::isEmbedded)
+                        .filter(subInfo -> !embeddedSubs.contains(subInfo.getSubscriptionId()))
+                        .forEach(subInfo -> {
+                            logl("updateEmbeddedSubscriptions: Mark the deleted sub "
+                                    + subInfo.getSubscriptionId() + " as non-embedded.");
+                            mSubscriptionDatabaseManager.setEmbedded(
+                                    subInfo.getSubscriptionId(), false);
+                        });
+                if (mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                        .anyMatch(subInfo -> subInfo.isEmbedded()
+                                && subInfo.isActive()
+                                && subInfo.getPortIndex()
+                                == TelephonyManager.INVALID_PORT_INDEX
+                                && mSimState[subInfo.getSimSlotIndex()]
+                                == TelephonyManager.SIM_STATE_LOADED)) {
+                    //Report Anomaly if invalid portIndex is updated in Active subscriptions
+                    AnomalyReporter.reportAnomaly(
+                            UUID.fromString("38fdf63c-3bd9-4fc2-ad33-a20246a32fa7"),
+                            "SubscriptionManagerService: Found Invalid portIndex"
+                                    + " in active subscriptions");
+                }
+            } else {
+                loge("The eSIM profiles update was not successful.");
+            }
+            log("updateEmbeddedSubscriptions: Finished embedded subscription update.");
+            // The runnable will be executed in the main thread. Pre Android-U behavior.
+            mHandler.post(() -> {
+                if (callback != null) {
+                    callback.run();
+                }
+            });
         });
-        log("updateEmbeddedSubscriptions: Finished embedded subscription update.");
-        if (callback != null) {
-            callback.run();
-        }
     }
 
     /**
@@ -1145,7 +1256,7 @@
             }
 
             if (mSimState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN) {
-                log("areAllSubscriptionsLoaded: SIM state is still unknown.");
+                log("areAllSubscriptionsLoaded: SIM " + phoneId + " state is still unknown.");
                 return false;
             }
         }
@@ -1154,138 +1265,175 @@
     }
 
     /**
-     * Update the subscriptions on the logical SIM slot index (i.e. phone id).
+     * Update the subscription on the logical SIM slot index (i.e. phone id).
      *
      * @param phoneId The phone id (i.e. Logical SIM slot index)
      */
-    private void updateSubscriptions(int phoneId) {
+    private void updateSubscription(int phoneId) {
         int simState = mSimState[phoneId];
-        log("updateSubscriptions: phoneId=" + phoneId + ", simState="
+        log("updateSubscription: phoneId=" + phoneId + ", simState="
                 + TelephonyManager.simStateToString(simState));
+        for (UiccSlot slot : mUiccController.getUiccSlots()) {
+            if (slot != null) {
+                log("  " + slot);
+            }
+        }
+
         if (simState == TelephonyManager.SIM_STATE_ABSENT) {
+            // Re-enable the pSIM when it's removed, so it will be in enabled state when it gets
+            // re-inserted again. (pre-U behavior)
+            List<String> iccIds = getIccIdsOfInsertedPhysicalSims();
+            mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                    // All the removed pSIMs (Note this could include some erased eSIM that has
+                    // embedded bit removed).
+                    .filter(subInfo -> !iccIds.contains(subInfo.getIccId())
+                            && !subInfo.isEmbedded())
+                    .forEach(subInfo -> {
+                        int subId = subInfo.getSubscriptionId();
+                        log("updateSubscription: Re-enable Uicc application on sub " + subId);
+                        mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, true);
+                        // When sim is absent, set the port index to invalid port index.
+                        // (pre-U behavior)
+                        mSubscriptionDatabaseManager.setPortIndex(subId,
+                                TelephonyManager.INVALID_PORT_INDEX);
+                    });
+
             if (mSlotIndexToSubId.containsKey(phoneId)) {
-                int subId = mSlotIndexToSubId.get(phoneId);
-                // Re-enable the SIM when it's removed, so it will be in enabled state when it gets
-                // re-inserted again. (pre-U behavior)
-                log("updateSubscriptions: Re-enable Uicc application on sub " + subId);
-                mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, true);
-                // When sim is absent, set the port index to invalid port index. (pre-U behavior)
-                mSubscriptionDatabaseManager.setPortIndex(subId,
-                        TelephonyManager.INVALID_PORT_INDEX);
                 markSubscriptionsInactive(phoneId);
             }
         } else if (simState == TelephonyManager.SIM_STATE_NOT_READY) {
             // Check if this is the final state. Only update the subscription if NOT_READY is a
             // final state.
             IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
+            if (iccCard.isEmptyProfile()) log("updateSubscription: iccCard has empty profile.");
             if (!iccCard.isEmptyProfile() && areUiccAppsEnabledOnCard(phoneId)) {
-                log("updateSubscriptions: SIM_STATE_NOT_READY is not a final state. Will update "
+                log("updateSubscription: SIM_STATE_NOT_READY is not a final state. Will update "
                         + "subscription later.");
                 return;
-            }
-
-            if (!areUiccAppsEnabledOnCard(phoneId)) {
-                logl("updateSubscriptions: UICC app disabled on slot " + phoneId);
+            } else {
+                logl("updateSubscription: UICC app disabled on slot " + phoneId);
                 markSubscriptionsInactive(phoneId);
             }
-        }
+        } else {
+            String iccId = getIccId(phoneId);
+            log("updateSubscription: Found iccId=" + SubscriptionInfo.getPrintableId(iccId)
+                    + " on phone " + phoneId);
 
-        String iccId = getIccId(phoneId);
-        if (!TextUtils.isEmpty(iccId)) {
-            // Check if the subscription already existed.
-            SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
-                    .getSubscriptionInfoInternalByIccId(iccId);
-            int subId;
-            if (subInfo == null) {
-                // This is a new SIM card. Insert a new record.
-                subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(
-                        new SubscriptionInfoInternal.Builder()
-                                .setIccId(iccId)
-                                .setSimSlotIndex(phoneId)
-                                .setIconTint(getColor())
-                                .build());
-                logl("updateSubscriptions: Inserted a new subscription. subId=" + subId
-                        + ", phoneId=" + phoneId);
-            } else {
-                subId = subInfo.getSubscriptionId();
-                log("updateSubscriptions: Found existing subscription. subId= " + subId
-                        + ", phoneId=" + phoneId);
+            // For eSIM switching, SIM absent will not happen. Below is to exam if we find ICCID
+            // mismatch on the SIM slot. If that's the case, we need to mark all subscriptions on
+            // that logical slot invalid first. The correct subscription will be assigned the
+            // correct slot later.
+            SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager.getAllSubscriptions()
+                    .stream()
+                    .filter(sub -> sub.getSimSlotIndex() == phoneId && !iccId.equals(
+                            sub.getIccId()))
+                    .findFirst()
+                    .orElse(null);
+            if (subInfo != null) {
+                log("updateSubscription: Found previous active sub " + subInfo.getSubscriptionId()
+                        + " that doesn't match current iccid on slot " + phoneId + ".");
+                markSubscriptionsInactive(phoneId);
             }
 
-            subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternal(subId);
-            if (subInfo != null && subInfo.areUiccApplicationsEnabled()) {
-                mSlotIndexToSubId.put(phoneId, subId);
-                // Update the SIM slot index. This will make the subscription active.
-                mSubscriptionDatabaseManager.setSimSlotIndex(subId, phoneId);
-            }
-
-            // Update the card id.
-            UiccCard card = mUiccController.getUiccCardForPhone(phoneId);
-            if (card != null) {
-                String cardId = card.getCardId();
-                if (cardId != null) {
-                    mSubscriptionDatabaseManager.setCardString(subId, cardId);
+            if (!TextUtils.isEmpty(iccId)) {
+                // Check if the subscription already existed.
+                subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternalByIccId(iccId);
+                int subId;
+                if (subInfo == null) {
+                    // This is a new SIM card. Insert a new record.
+                    subId = insertSubscriptionInfo(iccId, phoneId, null,
+                            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
+                } else {
+                    subId = subInfo.getSubscriptionId();
+                    log("updateSubscription: Found existing subscription. subId= " + subId
+                            + ", phoneId=" + phoneId);
                 }
-            }
 
-            // Update the port index.
-            UiccSlot slot = mUiccController.getUiccSlotForPhone(phoneId);
-            if (slot != null && !slot.isEuicc()) {
-                int portIndex = slot.getPortIndexFromIccId(iccId);
-                mSubscriptionDatabaseManager.setPortIndex(subId, portIndex);
-            }
+                subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternal(subId);
+                if (subInfo != null && subInfo.areUiccApplicationsEnabled()) {
+                    mSlotIndexToSubId.put(phoneId, subId);
+                    // Update the SIM slot index. This will make the subscription active.
+                    mSubscriptionDatabaseManager.setSimSlotIndex(subId, phoneId);
+                    logl("updateSubscription: current mapping " + slotMappingToString());
+                }
 
-            if (simState == TelephonyManager.SIM_STATE_LOADED) {
-                String mccMnc = mTelephonyManager.getSimOperatorNumeric(subId);
-                if (!TextUtils.isEmpty(mccMnc)) {
-                    if (subId == getDefaultSubId()) {
-                        MccTable.updateMccMncConfiguration(mContext, mccMnc);
+                // Update the card id.
+                UiccCard card = mUiccController.getUiccCardForPhone(phoneId);
+                if (card != null) {
+                    String cardId = card.getCardId();
+                    if (cardId != null) {
+                        mSubscriptionDatabaseManager.setCardString(subId, cardId);
                     }
-                    setMccMnc(subId, mccMnc);
-                } else {
-                    loge("updateSubscriptions: mcc/mnc is empty");
                 }
 
-                String iso = TelephonyManager.getSimCountryIsoForPhone(phoneId);
+                // Update the port index.
+                mSubscriptionDatabaseManager.setPortIndex(subId, getPortIndex(iccId));
 
-                if (!TextUtils.isEmpty(iso)) {
-                    setCountryIso(subId, iso);
-                } else {
-                    loge("updateSubscriptions: sim country iso is null");
-                }
-
-                String msisdn = mTelephonyManager.getLine1Number(subId);
-                if (!TextUtils.isEmpty(msisdn)) {
-                    setDisplayNumber(msisdn, subId);
-                }
-
-                String imsi = mTelephonyManager.createForSubscriptionId(subId).getSubscriberId();
-                if (imsi != null) {
-                    mSubscriptionDatabaseManager.setImsi(subId, imsi);
-                }
-
-                IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
-                if (iccCard != null) {
-                    IccRecords records = iccCard.getIccRecords();
-                    if (records != null) {
-                        String[] ehplmns = records.getEhplmns();
-                        if (ehplmns != null) {
-                            mSubscriptionDatabaseManager.setEhplmns(subId, ehplmns);
+                if (simState == TelephonyManager.SIM_STATE_LOADED) {
+                    String mccMnc = mTelephonyManager.getSimOperatorNumeric(subId);
+                    if (!TextUtils.isEmpty(mccMnc)) {
+                        if (subId == getDefaultSubId()) {
+                            MccTable.updateMccMncConfiguration(mContext, mccMnc);
                         }
-                        String[] hplmns = records.getPlmnsFromHplmnActRecord();
-                        if (hplmns != null) {
-                            mSubscriptionDatabaseManager.setHplmns(subId, hplmns);
+                        setMccMnc(subId, mccMnc);
+                    } else {
+                        loge("updateSubscription: mcc/mnc is empty");
+                    }
+
+                    String iso = TelephonyManager.getSimCountryIsoForPhone(phoneId);
+
+                    if (!TextUtils.isEmpty(iso)) {
+                        setCountryIso(subId, iso);
+                    } else {
+                        loge("updateSubscription: sim country iso is null");
+                    }
+
+                    String msisdn = mTelephonyManager.getLine1Number(subId);
+                    if (!TextUtils.isEmpty(msisdn)) {
+                        setDisplayNumber(msisdn, subId);
+                    }
+
+                    String imsi = mTelephonyManager.createForSubscriptionId(
+                            subId).getSubscriberId();
+                    if (imsi != null) {
+                        mSubscriptionDatabaseManager.setImsi(subId, imsi);
+                    }
+
+                    IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
+                    if (iccCard != null) {
+                        IccRecords records = iccCard.getIccRecords();
+                        if (records != null) {
+                            String[] ehplmns = records.getEhplmns();
+                            if (ehplmns != null) {
+                                mSubscriptionDatabaseManager.setEhplmns(subId, ehplmns);
+                            }
+                            String[] hplmns = records.getPlmnsFromHplmnActRecord();
+                            if (hplmns != null) {
+                                mSubscriptionDatabaseManager.setHplmns(subId, hplmns);
+                            }
+                        } else {
+                            loge("updateSubscription: ICC records are not available.");
                         }
                     } else {
-                        loge("updateSubscriptions: ICC records are not available.");
+                        loge("updateSubscription: ICC card is not available.");
                     }
-                } else {
-                    loge("updateSubscriptions: ICC card is not available.");
+
+                    // Attempt to restore SIM specific settings when SIM is loaded.
+                    mContext.getContentResolver().call(
+                            SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                            SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+                            iccId, null);
+                    log("Reload the database.");
+                    mSubscriptionDatabaseManager.reloadDatabase();
                 }
+
+                log("updateSubscription: " + mSubscriptionDatabaseManager
+                        .getSubscriptionInfoInternal(subId));
+            } else {
+                log("updateSubscription: No ICCID available for phone " + phoneId);
+                mSlotIndexToSubId.remove(phoneId);
+                logl("updateSubscription: current mapping " + slotMappingToString());
             }
-        } else {
-            log("updateSubscriptions: No ICCID available for phone " + phoneId);
-            mSlotIndexToSubId.remove(phoneId);
         }
 
         if (areAllSubscriptionsLoaded()) {
@@ -1293,6 +1441,7 @@
             MultiSimSettingController.getInstance().notifyAllSubscriptionLoaded();
         }
 
+        updateGroupDisabled();
         updateDefaultSubId();
     }
 
@@ -1436,6 +1585,8 @@
             }
         }
 
+        updateGroupDisabled();
+
         final int preferredUsageSetting = config.getInt(
                 CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT,
                 SubscriptionManager.USAGE_SETTING_UNKNOWN);
@@ -1486,9 +1637,6 @@
     })
     public List<SubscriptionInfo> getAllSubInfoList(@NonNull String callingPackage,
             @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         // Check if the caller has READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or carrier
         // privilege on any active subscription. The carrier app will get full subscription infos
         // on the subs it has carrier privilege.
@@ -1535,9 +1683,6 @@
     })
     public SubscriptionInfo getActiveSubscriptionInfo(int subId, @NonNull String callingPackage,
             @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
                 callingFeatureId, "getActiveSubscriptionInfo")) {
             throw new SecurityException("Need READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or "
@@ -1569,9 +1714,6 @@
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public SubscriptionInfo getActiveSubscriptionInfoForIccId(@NonNull String iccId,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         enforcePermissions("getActiveSubscriptionInfoForIccId",
                 Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
 
@@ -1608,9 +1750,6 @@
     })
     public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         int subId = mSlotIndexToSubId.getOrDefault(slotIndex,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
@@ -1646,8 +1785,6 @@
      *
      * @return Sorted list of the currently {@link SubscriptionInfo} records available on the
      * device.
-     *
-     * @throws SecurityException if the caller does not have required permissions.
      */
     @Override
     @NonNull
@@ -1658,17 +1795,18 @@
     })
     public List<SubscriptionInfo> getActiveSubscriptionInfoList(@NonNull String callingPackage,
             @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         // Check if the caller has READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or carrier
         // privilege on any active subscription. The carrier app will get full subscription infos
         // on the subs it has carrier privilege.
         if (!TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(mContext,
                 Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, callingFeatureId,
                 "getAllSubInfoList")) {
-            throw new SecurityException("Need READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or "
-                    + "carrier privilege");
+            // Ideally we should avoid silent failure, but since this API has already been used by
+            // many apps and they do not expect the security exception, we return an empty list
+            // here so it's consistent with pre-U behavior.
+            loge("getActiveSubscriptionInfoList: " + callingPackage + " does not have enough "
+                    + "permission. Returning empty list here.");
+            return Collections.emptyList();
         }
 
         return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
@@ -1701,9 +1839,6 @@
     })
     public int getActiveSubInfoCount(@NonNull String callingPackage,
             @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         if (!TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(mContext,
                 Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, callingFeatureId,
                 "getAllSubInfoList")) {
@@ -1800,10 +1935,13 @@
             return null;
         }
 
+        // Verify that the callingPackage belongs to the calling UID
+        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
+
         return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
                 .map(SubscriptionInfoInternal::toSubscriptionInfo)
-                .filter(subInfo -> mSubscriptionManager
-                        .canManageSubscription(subInfo, callingPackage))
+                .filter(subInfo -> subInfo.isEmbedded()
+                        && mSubscriptionManager.canManageSubscription(subInfo, callingPackage))
                 .sorted(Comparator.comparing(SubscriptionInfo::getSimSlotIndex)
                         .thenComparing(SubscriptionInfo::getSubscriptionId))
                 .collect(Collectors.toList());
@@ -1813,7 +1951,6 @@
      * @see SubscriptionManager#requestEmbeddedSubscriptionInfoListRefresh
      */
     @Override
-    // TODO: Remove this after SubscriptionController is removed.
     public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
         updateEmbeddedSubscriptions(List.of(cardId), null);
     }
@@ -1834,10 +1971,11 @@
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public int addSubInfo(@NonNull String iccId, @NonNull String displayName, int slotIndex,
             @SubscriptionType int subscriptionType) {
-        log("addSubInfo: iccId=" + SubscriptionInfo.givePrintableIccid(iccId) + ", slotIndex="
-                + slotIndex + ", displayName=" + displayName + ", type="
-                + SubscriptionManager.subscriptionTypeToString(subscriptionType));
         enforcePermissions("addSubInfo", Manifest.permission.MODIFY_PHONE_STATE);
+        logl("addSubInfo: iccId=" + SubscriptionInfo.getPrintableId(iccId) + ", slotIndex="
+                + slotIndex + ", displayName=" + displayName + ", type="
+                + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
+                + getCallingPackage());
 
         // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
@@ -1858,16 +1996,11 @@
                     loge("Already a subscription on slot " + slotIndex);
                     return -1;
                 }
-                int subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(
-                        new SubscriptionInfoInternal.Builder()
-                                .setIccId(iccId)
-                                .setSimSlotIndex(slotIndex)
-                                .setDisplayName(displayName)
-                                .setIconTint(getColor())
-                                .setType(subscriptionType)
-                                .build()
-                );
+
+                int subId = insertSubscriptionInfo(iccId, slotIndex, displayName, subscriptionType);
+                updateGroupDisabled();
                 mSlotIndexToSubId.put(slotIndex, subId);
+                logl("addSubInfo: current mapping " + slotMappingToString());
             } else {
                 // Record already exists.
                 loge("Subscription record already existed.");
@@ -1886,31 +2019,34 @@
      * subscription type.
      * @param subscriptionType the type of subscription to be removed.
      *
-     * // TODO: Remove this terrible return value once SubscriptionController is removed.
-     * @return 0 if success, < 0 on error.
+     * @return {@code true} if succeeded, otherwise {@code false}.
      *
      * @throws NullPointerException if {@code uniqueId} is {@code null}.
      * @throws SecurityException if callers do not hold the required permission.
      */
     @Override
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public int removeSubInfo(@NonNull String uniqueId, int subscriptionType) {
+    public boolean removeSubInfo(@NonNull String uniqueId, int subscriptionType) {
         enforcePermissions("removeSubInfo", Manifest.permission.MODIFY_PHONE_STATE);
 
+        logl("removeSubInfo: uniqueId=" + SubscriptionInfo.getPrintableId(uniqueId) + ", "
+                + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
+                + getCallingPackage());
         final long identity = Binder.clearCallingIdentity();
         try {
             SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
                     .getSubscriptionInfoInternalByIccId(uniqueId);
             if (subInfo == null) {
                 loge("Cannot find subscription with uniqueId " + uniqueId);
-                return -1;
+                return false;
             }
             if (subInfo.getSubscriptionType() != subscriptionType) {
                 loge("The subscription type does not match.");
-                return -1;
+                return false;
             }
+            mSlotIndexToSubId.remove(subInfo.getSimSlotIndex());
             mSubscriptionDatabaseManager.removeSubscriptionInfo(subInfo.getSubscriptionId());
-            return 0;
+            return true;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -1966,6 +2102,7 @@
             @SimDisplayNameSource int nameSource) {
         enforcePermissions("setDisplayNameUsingSrc", Manifest.permission.MODIFY_PHONE_STATE);
 
+        String callingPackage = getCallingPackage();
         final long identity = Binder.clearCallingIdentity();
         try {
             Objects.requireNonNull(displayName, "setDisplayNameUsingSrc");
@@ -2013,6 +2150,9 @@
                 nameToSet = displayName;
             }
 
+            logl("setDisplayNameUsingSrc: subId=" + subId + ", name=" + nameToSet
+                    + ", nameSource=" + SubscriptionManager.displayNameSourceToString(nameSource)
+                    + ", calling package=" + callingPackage);
             mSubscriptionDatabaseManager.setDisplayName(subId, nameToSet);
             mSubscriptionDatabaseManager.setDisplayNameSource(subId, nameSource);
 
@@ -2050,11 +2190,13 @@
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public int setDisplayNumber(@NonNull String number, int subId) {
         enforcePermissions("setDisplayNumber", Manifest.permission.MODIFY_PHONE_STATE);
-
+        logl("setDisplayNumber: subId=" + subId + ", number="
+                + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, number)
+                + ", calling package=" + getCallingPackage());
         // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
         try {
-            mSubscriptionDatabaseManager.setDisplayName(subId, number);
+            mSubscriptionDatabaseManager.setNumber(subId, number);
             return 1;
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -2109,9 +2251,6 @@
             "carrier privileges",
     })
     public int setOpportunistic(boolean opportunistic, int subId, @NonNull String callingPackage) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
                 mContext, Binder.getCallingUid(), subId, true, "setOpportunistic",
                 Manifest.permission.MODIFY_PHONE_STATE);
@@ -2179,6 +2318,7 @@
                 mSubscriptionDatabaseManager.setGroupUuid(subId, uuidString);
                 mSubscriptionDatabaseManager.setGroupOwner(subId, callingPackage);
             }
+            updateGroupDisabled();
 
             MultiSimSettingController.getInstance().notifySubscriptionGroupChanged(groupUUID);
             return groupUUID;
@@ -2265,8 +2405,6 @@
      * @param callingFeatureId The feature in the package.
      *
      * @return The list of opportunistic subscription info that can be accessed by the callers.
-     *
-     * @throws SecurityException if callers do not hold the required permission.
      */
     @Override
     @NonNull
@@ -2277,17 +2415,18 @@
     })
     public List<SubscriptionInfo> getOpportunisticSubscriptions(@NonNull String callingPackage,
             @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         // Check if the caller has READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or carrier
         // privilege on any active subscription. The carrier app will get full subscription infos
         // on the subs it has carrier privilege.
         if (!TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(mContext,
                 Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, callingFeatureId,
                 "getOpportunisticSubscriptions")) {
-            throw new SecurityException("Need READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or "
-                    + "carrier privilege");
+            // Ideally we should avoid silent failure, but since this API has already been used by
+            // many apps and they do not expect the security exception, we return an empty list
+            // here so it's consistent with pre-U behavior.
+            loge("getOpportunisticSubscriptions: " + callingPackage + " does not have enough "
+                    + "permission. Returning empty list here.");
+            return Collections.emptyList();
         }
 
         return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
@@ -2324,9 +2463,6 @@
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void removeSubscriptionsFromGroup(@NonNull int[] subIdList,
             @NonNull ParcelUuid groupUuid, @NonNull String callingPackage) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         // If it doesn't have modify phone state permission, or carrier privilege permission,
         // a SecurityException will be thrown. If it's due to invalid parameter or internal state,
         // it will return null.
@@ -2374,6 +2510,8 @@
                             subInfo.getSubscriptionId(), callingPackage);
                 }
             }
+
+            updateGroupDisabled();
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -2401,9 +2539,6 @@
     })
     public void addSubscriptionsIntoGroup(@NonNull int[] subIdList, @NonNull ParcelUuid groupUuid,
             @NonNull String callingPackage) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         Objects.requireNonNull(subIdList, "subIdList");
         if (subIdList.length == 0) {
             throw new IllegalArgumentException("Invalid subId list");
@@ -2415,6 +2550,9 @@
             throw new IllegalArgumentException("Invalid groupUuid");
         }
 
+        // Verify that the callingPackage belongs to the calling UID
+        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
+
         // If it doesn't have modify phone state permission, or carrier privilege permission,
         // a SecurityException will be thrown.
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -2433,6 +2571,7 @@
                 mSubscriptionDatabaseManager.setGroupOwner(subId, callingPackage);
             }
 
+            updateGroupDisabled();
             MultiSimSettingController.getInstance().notifySubscriptionGroupChanged(groupUuid);
             logl("addSubscriptionsIntoGroup: add subs " + Arrays.toString(subIdList)
                     + " to the group.");
@@ -2476,9 +2615,6 @@
     })
     public List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         // If the calling app neither has carrier privileges nor READ_PHONE_STATE and access to
         // device identifiers, it will throw a SecurityException.
         if (CompatChanges.isChangeEnabled(REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID,
@@ -2554,11 +2690,6 @@
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
 
-    @Override
-    public int[] getSubIds(int slotIndex) {
-        return new int[]{getSubId(slotIndex)};
-    }
-
     /**
      * Update default sub id.
      */
@@ -2592,7 +2723,7 @@
             Intent intent = new Intent(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
             SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId, subId);
-            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
         }
     }
 
@@ -2662,11 +2793,8 @@
             if (mDefaultDataSubId.set(subId)) {
                 MultiSimSettingController.getInstance().notifyDefaultDataSubChanged();
 
-                Intent intent = new Intent(
-                        TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
-                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-                SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+                broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
+                        subId);
 
                 updateDefaultSubId();
             }
@@ -2702,11 +2830,8 @@
         final long token = Binder.clearCallingIdentity();
         try {
             if (mDefaultVoiceSubId.set(subId)) {
-                Intent intent = new Intent(
-                        TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
-                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-                SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+                broadcastSubId(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED,
+                        subId);
 
                 PhoneAccountHandle newHandle = subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
                         ? null : mTelephonyManager.getPhoneAccountHandleForSubscriptionId(subId);
@@ -2751,11 +2876,8 @@
         final long token = Binder.clearCallingIdentity();
         try {
             if (mDefaultSmsSubId.set(subId)) {
-                Intent intent = new Intent(
-                        SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
-                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-                SubscriptionManager.putSubscriptionIdExtra(intent, subId);
-                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+                broadcastSubId(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED,
+                        subId);
             }
 
         } finally {
@@ -2764,6 +2886,19 @@
     }
 
     /**
+     * Broadcast a sub Id with the given action.
+     * @param action The intent action.
+     * @param newSubId The sub Id to broadcast.
+     */
+    private void broadcastSubId(@NonNull String action, int newSubId) {
+        Intent intent = new Intent(action);
+        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+        SubscriptionManager.putSubscriptionIdExtra(intent, newSubId);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+        log("broadcastSubId action: " + action + " subId= " + newSubId);
+    }
+
+    /**
      * Get the active subscription id list.
      *
      * @param visibleOnly {@code true} if only includes user visible subscription's sub id.
@@ -2798,9 +2933,6 @@
      * @param columnName Column name in the database. Note not all fields are supported.
      * @param value Value to store in the database.
      *
-     * // TODO: Remove return value after SubscriptionController is deleted.
-     * @return always 1
-     *
      * @throws IllegalArgumentException if {@code subscriptionId} is invalid, or the field is not
      * exposed.
      * @throws SecurityException if callers do not hold the required permission.
@@ -2810,14 +2942,14 @@
      */
     @Override
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public int setSubscriptionProperty(int subId, @NonNull String columnName,
+    public void setSubscriptionProperty(int subId, @NonNull String columnName,
             @NonNull String value) {
         enforcePermissions("setSubscriptionProperty", Manifest.permission.MODIFY_PHONE_STATE);
 
         final long token = Binder.clearCallingIdentity();
         try {
             logl("setSubscriptionProperty: subId=" + subId + ", columnName=" + columnName
-                    + ", value=" + value);
+                    + ", value=" + value + ", calling package=" + getCallingPackage());
 
             if (!SimInfo.getAllColumns().contains(columnName)) {
                 throw new IllegalArgumentException("Invalid column name " + columnName);
@@ -2831,7 +2963,6 @@
             }
 
             mSubscriptionDatabaseManager.setSubscriptionProperty(subId, columnName, value);
-            return 1;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -2861,9 +2992,6 @@
     })
     public String getSubscriptionProperty(int subId, @NonNull String columnName,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         Objects.requireNonNull(columnName);
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
                 callingPackage, callingFeatureId,
@@ -2901,21 +3029,13 @@
                         + columnName);
             }
         } catch (IllegalArgumentException e) {
-            logv("getSubscriptionProperty: Invalid subId " + subId + ", columnName=" + columnName);
+            loge("getSubscriptionProperty: Invalid subId " + subId + ", columnName=" + columnName);
             return null;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
-    @Override
-    public boolean setSubscriptionEnabled(boolean enable, int subId) {
-        enforcePermissions("setSubscriptionEnabled", Manifest.permission.MODIFY_PHONE_STATE);
-
-
-        return true;
-    }
-
     /**
      * Check if a subscription is active.
      *
@@ -3079,19 +3199,36 @@
      * @param enabled whether uicc applications are enabled or disabled.
      * @param subId which subscription to operate on.
      *
-     * @return the number of records updated.
-     *
      * @throws IllegalArgumentException if the subscription does not exist.
      * @throws SecurityException if callers do not hold the required permission.
      */
     @Override
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public int setUiccApplicationsEnabled(boolean enabled, int subId) {
+    public void setUiccApplicationsEnabled(boolean enabled, int subId) {
         enforcePermissions("setUiccApplicationsEnabled",
                 Manifest.permission.MODIFY_PHONE_STATE);
-        logl("setUiccApplicationsEnabled: subId=" + subId + ", enabled=" + enabled);
-        mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, enabled);
-        return 1;
+        logl("setUiccApplicationsEnabled: subId=" + subId + ", enabled=" + enabled
+                + ", calling package=" + getCallingPackage());
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+
+            SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
+                    .getSubscriptionInfoInternal(subId);
+            if (subInfo == null) {
+                throw new IllegalArgumentException("setUiccApplicationsEnabled: Subscription "
+                        + "doesn't exist. subId=" + subId);
+            }
+
+            if (subInfo.areUiccApplicationsEnabled() != enabled) {
+                mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, enabled);
+                mSubscriptionManagerServiceCallbacks.forEach(
+                        callback -> callback.invokeFromExecutor(
+                                () -> callback.onUiccApplicationsEnabledChanged(subId)));
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     /**
@@ -3193,15 +3330,12 @@
      *
      * @return The phone number, or an empty string if not available.
      *
-     * @throws IllegalArgumentException if {@code source} or {@code subId} is invalid.
+     * @throws IllegalArgumentException if {@code source} is invalid.
      * @throws SecurityException if the caller doesn't have permissions required.
      *
      * @see SubscriptionManager#PHONE_NUMBER_SOURCE_UICC
      * @see SubscriptionManager#PHONE_NUMBER_SOURCE_CARRIER
      * @see SubscriptionManager#PHONE_NUMBER_SOURCE_IMS
-     *
-     * @throws IllegalArgumentException if {@code subId} is invalid.
-     * @throws SecurityException if callers do not hold the required permission.
      */
     @Override
     @NonNull
@@ -3212,9 +3346,6 @@
     })
     public String getPhoneNumber(int subId, @PhoneNumberSource int source,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
                 mContext, subId, Binder.getCallingUid(), "getPhoneNumber",
                 Manifest.permission.READ_PHONE_NUMBERS,
@@ -3226,7 +3357,8 @@
                 .getSubscriptionInfoInternal(subId);
 
         if (subInfo == null) {
-            throw new IllegalArgumentException("Invalid sub id " + subId);
+            loge("Invalid sub id " + subId + ", callingPackage=" + callingPackage);
+            return "";
         }
 
         try {
@@ -3274,9 +3406,6 @@
     })
     public String getPhoneNumberFromFirstAvailableSource(int subId,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
                 mContext, subId, Binder.getCallingUid(), "getPhoneNumberFromFirstAvailableSource",
                 Manifest.permission.READ_PHONE_NUMBERS,
@@ -3320,9 +3449,6 @@
     @RequiresPermission("carrier privileges")
     public void setPhoneNumber(int subId, @PhoneNumberSource int source, @NonNull String number,
             @NonNull String callingPackage, @Nullable String callingFeatureId) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
             throw new SecurityException("setPhoneNumber for CARRIER needs carrier privilege.");
         }
@@ -3360,9 +3486,6 @@
     })
     public int setUsageSetting(@UsageSetting int usageSetting, int subId,
             @NonNull String callingPackage) {
-        // Verify that the callingPackage belongs to the calling UID
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-
         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
                 mContext, Binder.getCallingUid(), subId, true, "setUsageSetting",
                 Manifest.permission.MODIFY_PHONE_STATE);
@@ -3429,12 +3552,6 @@
     public UserHandle getSubscriptionUserHandle(int subId) {
         enforcePermissions("getSubscriptionUserHandle",
                 Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
-
-        if (!mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enable_get_subscription_user_handle)) {
-            return null;
-        }
-
         long token = Binder.clearCallingIdentity();
         try {
             SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
@@ -3445,6 +3562,7 @@
             }
 
             UserHandle userHandle = UserHandle.of(subInfo.getUserId());
+            logv("getSubscriptionUserHandle subId = " + subId + " userHandle = " + userHandle);
             if (userHandle.getIdentifier() == UserHandle.USER_NULL) {
                 return null;
             }
@@ -3460,11 +3578,10 @@
      * @param subscriptionId the subId of the subscription
      * @param userHandle user handle of the user
      * @return {@code true} if subscription is associated with user
-     * {code true} if there are no subscriptions on device
+     * {@code true} if there are no subscriptions on device
      * else {@code false} if subscription is not associated with user.
      *
      * @throws SecurityException if the caller doesn't have permissions required.
-     * @throws IllegalStateException if subscription service is not available.
      *
      */
     @Override
@@ -3482,6 +3599,13 @@
                 return true;
             }
 
+            List<Integer> subIdList = subInfoList.stream().map(SubscriptionInfo::getSubscriptionId)
+                    .collect(Collectors.toList());
+            if (!subIdList.contains(subscriptionId)) {
+                // Return true as this subscription is not available on the device.
+                return true;
+            }
+
             // Get list of subscriptions associated with this user.
             List<SubscriptionInfo> associatedSubscriptionsList =
                     getSubscriptionInfoListAssociatedWithUser(userHandle);
@@ -3511,7 +3635,6 @@
      * @return list of subscriptionInfo associated with the user.
      *
      * @throws SecurityException if the caller doesn't have permissions required.
-     * @throws IllegalStateException if subscription service is not available.
      *
      */
     @Override
@@ -3550,13 +3673,39 @@
     }
 
     /**
-     * @return {@code true} if using {@link SubscriptionManagerService} instead of
-     * {@link SubscriptionController}.
+     * Called during setup wizard restore flow to attempt to restore the backed up sim-specific
+     * configs to device for all existing SIMs in the subscription database {@link SimInfo}.
+     * Internally, it will store the backup data in an internal file. This file will persist on
+     * device for device's lifetime and will be used later on when a SIM is inserted to restore that
+     * specific SIM's settings. End result is subscription database is modified to match any backed
+     * up configs for the appropriate inserted SIMs.
+     *
+     * <p>
+     * The {@link Uri} {@link SubscriptionManager#SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is
+     * notified if any {@link SimInfo} entry is updated as the result of this method call.
+     *
+     * @param data with the sim specific configs to be backed up.
      */
-    //TODO: Removed before U AOSP public release.
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @Override
-    public boolean isSubscriptionManagerServiceEnabled() {
-        return true;
+    public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
+        enforcePermissions("restoreAllSimSpecificSettingsFromBackup",
+                Manifest.permission.MODIFY_PHONE_STATE);
+
+        long token = Binder.clearCallingIdentity();
+        try {
+            Bundle bundle = new Bundle();
+            bundle.putByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
+            logl("restoreAllSimSpecificSettingsFromBackup");
+            mContext.getContentResolver().call(
+                    SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                    SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+                    null, bundle);
+            // After restoring, we need to reload the content provider into the cache.
+            mSubscriptionDatabaseManager.reloadDatabase();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /**
@@ -3623,19 +3772,46 @@
     }
 
     /**
-     * Called when eSIM becomes inactive.
+     * Called when SIM becomes inactive.
      *
      * @param slotIndex The logical SIM slot index.
+     * @param iccId iccId of the SIM in inactivate slot.
      */
-    public void updateSimStateForInactivePort(int slotIndex) {
+    public void updateSimStateForInactivePort(int slotIndex, @NonNull String iccId) {
         mHandler.post(() -> {
-            logl("updateSimStateForInactivePort: slotIndex=" + slotIndex);
+            logl("updateSimStateForInactivePort: slotIndex=" + slotIndex + ", iccId="
+                    + SubscriptionInfo.getPrintableId(iccId));
             if (mSlotIndexToSubId.containsKey(slotIndex)) {
                 // Re-enable the UICC application , so it will be in enabled state when it becomes
-                // active again. (pre-U behavior)
+                // active again. (Pre-U behavior)
                 mSubscriptionDatabaseManager.setUiccApplicationsEnabled(
                         mSlotIndexToSubId.get(slotIndex), true);
-                updateSubscriptions(slotIndex);
+                updateSubscription(slotIndex);
+            }
+            if (!TextUtils.isEmpty(iccId)) {
+                // When port is inactive, sometimes valid iccid is present in the slot status,
+                // hence update the portIndex. (Pre-U behavior)
+                SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
+                        .getSubscriptionInfoInternalByIccId(IccUtils.stripTrailingFs(iccId));
+                int subId;
+                if (subInfo != null) {
+                    subId = subInfo.getSubscriptionId();
+                    log("updateSimStateForInactivePort: Found existing subscription. subId="
+                            + subId);
+                } else {
+                    // If iccId is new, add a subscription record in the database so it can be
+                    // activated later. (Pre-U behavior)
+                    subId = insertSubscriptionInfo(IccUtils.stripTrailingFs(iccId),
+                            SubscriptionManager.INVALID_SIM_SLOT_INDEX, "",
+                            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
+                    mSubscriptionDatabaseManager.setDisplayName(subId,
+                            mContext.getResources().getString(R.string.default_card_name, subId));
+                    log("updateSimStateForInactivePort: Insert a new subscription for inactive SIM."
+                            + " subId=" + subId);
+                }
+                if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                    mSubscriptionDatabaseManager.setPortIndex(subId, getPortIndex(iccId));
+                }
             }
         });
     }
@@ -3667,7 +3843,7 @@
                 case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
                 case TelephonyManager.SIM_STATE_LOADED:
                 case TelephonyManager.SIM_STATE_NOT_READY:
-                    updateSubscriptions(slotIndex);
+                    updateSubscription(slotIndex);
                     break;
                 case TelephonyManager.SIM_STATE_CARD_RESTRICTED:
                 default:
@@ -3682,6 +3858,53 @@
     }
 
     /**
+     * Get the calling package(s).
+     *
+     * @return The calling package(s).
+     */
+    @NonNull
+    private String getCallingPackage() {
+        if (Binder.getCallingUid() == Process.PHONE_UID) {
+            // Too many packages running with phone uid. Just return one here.
+            return "com.android.phone";
+        }
+        return Arrays.toString(mContext.getPackageManager().getPackagesForUid(
+                Binder.getCallingUid()));
+    }
+
+    /**
+     * Update the {@link SubscriptionInfo#isGroupDisabled()} bit for the opportunistic
+     * subscriptions.
+     *
+     * If all primary (non-opportunistic) subscriptions in the group are deactivated
+     * (unplugged pSIM or deactivated eSIM profile), we should disable this opportunistic
+     * subscriptions.
+     */
+    @VisibleForTesting
+    public void updateGroupDisabled() {
+        List<SubscriptionInfo> activeSubscriptions = getActiveSubscriptionInfoList(
+                mContext.getOpPackageName(), mContext.getFeatureId());
+        for (SubscriptionInfo oppSubInfo : getOpportunisticSubscriptions(
+                mContext.getOpPackageName(), mContext.getFeatureId())) {
+            boolean groupDisabled = activeSubscriptions.stream()
+                    .noneMatch(subInfo -> !subInfo.isOpportunistic()
+                            && Objects.equals(oppSubInfo.getGroupUuid(), subInfo.getGroupUuid()));
+            mSubscriptionDatabaseManager.setGroupDisabled(
+                    oppSubInfo.getSubscriptionId(), groupDisabled);
+        }
+    }
+
+    /**
+     * @return The logical SIM slot/sub mapping to string.
+     */
+    @NonNull
+    private String slotMappingToString() {
+        return "[" + mSlotIndexToSubId.entrySet().stream()
+                .map(e -> "slot " + e.getKey() + ": subId=" + e.getValue())
+                .collect(Collectors.joining(", ")) + "]";
+    }
+
+    /**
      * Log debug messages.
      *
      * @param s debug messages
@@ -3700,15 +3923,6 @@
     }
 
     /**
-     * Log verbose messages.
-     *
-     * @param s debug messages.
-     */
-    private void logv(@NonNull String s) {
-        if (VDBG) Rlog.v(LOG_TAG, s);
-    }
-
-    /**
      * Log debug messages and also log into the local log.
      *
      * @param s debug messages
@@ -3719,6 +3933,15 @@
     }
 
     /**
+     * Log verbose messages.
+     *
+     * @param s verbose messages
+     */
+    private void logv(@NonNull String s) {
+        Rlog.v(LOG_TAG, s);
+    }
+
+    /**
      * Dump the state of {@link SubscriptionManagerService}.
      *
      * @param fd File descriptor
@@ -3727,70 +3950,87 @@
      */
     public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter printWriter,
             @NonNull String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(SubscriptionManagerService.class.getSimpleName() + ":");
-        pw.println("Logical SIM slot sub id mapping:");
-        pw.increaseIndent();
-        mSlotIndexToSubId.forEach((slotIndex, subId)
-                -> pw.println("Logical SIM slot " + slotIndex + ": subId=" + subId));
-        pw.decreaseIndent();
-        pw.println();
-        pw.println("defaultSubId=" + getDefaultSubId());
-        pw.println("defaultVoiceSubId=" + getDefaultVoiceSubId());
-        pw.println("defaultDataSubId=" + getDefaultDataSubId());
-        pw.println("activeDataSubId=" + getActiveDataSubscriptionId());
-        pw.println("defaultSmsSubId=" + getDefaultSmsSubId());
-        pw.println("areAllSubscriptionsLoaded=" + areAllSubscriptionsLoaded());
-        pw.println();
-        for (int i = 0; i < mSimState.length; i++) {
-            pw.println("mSimState[" + i + "]=" + TelephonyManager.simStateToString(mSimState[i]));
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
+                "Requires android.Manifest.permission.DUMP");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+            pw.println(SubscriptionManagerService.class.getSimpleName() + ":");
+            pw.println("Active modem count=" + mTelephonyManager.getActiveModemCount());
+            pw.println("Logical SIM slot sub id mapping:");
+            pw.increaseIndent();
+            mSlotIndexToSubId.forEach((slotIndex, subId)
+                    -> pw.println("Logical SIM slot " + slotIndex + ": subId=" + subId));
+            pw.decreaseIndent();
+            pw.println("ICCID:");
+            pw.increaseIndent();
+            for (int i = 0; i < mTelephonyManager.getActiveModemCount(); i++) {
+                pw.println("slot " + i + ": " + SubscriptionInfo.getPrintableId(getIccId(i)));
+            }
+            pw.decreaseIndent();
+            pw.println();
+            pw.println("defaultSubId=" + getDefaultSubId());
+            pw.println("defaultVoiceSubId=" + getDefaultVoiceSubId());
+            pw.println("defaultDataSubId=" + getDefaultDataSubId());
+            pw.println("activeDataSubId=" + getActiveDataSubscriptionId());
+            pw.println("defaultSmsSubId=" + getDefaultSmsSubId());
+            pw.println("areAllSubscriptionsLoaded=" + areAllSubscriptionsLoaded());
+            pw.println();
+            for (int i = 0; i < mSimState.length; i++) {
+                pw.println("mSimState[" + i + "]="
+                        + TelephonyManager.simStateToString(mSimState[i]));
+            }
+
+            pw.println();
+            pw.println("Active subscriptions:");
+            pw.increaseIndent();
+            mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                    .filter(SubscriptionInfoInternal::isActive).forEach(pw::println);
+            pw.decreaseIndent();
+
+            pw.println();
+            pw.println("All subscriptions:");
+            pw.increaseIndent();
+            mSubscriptionDatabaseManager.getAllSubscriptions().forEach(pw::println);
+            pw.decreaseIndent();
+            pw.println();
+
+            pw.print("Embedded subscriptions: [");
+            pw.println(mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                    .filter(SubscriptionInfoInternal::isEmbedded)
+                    .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
+                    .collect(Collectors.joining(", ")) + "]");
+
+            pw.print("Opportunistic subscriptions: [");
+            pw.println(mSubscriptionDatabaseManager.getAllSubscriptions().stream()
+                    .filter(SubscriptionInfoInternal::isOpportunistic)
+                    .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
+                    .collect(Collectors.joining(", ")) + "]");
+
+            pw.print("getAvailableSubscriptionInfoList: [");
+            pw.println(getAvailableSubscriptionInfoList(
+                    mContext.getOpPackageName(), mContext.getFeatureId()).stream()
+                    .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
+                    .collect(Collectors.joining(", ")) + "]");
+
+            pw.print("getSelectableSubscriptionInfoList: [");
+            pw.println(mSubscriptionManager.getSelectableSubscriptionInfoList().stream()
+                    .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
+                    .collect(Collectors.joining(", ")) + "]");
+
+            if (mEuiccManager != null) {
+                pw.println("Euicc enabled=" + mEuiccManager.isEnabled());
+            }
+            pw.println();
+            pw.println("Local log:");
+            pw.increaseIndent();
+            mLocalLog.dump(fd, pw, args);
+            pw.decreaseIndent();
+            pw.decreaseIndent();
+            pw.println();
+            mSubscriptionDatabaseManager.dump(fd, pw, args);
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-
-        pw.println();
-        pw.println("Active subscriptions:");
-        pw.increaseIndent();
-        mSubscriptionDatabaseManager.getAllSubscriptions().stream()
-                .filter(SubscriptionInfoInternal::isActive).forEach(pw::println);
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println("All subscriptions:");
-        pw.increaseIndent();
-        mSubscriptionDatabaseManager.getAllSubscriptions().forEach(pw::println);
-        pw.decreaseIndent();
-        pw.println();
-
-        pw.print("Embedded subscriptions: [");
-        pw.println(mSubscriptionDatabaseManager.getAllSubscriptions().stream()
-                .filter(SubscriptionInfoInternal::isEmbedded)
-                .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
-                .collect(Collectors.joining(", ")) + "]");
-
-        pw.print("Opportunistic subscriptions: [");
-        pw.println(mSubscriptionDatabaseManager.getAllSubscriptions().stream()
-                .filter(SubscriptionInfoInternal::isOpportunistic)
-                .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
-                .collect(Collectors.joining(", ")) + "]");
-
-        pw.print("getAvailableSubscriptionInfoList: [");
-        pw.println(getAvailableSubscriptionInfoList(
-                mContext.getOpPackageName(), mContext.getFeatureId()).stream()
-                .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
-                .collect(Collectors.joining(", ")) + "]");
-
-        pw.print("getSelectableSubscriptionInfoList: [");
-        pw.println(mSubscriptionManager.getSelectableSubscriptionInfoList().stream()
-                .map(subInfo -> String.valueOf(subInfo.getSubscriptionId()))
-                .collect(Collectors.joining(", ")) + "]");
-
-        if (mEuiccManager != null) {
-            pw.println("Euicc enabled=" + mEuiccManager.isEnabled());
-        }
-        pw.println();
-        pw.println("Local log:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
index 21a6e37..90c9491 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
@@ -23,10 +23,12 @@
 import android.os.Message;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.gsm.UsimPhoneBookManager;
 
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Locale;
 
 /**
  * {@hide}
@@ -58,14 +60,16 @@
     static final int EVENT_UPDATE_ADN_DONE = 2;
 
     //***** Constructor
-
-
-
     AdnRecordCache(IccFileHandler fh) {
         mFh = fh;
         mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this);
     }
 
+    public AdnRecordCache(IccFileHandler fh, UsimPhoneBookManager usimPhoneBookManager) {
+        mFh = fh;
+        mUsimPhoneBookManager = usimPhoneBookManager;
+    }
+
     //***** Called from SIMRecords
 
     /**
@@ -156,14 +160,14 @@
         int extensionEF = extensionEfForEf(efid);
         if (extensionEF < 0) {
             sendErrorResponse(response, "EF is not known ADN-like EF:0x" +
-                    Integer.toHexString(efid).toUpperCase());
+                    Integer.toHexString(efid).toUpperCase(Locale.ROOT));
             return;
         }
 
         Message pendingResponse = mUserWriteResponse.get(efid);
         if (pendingResponse != null) {
             sendErrorResponse(response, "Have pending update for EF:0x" +
-                    Integer.toHexString(efid).toUpperCase());
+                    Integer.toHexString(efid).toUpperCase(Locale.ROOT));
             return;
         }
 
@@ -190,16 +194,14 @@
      */
     public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
             String pin2, Message response) {
-
         int extensionEF;
         extensionEF = extensionEfForEf(efid);
 
         if (extensionEF < 0) {
             sendErrorResponse(response, "EF is not known ADN-like EF:0x" +
-                    Integer.toHexString(efid).toUpperCase());
+                    Integer.toHexString(efid).toUpperCase(Locale.ROOT));
             return;
         }
-
         ArrayList<AdnRecord>  oldAdnList;
 
         if (efid == EF_PBR) {
@@ -207,13 +209,11 @@
         } else {
             oldAdnList = getRecordsIfLoaded(efid);
         }
-
         if (oldAdnList == null) {
             sendErrorResponse(response, "Adn list not exist for EF:0x" +
-                    Integer.toHexString(efid).toUpperCase());
+                    Integer.toHexString(efid).toUpperCase(Locale.ROOT));
             return;
         }
-
         int index = -1;
         int count = 1;
         for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
@@ -223,7 +223,6 @@
             }
             count++;
         }
-
         if (index == -1) {
             sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
             return;
@@ -244,7 +243,7 @@
 
         if (pendingResponse != null) {
             sendErrorResponse(response, "Have pending update for EF:0x" +
-                    Integer.toHexString(efid).toUpperCase());
+                    Integer.toHexString(efid).toUpperCase(Locale.ROOT));
             return;
         }
 
@@ -307,7 +306,7 @@
             if (response != null) {
                 AsyncResult.forMessage(response).exception
                     = new RuntimeException("EF is not known ADN-like EF:0x" +
-                        Integer.toHexString(efid).toUpperCase());
+                        Integer.toHexString(efid).toUpperCase(Locale.ROOT));
                 response.sendToTarget();
             }
 
@@ -342,7 +341,6 @@
     handleMessage(Message msg) {
         AsyncResult ar;
         int efid;
-
         switch(msg.what) {
             case EVENT_LOAD_ALL_ADN_LIKE_DONE:
                 /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/
@@ -381,4 +379,24 @@
                 break;
         }
     }
+
+    @VisibleForTesting
+    protected void setAdnLikeWriters(int key, ArrayList<Message> waiters) {
+        mAdnLikeWaiters.put(EF_MBDN, waiters);
+    }
+
+    @VisibleForTesting
+    protected void setAdnLikeFiles(int key, ArrayList<AdnRecord> adnRecordList) {
+        mAdnLikeFiles.put(EF_MBDN, adnRecordList);
+    }
+
+    @VisibleForTesting
+    protected void setUserWriteResponse(int key, Message message) {
+        mUserWriteResponse.put(EF_MBDN, message);
+    }
+
+    @VisibleForTesting
+    protected UsimPhoneBookManager getUsimPhoneBookManager() {
+        return mUsimPhoneBookManager;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
index a688c6e..5b0a6a3 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
@@ -59,6 +59,7 @@
     static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4;
     static final int EVENT_UPDATE_RECORD_DONE = 5;
 
+    static final int VOICEMAIL_ALPHATAG_ARG = 1;
     //***** Constructor
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -177,14 +178,34 @@
                     data = adn.buildAdnString(recordSize[0]);
 
                     if(data == null) {
-                        throw new RuntimeException("wrong ADN format",
-                                ar.exception);
+                        /**
+                         * The voicemail number saving to the SIM is in name(alphaTag) and number
+                         * format. {@link recordSize[0]} indicates the SIM EF memory size that the
+                         * sim can have to save both voicemail name and number. 14 byte of memory
+                         * is reserved to save the voicemail number and remaining memory is reserved
+                         * for the alphaTag. In case if we receive the alphaTag which is more than
+                         * the reserved memory size then SIM will throw the exception and it don't
+                         * save both the voicemail number and alphaTag. To avoid this problem, in
+                         * case alphaTag length is more we nullify the alphaTag and save the same.
+                         */
+                        if (mUserResponse.arg1 == VOICEMAIL_ALPHATAG_ARG) {
+                            adn.mAlphaTag = null;
+                            data = adn.buildAdnString(recordSize[0]);
+                        }
+                        if (data == null) {
+                            throw new RuntimeException("wrong ADN format",
+                                    ar.exception);
+                        }
                     }
 
-
-                    mFh.updateEFLinearFixed(mEf, getEFPath(mEf), mRecordNumber,
-                            data, mPin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
-
+                    // Send adn record to caller to track the changes made to alphaTag
+                    if (mUserResponse.arg1 == VOICEMAIL_ALPHATAG_ARG) {
+                        mFh.updateEFLinearFixed(mEf, getEFPath(mEf), mRecordNumber,
+                                data, mPin2, obtainMessage(EVENT_UPDATE_RECORD_DONE, adn));
+                    } else {
+                        mFh.updateEFLinearFixed(mEf, getEFPath(mEf), mRecordNumber,
+                                data, mPin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
+                    }
                     mPendingExtLoads = 1;
 
                     break;
@@ -195,7 +216,12 @@
                                 ar.exception);
                     }
                     mPendingExtLoads = 0;
-                    mResult = null;
+                    // send the adn record back to caller through the result of AsyncResult
+                    if (mUserResponse.arg1 == VOICEMAIL_ALPHATAG_ARG) {
+                        mResult =  ar.userObj;
+                    } else {
+                        mResult = null;
+                    }
                     break;
                 case EVENT_ADN_LOAD_DONE:
                     ar = (AsyncResult)(msg.obj);
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
index ec07780..f0d949d 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
@@ -20,6 +20,7 @@
 import android.os.Build;
 import android.telephony.SubscriptionInfo;
 
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
@@ -90,6 +91,30 @@
 
     public IccSlotPortMapping mSlotPortMapping;
 
+    public MultipleEnabledProfilesMode mSupportedMepMode = MultipleEnabledProfilesMode.NONE;
+
+    /**
+     * Set the MultipleEnabledProfilesMode according to the input mode.
+     */
+    public void setMultipleEnabledProfilesMode(int mode) {
+        switch(mode) {
+            case 0:
+                mSupportedMepMode = MultipleEnabledProfilesMode.NONE;
+                break;
+            case 1:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_A1;
+                break;
+            case 2:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_A2;
+                break;
+            case 3:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_MultipleEnabledProfilesMode: " + mode);
+        }
+    }
+
     public void setCardState(int state) {
         switch(state) {
         case 0:
@@ -172,8 +197,9 @@
         }
 
         sb.append(",atr=").append(atr);
-        sb.append(",iccid=").append(SubscriptionInfo.givePrintableIccid(iccid));
+        sb.append(",iccid=").append(SubscriptionInfo.getPrintableId(iccid));
         sb.append(",eid=").append(Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid));
+        sb.append(",SupportedMepMode=").append(mSupportedMepMode);
         sb.append(",SlotPortMapping=").append(mSlotPortMapping);
 
         sb.append("}");
diff --git a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
index 6c4ac69..5f8ccb4 100644
--- a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
+++ b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.Message;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
 
 import java.util.ArrayList;
@@ -108,7 +109,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected final String mAid;
 
-    static class LoadLinearFixedContext {
+    public static class LoadLinearFixedContext {
 
         int mEfid;
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -145,14 +146,11 @@
             mOnLoaded = onLoaded;
             mPath = path;
         }
+    }
 
-        LoadLinearFixedContext(int efid, Message onLoaded) {
-            mEfid = efid;
-            mRecordNum = 1;
-            mLoadAll = true;
-            mOnLoaded = onLoaded;
-            mPath = null;
-        }
+    @VisibleForTesting
+    public int getEfid(LoadLinearFixedContext lc) {
+        return lc.mEfid;
     }
 
     /**
@@ -164,6 +162,13 @@
         mCi = ci;
     }
 
+    @VisibleForTesting
+    public IccFileHandler(CommandsInterface ci) {
+        mParentApp = null;
+        mAid = null;
+        mCi = ci;
+    }
+
     public void dispose() {
     }
 
@@ -267,8 +272,7 @@
      * @param path Path of the EF on the card
      * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of data int
      */
-    public void getEFTransparentRecordSize(int fileid, String path, Message onLoaded) {
-        String efPath = (path == null) ? getEFPath(fileid) : path;
+    public void getEFTransparentRecordSize(int fileid, Message onLoaded) {
         Message response = obtainMessage(EVENT_GET_EF_TRANSPARENT_SIZE_DONE, fileid, 0, onLoaded);
         mCi.iccIOForApp(
                 COMMAND_GET_RESPONSE,
@@ -284,16 +288,6 @@
     }
 
     /**
-     * Get record size for a transparent EF
-     *
-     * @param fileid EF id
-     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of the data int
-     */
-    public void getEFTransparentRecordSize(int fileid, Message onLoaded) {
-        getEFTransparentRecordSize(fileid, getEFPath(fileid), onLoaded);
-    }
-
-    /**
      * Load all records from a SIM Linear Fixed EF
      *
      * @param fileid EF id
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index da112b1..f803696 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -257,6 +257,8 @@
     // call back received on this upon EF_SMSS record update.
     public static final int EVENT_SET_SMSS_RECORD_DONE = 201;
 
+    private static final int EVENT_GET_FDN_DONE = 202;
+
     /**
      * There are two purposes for this class. First, each instance of AuthAsyncResponse acts as a
      * lock to for calling thead to wait in getIccSimChallengeResponse(). Second, pass the IMS
@@ -269,7 +271,7 @@
 
     @Override
     public String toString() {
-        String iccIdToPrint = SubscriptionInfo.givePrintableIccid(mFullIccId);
+        String iccIdToPrint = SubscriptionInfo.getPrintableId(mFullIccId);
         return "mDestroyed=" + mDestroyed
                 + " mContext=" + mContext
                 + " mCi=" + mCi
@@ -999,6 +1001,15 @@
                 }
                 break;
 
+            case EVENT_GET_FDN_DONE:
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    loge("Failed to read USIM EF_FDN field error=" + ar.exception);
+                } else {
+                    log("EF_FDN read successfully");
+                }
+                break;
+
             default:
                 super.handleMessage(msg);
         }
@@ -1428,7 +1439,7 @@
         pw.println(" mRecordsToLoad=" + mRecordsToLoad);
         pw.println(" mRdnCache=" + mAdnCache);
 
-        String iccIdToPrint = SubscriptionInfo.givePrintableIccid(mFullIccId);
+        String iccIdToPrint = SubscriptionInfo.getPrintableId(mFullIccId);
         pw.println(" iccid=" + iccIdToPrint);
         pw.println(" mMsisdn=" + Rlog.pii(VDBG, mMsisdn));
         pw.println(" mMsisdnTag=" + mMsisdnTag);
@@ -1674,4 +1685,12 @@
             return mMsg;
         }
     }
+
+    public void loadFdnRecords() {
+        if (mParentApp != null) {
+            log("Loading FdnRecords");
+            mAdnCache.requestLoadAllAdnLike(IccConstants.EF_FDN, EF_EXT2,
+                    obtainMessage(EVENT_GET_FDN_DONE));
+        }
+    }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java b/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java
index 9a5e10d..4164a1e 100644
--- a/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java
+++ b/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java
@@ -51,7 +51,7 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("{").append("iccid=")
-                .append(SubscriptionInfo.givePrintableIccid(mIccId)).append(",")
+                .append(SubscriptionInfo.getPrintableId(mIccId)).append(",")
                 .append("logicalSlotIndex=").append(mLogicalSlotIndex).append(",")
                 .append("portActive=").append(mPortActive)
                 .append("}");
diff --git a/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java b/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
index 96a3a33..8e55f7c 100644
--- a/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
@@ -30,11 +30,46 @@
     /* Added state active to check slotState in old HAL case.*/
     public static final int STATE_ACTIVE = 1;
 
+    public enum MultipleEnabledProfilesMode {
+        /**
+         * If there is no jointly supported MEP mode, set supported MEP mode to NONE.
+         */
+        NONE,
+        /**
+         * In case of MEP-A1, the ISD-R is selected on eSIM port 0 only and profiles are selected
+         * on eSIM ports 1 and higher, with the eSIM port being assigned by the LPA or platform.
+         */
+        MEP_A1,
+        /**
+         * In case of MEP-A2, the ISD-R is selected on eSIM port 0 only and profiles are selected
+         * on eSIM ports 1 and higher, with the eSIM port being assigned by the eUICC.
+         */
+        MEP_A2,
+        /**
+         * In case of MEP-B, profiles are selected on eSIM ports 0 and higher, with the ISD-R being
+         * selectable on any of these eSIM ports.
+         */
+        MEP_B;
+
+        public boolean isMepAMode() {
+            return (this == MEP_A1 || this == MEP_A2);
+        }
+
+        public boolean isMepA1Mode() {
+            return this == MEP_A1;
+        }
+
+        public boolean isMepMode() {
+            return this != NONE;
+        }
+    }
+
     public IccCardStatus.CardState  cardState;
     public String     atr;
     public String     eid;
 
     public IccSimPortInfo[] mSimPortInfos;
+    public MultipleEnabledProfilesMode mSupportedMepMode = MultipleEnabledProfilesMode.NONE;
 
     /**
      * Set the cardState according to the input state.
@@ -58,6 +93,28 @@
         }
     }
 
+    /**
+     * Set the MultipleEnabledProfilesMode according to the input mode.
+     */
+    public void setMultipleEnabledProfilesMode(int mode) {
+        switch(mode) {
+            case 0:
+                mSupportedMepMode = MultipleEnabledProfilesMode.NONE;
+                break;
+            case 1:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_A1;
+                break;
+            case 2:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_A2;
+                break;
+            case 3:
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_MultipleEnabledProfilesMode: " + mode);
+        }
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -72,6 +129,7 @@
         } else {
             sb.append("num_ports=null");
         }
+        sb.append(", SupportedMepMode=" + mSupportedMepMode);
         sb.append("}");
         return sb.toString();
     }
diff --git a/src/java/com/android/internal/telephony/uicc/InstallCarrierAppUtils.java b/src/java/com/android/internal/telephony/uicc/InstallCarrierAppUtils.java
index 412295d..7666f4c 100644
--- a/src/java/com/android/internal/telephony/uicc/InstallCarrierAppUtils.java
+++ b/src/java/com/android/internal/telephony/uicc/InstallCarrierAppUtils.java
@@ -38,6 +38,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Utility methods for installing the carrier app when a SIM is insterted without the carrier app
@@ -178,7 +179,7 @@
      */
     @VisibleForTesting
     public static String getAppNameFromPackageName(String packageName, String mapString) {
-        packageName = packageName.toLowerCase();
+        packageName = packageName.toLowerCase(Locale.ROOT);
         final String pairDelim = "\\s*;\\s*";
         final String keyValueDelim = "\\s*:\\s*";
 
diff --git a/src/java/com/android/internal/telephony/uicc/IsimServiceTable.java b/src/java/com/android/internal/telephony/uicc/IsimServiceTable.java
new file mode 100644
index 0000000..289229c
--- /dev/null
+++ b/src/java/com/android/internal/telephony/uicc/IsimServiceTable.java
@@ -0,0 +1,56 @@
+/*
+ * 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.uicc;
+
+public final class IsimServiceTable extends IccServiceTable {
+    private static final String TAG = "IsimServiceTable";
+    public enum IsimService {
+        PCSCF_ADDRESS,
+        GBA,                                // Generic Bootstrapping Architecture (GBA)
+        HTTP_DIGEST,
+        GBA_LOCALKEY_ESTABLISHMENT,         // GBA-based Local Key Establishment Mechanism
+        PCSCF_DISCOVERY_FOR_IMS,            // Support of P-CSCF discovery for IMS Local Break Out
+        SMS,
+        SMSR,                               // Short Message Status Reports
+        SM_OVERIP_AND_DATA_DL_VIA_SMS_PP,   // Support for SM-over-IP including data download via
+        // SMS-PP
+        COMMUNICATION_CONTROL_FOR_IMS_BY_ISIM,
+        UICC_ACCESS_TO_IMS
+    }
+
+    public IsimServiceTable(byte[] table) {
+        super(table);
+    }
+
+    public boolean isAvailable(IsimService service) {
+        return super.isAvailable(service.ordinal());
+    }
+
+    @Override
+    protected String getTag() {
+        return TAG;
+    }
+
+    @Override
+    protected Object[] getValues() {
+        return IsimService.values();
+    }
+
+    public byte[] getISIMServiceTable() {
+        return mServiceTable;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index f9b51cf..9591a498 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -225,6 +225,11 @@
         }
     }
 
+    @VisibleForTesting
+    public EfIsimIstLoaded getIsimIstObject() {
+        return new EfIsimIstLoaded();
+    }
+
     private class EfIsimSmssLoaded implements IccRecords.IccRecordLoaded {
 
         @Override
@@ -484,11 +489,11 @@
         pw.println("IsimRecords: " + this);
         pw.println(" extends:");
         super.dump(fd, pw, args);
+        pw.println(" mIsimServiceTable=" + getIsimServiceTable());
         if (DUMP_RECORDS) {
             pw.println(" mIsimImpi=" + mIsimImpi);
             pw.println(" mIsimDomain=" + mIsimDomain);
             pw.println(" mIsimImpu[]=" + Arrays.toString(mIsimImpu));
-            pw.println(" mIsimIst" + mIsimIst);
             pw.println(" mIsimPcscf" + Arrays.toString(mIsimPcscf));
             pw.println(" mPsismsc=" + mPsiSmsc);
             pw.println(" mSmss TPMR=" + getSmssTpmrValue());
@@ -496,6 +501,14 @@
         pw.flush();
     }
 
+    // Just to return the Enums of service table to print in DUMP
+    private IsimServiceTable getIsimServiceTable() {
+        if (mIsimIst != null) {
+            byte[] istTable = IccUtils.hexStringToBytes(mIsimIst);
+            return new IsimServiceTable(istTable);
+        }
+        return null;
+    }
     @Override
     public int getVoiceMessageCount() {
         return 0; // Not applicable to Isim
diff --git a/src/java/com/android/internal/telephony/uicc/PinStorage.java b/src/java/com/android/internal/telephony/uicc/PinStorage.java
index ed16ee4..23769ad 100644
--- a/src/java/com/android/internal/telephony/uicc/PinStorage.java
+++ b/src/java/com/android/internal/telephony/uicc/PinStorage.java
@@ -28,6 +28,7 @@
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT;
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR;
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR;
+import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_KEY_MISSING;
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT;
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION;
 import static com.android.internal.telephony.TelephonyStatsLog.PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE;
@@ -54,6 +55,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.SimState;
 import android.util.Base64;
+import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
 
 import com.android.internal.R;
@@ -132,7 +134,6 @@
 
     // Events
     private static final int ICC_CHANGED_EVENT = 1;
-    private static final int CARRIER_CONFIG_CHANGED_EVENT = 2;
     private static final int TIMER_EXPIRATION_EVENT = 3;
     private static final int USER_UNLOCKED_EVENT = 4;
     private static final int SUPPLY_PIN_COMPLETE = 5;
@@ -156,14 +157,11 @@
     private final SparseArray<byte[]> mRamStorage;
 
     /** Receiver for the required intents. */
-    private final BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
-                int slotId = intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, -1);
-                sendMessage(obtainMessage(CARRIER_CONFIG_CHANGED_EVENT, slotId, 0));
-            } else if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(action)
+            if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(action)
                     || TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED.equals(action)) {
                 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1);
                 int state = intent.getIntExtra(
@@ -188,11 +186,16 @@
 
         // Register for necessary intents.
         IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         intentFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
         intentFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
         intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiver(mCarrierConfigChangedReceiver, intentFilter);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+        CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
+        // Callback directly handle config change and should be executed in handler thread
+        ccm.registerCarrierConfigChangeListener(this::post,
+                (slotIndex, subId, carrierId, specificCarrierId) ->
+                        onCarrierConfigurationChanged(slotIndex));
 
         // Initialize the long term secret key. This needs to be present in all cases:
         //  - if the device is not secure or is locked: key does not require user authentication
@@ -560,7 +563,7 @@
         }
     }
 
-    private void onCarrierConfigChanged(int slotId) {
+    private void onCarrierConfigurationChanged(int slotId) {
         logv("onCarrierConfigChanged[%d]", slotId);
         if (!isCacheAllowed(slotId)) {
             logd("onCarrierConfigChanged[%d] - PIN caching not allowed", slotId);
@@ -590,9 +593,6 @@
             case ICC_CHANGED_EVENT:
                 onSimStatusChange(/* slotId= */ msg.arg1, /* state= */ msg.arg2);
                 break;
-            case CARRIER_CONFIG_CHANGED_EVENT:
-                onCarrierConfigChanged(/* slotId= */ msg.arg1);
-                break;
             case TIMER_EXPIRATION_EVENT:
                 onTimerExpiration();
                 break;
@@ -723,7 +723,11 @@
      */
     @Nullable
     private StoredPin decryptStoredPin(byte[] blob, @Nullable SecretKey secretKey) {
-        if (secretKey != null) {
+        if (secretKey == null) {
+            TelephonyStatsLog.write(PIN_STORAGE_EVENT,
+                    PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_KEY_MISSING,
+                    /* number_of_pins= */ 1, /* package_name= */ "");
+        } else {
             try {
                 byte[] decryptedPin = decrypt(secretKey, blob);
                 if (decryptedPin.length > 0) {
@@ -993,14 +997,15 @@
         PersistableBundle config = null;
         CarrierConfigManager configManager =
                 mContext.getSystemService(CarrierConfigManager.class);
-        if (configManager != null) {
-            Phone phone = PhoneFactory.getPhone(slotId);
-            if (phone != null) {
-                 // If an invalid subId is used, this bundle will contain default values.
-                config = configManager.getConfigForSubId(phone.getSubId());
-            }
+        Phone phone = PhoneFactory.getPhone(slotId);
+        if (configManager != null && phone != null) {
+            config =
+                    CarrierConfigManager.getCarrierConfigSubset(
+                            mContext,
+                            phone.getSubId(),
+                            CarrierConfigManager.KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL);
         }
-        if (config == null) {
+        if (config == null || config.isEmpty()) {
             config = CarrierConfigManager.getDefaultConfig();
         }
 
@@ -1205,16 +1210,18 @@
         Rlog.e(TAG, msg, tr);
     }
 
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("PinStorage:");
-        pw.println(" mIsDeviceSecure=" + mIsDeviceSecure);
-        pw.println(" mIsDeviceLocked=" + mIsDeviceLocked);
-        pw.println(" isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null));
-        pw.println(" isShortTermSecretKey=" + (boolean) (mShortTermSecretKey != null));
-        pw.println(" isCacheAllowedByDevice=" + isCacheAllowedByDevice());
+        pw.increaseIndent();
+        pw.println("mIsDeviceSecure=" + mIsDeviceSecure);
+        pw.println("mIsDeviceLocked=" + mIsDeviceLocked);
+        pw.println("isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null));
+        pw.println("isShortTermSecretKey=" + (boolean) (mShortTermSecretKey != null));
+        pw.println("isCacheAllowedByDevice=" + isCacheAllowedByDevice());
         int slotCount = getSlotCount();
         for (int i = 0; i < slotCount; i++) {
-            pw.println(" isCacheAllowedByCarrier[" + i + "]=" + isCacheAllowedByCarrier(i));
+            pw.println("isCacheAllowedByCarrier[" + i + "]=" + isCacheAllowedByCarrier(i));
         }
         if (VDBG) {
             SparseArray<StoredPin> storedPins = loadPinInformation();
@@ -1222,5 +1229,6 @@
                 pw.println(" pin=" + storedPins.valueAt(i).toString());
             }
         }
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/PlmnActRecord.java b/src/java/com/android/internal/telephony/uicc/PlmnActRecord.java
old mode 100755
new mode 100644
diff --git a/src/java/com/android/internal/telephony/uicc/PortUtils.java b/src/java/com/android/internal/telephony/uicc/PortUtils.java
new file mode 100644
index 0000000..4a18b56
--- /dev/null
+++ b/src/java/com/android/internal/telephony/uicc/PortUtils.java
@@ -0,0 +1,77 @@
+/*
+ * 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.uicc;
+
+import android.annotation.NonNull;
+
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
+
+/**
+ * Various methods, useful for dealing with port.
+ */
+public class PortUtils {
+
+    /**
+     * Converts the port index to compatible with the HAL.
+     *
+     * @param mepMode   supported MultipleEnabledProfilesMode
+     * @param portIndex port index
+     * @return target index according to the MultipleEnabledProfilesMode
+     */
+    public static int convertToHalPortIndex(@NonNull MultipleEnabledProfilesMode mepMode,
+            int portIndex) {
+        // In case of MEP-A1 and MEP-A2, profiles are selected on eSIM Ports 1 and higher, hence
+        // HAL expects the ports are indexed with 1, 2... etc.
+        // So inorder to compatible with HAL, shift the port index.
+        return mepMode.isMepAMode() ? ++portIndex : portIndex;
+    }
+
+    /**
+     * Converts the port index to compatible with the HAL.
+     *
+     * @param slotIndex   physical slot index corresponding to the portIndex
+     * @param portIndex port index
+     * @return target port index according to the MultipleEnabledProfilesMode
+     */
+    public static int convertToHalPortIndex(int slotIndex, int portIndex) {
+        return convertToHalPortIndex(UiccController.getInstance().getSupportedMepMode(slotIndex),
+                portIndex);
+    }
+
+    /**
+     * Converts the port index to compatible with the platform.
+     *
+     * @param slotIndex physical slot index corresponding to the portIndex
+     * @param portIndex target port index
+     * @param cardState cardState
+     * @param supportedMepMode supported MEP mode
+     * @return shifted port index according to the MultipleEnabledProfilesMode
+     */
+    public static int convertFromHalPortIndex(int slotIndex, int portIndex,
+            IccCardStatus.CardState cardState, MultipleEnabledProfilesMode supportedMepMode) {
+        // In case of MEP-A1 and MEP-A2, profiles are selected on eSIM Ports 1 and higher.
+        // But inorder to platform code MEP mode agnostic, platform always expects the ports
+        // are indexed with 0, 1... etc. Hence shift the target port index to be compatible
+        // with platform.
+
+        // When the SIM_STATUS is related to CARDSTATE_ABSENT, CardStatus will not contain proper
+        // MEP mode info, fallback onto to the supportedMepMode data available in UiccSlot.
+        MultipleEnabledProfilesMode mepMode = cardState.isCardPresent() ? supportedMepMode
+                : UiccController.getInstance().getSupportedMepMode(slotIndex);
+        return mepMode.isMepAMode() ? --portIndex : portIndex;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
old mode 100755
new mode 100644
index 041b5dd..2e490e3
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -690,7 +690,7 @@
                 mIccId = IccUtils.bcdToString(data, 0, data.length);
                 mFullIccId = IccUtils.bchToString(data, 0, data.length);
 
-                log("iccid: " + SubscriptionInfo.givePrintableIccid(mFullIccId));
+                log("iccid: " + SubscriptionInfo.getPrintableId(mFullIccId));
 
             break;
 
@@ -817,7 +817,6 @@
         mLoaded.set(true);
         mRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
 
-        // TODO: The below is hacky since the SubscriptionController may not be ready at this time.
         if (!TextUtils.isEmpty(mMdn)) {
             int phoneId = mParentApp.getUiccProfile().getPhoneId();
             int subId = SubscriptionManager.getSubscriptionId(phoneId);
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 485838b..a97b00b 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -35,6 +35,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.SmsConstants;
@@ -167,7 +168,7 @@
     private static final int EVENT_UPDATE_DONE = 14 + SIM_RECORD_EVENT_BASE;
     protected static final int EVENT_GET_PNN_DONE = 15 + SIM_RECORD_EVENT_BASE;
     protected static final int EVENT_GET_OPL_DONE = 16 + SIM_RECORD_EVENT_BASE;
-    private static final int EVENT_GET_SST_DONE = 17 + SIM_RECORD_EVENT_BASE;
+    protected static final int EVENT_GET_SST_DONE = 17 + SIM_RECORD_EVENT_BASE;
     private static final int EVENT_GET_ALL_SMS_DONE = 18 + SIM_RECORD_EVENT_BASE;
     private static final int EVENT_MARK_SMS_READ_DONE = 19 + SIM_RECORD_EVENT_BASE;
     private static final int EVENT_SET_MBDN_DONE = 20 + SIM_RECORD_EVENT_BASE;
@@ -190,7 +191,6 @@
     private static final int EVENT_SET_FPLMN_DONE = 43 + SIM_RECORD_EVENT_BASE;
     protected static final int EVENT_GET_SMSS_RECORD_DONE = 46 + SIM_RECORD_EVENT_BASE;
     protected static final int EVENT_GET_PSISMSC_DONE = 47 + SIM_RECORD_EVENT_BASE;
-    protected static final int EVENT_GET_FDN_DONE = 48 + SIM_RECORD_EVENT_BASE;
 
     // ***** Constructor
 
@@ -280,6 +280,18 @@
         return mUsimServiceTable;
     }
 
+    /**
+     * Fetches the USIM service table from UsimServiceTable
+     *
+     * @return HexString representation of USIM service table
+     */
+    public String getSimServiceTable() {
+        if (mUsimServiceTable != null) {
+            return IccUtils.bytesToHexString(mUsimServiceTable.getUSIMServiceTable());
+        }
+        return null;
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private int getExtFromEf(int ef) {
         int ext;
@@ -387,18 +399,20 @@
         mNewVoiceMailTag = alphaTag;
 
         AdnRecord adn = new AdnRecord(mNewVoiceMailTag, mNewVoiceMailNum);
-
         if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
 
             new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
                     mMailboxIndex, null,
-                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
+                    obtainMessage(EVENT_SET_MBDN_DONE, AdnRecordLoader.VOICEMAIL_ALPHATAG_ARG,
+                            0 /* ignored arg2 */, onComplete));
 
         } else if (isCphsMailboxEnabled()) {
 
             new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
                     EF_EXT1, 1, null,
-                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
+                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
+                            AdnRecordLoader.VOICEMAIL_ALPHATAG_ARG,
+                            0 /* ignored arg2 */, onComplete));
 
         } else {
             AsyncResult.forMessage((onComplete)).exception =
@@ -844,7 +858,7 @@
                     mIccId = IccUtils.bcdToString(data, 0, data.length);
                     mFullIccId = IccUtils.bchToString(data, 0, data.length);
 
-                    log("iccid: " + SubscriptionInfo.givePrintableIccid(mFullIccId));
+                    log("iccid: " + SubscriptionInfo.getPrintableId(mFullIccId));
                     break;
 
                 case EVENT_GET_AD_DONE:
@@ -1021,10 +1035,20 @@
 
                     if (DBG) log("EVENT_SET_MBDN_DONE ex:" + ar.exception);
                     if (ar.exception == null) {
+                        /**
+                         * Check for any changes made to voicemail alphaTag while saving to SIM.
+                         * if voicemail alphaTag length is more than allowed limit of SIM EF then
+                         * null alphaTag will be saved to SIM {@code AdnRecordLoader}.
+                         */
+                        if (ar.result != null) {
+                            AdnRecord adnRecord = (AdnRecord) (ar.result);
+                            if (adnRecord != null) {
+                                mNewVoiceMailTag = adnRecord.mAlphaTag;
+                            }
+                        }
                         mVoiceMailNum = mNewVoiceMailNum;
                         mVoiceMailTag = mNewVoiceMailTag;
                     }
-
                     if (isCphsMailboxEnabled()) {
                         adn = new AdnRecord(mVoiceMailTag, mVoiceMailNum);
                         Message onCphsCompleted = (Message) ar.userObj;
@@ -1048,7 +1072,8 @@
                         new AdnRecordLoader(mFh)
                                 .updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
                                 obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
-                                        onCphsCompleted));
+                                       AdnRecordLoader.VOICEMAIL_ALPHATAG_ARG,
+                                        0 /* ignored arg2 */, onCphsCompleted));
                     } else {
                         if (ar.userObj != null) {
                             CarrierConfigManager configManager = (CarrierConfigManager)
@@ -1080,6 +1105,12 @@
                     isRecordLoadResponse = false;
                     ar = (AsyncResult) msg.obj;
                     if (ar.exception == null) {
+                        if (ar.result != null) {
+                            AdnRecord adnRecord = (AdnRecord) (ar.result);
+                            if (adnRecord != null) {
+                                mNewVoiceMailTag = adnRecord.mAlphaTag;
+                            }
+                        }
                         mVoiceMailNum = mNewVoiceMailNum;
                         mVoiceMailTag = mNewVoiceMailTag;
                     } else {
@@ -1328,15 +1359,6 @@
                     }
                     break;
 
-                case EVENT_GET_FDN_DONE:
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        loge("Failed to read USIM EF_FDN field error=" + ar.exception);
-                    } else {
-                        log("EF_FDN read successfully");
-                    }
-                    break;
-
                 default:
                     super.handleMessage(msg);   // IccRecords handles generic record load responses
             }
@@ -2162,13 +2184,9 @@
         log("[CSP] Value Added Service Group (0xC0), not found!");
     }
 
-    public void loadFdnRecords() {
-        if (mParentApp != null && mParentApp.getIccFdnEnabled()
-                && mParentApp.getIccFdnAvailable()) {
-            log("Loading FdnRecords");
-            mAdnCache.requestLoadAllAdnLike(IccConstants.EF_FDN, getExtFromEf(IccConstants.EF_FDN),
-                    obtainMessage(EVENT_GET_FDN_DONE));
-        }
+    @VisibleForTesting
+    public void setMailboxIndex(int mailboxIndex) {
+        mMailboxIndex = mailboxIndex;
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 689e4b7..960a166 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -21,16 +21,20 @@
 import android.os.Build;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.uicc.euicc.EuiccCard;
 import com.android.internal.telephony.uicc.euicc.EuiccPort;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 
 /**
  * {@hide}
@@ -49,17 +53,17 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private CardState mCardState;
     protected String mCardId;
-    protected boolean mIsSupportsMultipleEnabledProfiles;
+    protected MultipleEnabledProfilesMode mSupportedMepMode;
 
-    protected HashMap<Integer, UiccPort> mUiccPorts = new HashMap<>();
+    protected LinkedHashMap<Integer, UiccPort> mUiccPorts = new LinkedHashMap<>();
     private HashMap<Integer, Integer> mPhoneIdToPortIdx = new HashMap<>();
 
     public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            boolean isSupportsMultipleEnabledProfiles) {
+            MultipleEnabledProfilesMode supportedMepMode) {
         if (DBG) log("Creating");
         mCardState = ics.mCardState;
         mLock = lock;
-        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
+        mSupportedMepMode = supportedMepMode;
         update(c, ci, ics, phoneId);
     }
 
@@ -109,7 +113,7 @@
                 if (port == null) {
                     if (this instanceof EuiccCard) {
                         port = new EuiccPort(c, ci, ics, phoneId, mLock, this,
-                                mIsSupportsMultipleEnabledProfiles); // eSim
+                                mSupportedMepMode); // eSim
                     } else {
                         port = new UiccPort(c, ci, ics, phoneId, mLock, this); // pSim
                     }
@@ -143,13 +147,13 @@
 
 
     /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
+     * Updates MEP(Multiple Enabled Profile) supported mode flag.
      *
      * <p>If IccSlotStatus comes later, the number of ports reported is only known after the
      * UiccCard creation which will impact UICC MEP capability.
      */
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        mIsSupportsMultipleEnabledProfiles = supported;
+    public void updateSupportedMepMode(MultipleEnabledProfilesMode supportedMepMode) {
+        mSupportedMepMode = supportedMepMode;
     }
 
     @UnsupportedAppUsage
@@ -167,8 +171,11 @@
         if (!TextUtils.isEmpty(mCardId)) {
             return mCardId;
         } else {
-            UiccProfile uiccProfile = mUiccPorts.get(TelephonyManager.DEFAULT_PORT_INDEX)
-                    .getUiccProfile();
+            UiccPort uiccPort = mUiccPorts.get(TelephonyManager.DEFAULT_PORT_INDEX);
+            if (uiccPort == null) {
+                return null;
+            }
+            UiccProfile uiccProfile = uiccPort.getUiccProfile();
             return uiccProfile == null ? null : uiccProfile.getIccId();
         }
     }
@@ -210,15 +217,20 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("UiccCard:");
-        pw.println(" mCardState=" + mCardState);
-        pw.println(" mCardId=" + mCardId);
-        pw.println(" mNumberOfPorts=" + mUiccPorts.size());
-        pw.println( "mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
-        pw.println();
+        pw.increaseIndent();
+        pw.println("mCardState=" + mCardState);
+        pw.println("mCardId=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mCardId));
+        pw.println("mNumberOfPorts=" + mUiccPorts.size());
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
+        pw.println("mUiccPorts= size=" + mUiccPorts.size());
+        pw.increaseIndent();
         for (UiccPort uiccPort : mUiccPorts.values()) {
             uiccPort.dump(fd, pw, args);
         }
+        pw.decreaseIndent();
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 8ef58ec..fe19e99 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -24,6 +24,7 @@
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
@@ -59,6 +60,9 @@
      */
     public static final int AUTH_CONTEXT_EAP_SIM = PhoneConstants.AUTH_CONTEXT_EAP_SIM;
     public static final int AUTH_CONTEXT_EAP_AKA = PhoneConstants.AUTH_CONTEXT_EAP_AKA;
+    public static final int AUTH_CONTEXT_GBA_BOOTSTRAP = PhoneConstants.AUTH_CONTEXT_GBA_BOOTSTRAP;
+    public static final int AUTHTYPE_GBA_NAF_KEY_EXTERNAL =
+            PhoneConstants.AUTHTYPE_GBA_NAF_KEY_EXTERNAL;
     public static final int AUTH_CONTEXT_UNDEFINED = PhoneConstants.AUTH_CONTEXT_UNDEFINED;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -267,7 +271,7 @@
                 loge("Bogus facility lock response");
             }
             if (mIccFdnEnabled && mIccFdnAvailable) {
-                ((SIMRecords) mIccRecords).loadFdnRecords();
+                mIccRecords.loadFdnRecords();
             }
         }
     }
@@ -984,40 +988,27 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccCardApplication: " + this);
-        pw.println(" mUiccProfile=" + mUiccProfile);
-        pw.println(" mAppState=" + mAppState);
-        pw.println(" mAppType=" + mAppType);
-        pw.println(" mPersoSubState=" + mPersoSubState);
-        pw.println(" mAid=" + mAid);
-        pw.println(" mAppLabel=" + mAppLabel);
-        pw.println(" mPin1Replaced=" + mPin1Replaced);
-        pw.println(" mPin1State=" + mPin1State);
-        pw.println(" mPin2State=" + mPin2State);
-        pw.println(" mIccFdnEnabled=" + mIccFdnEnabled);
-        pw.println(" mDesiredFdnEnabled=" + mDesiredFdnEnabled);
-        pw.println(" mIccLockEnabled=" + mIccLockEnabled);
-        pw.println(" mDesiredPinLocked=" + mDesiredPinLocked);
-        pw.println(" mCi=" + mCi);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mIccFh=" + mIccFh);
-        pw.println(" mDestroyed=" + mDestroyed);
-        pw.println(" mReadyRegistrants: size=" + mReadyRegistrants.size());
-        for (int i = 0; i < mReadyRegistrants.size(); i++) {
-            pw.println("  mReadyRegistrants[" + i + "]="
-                    + ((Registrant)mReadyRegistrants.get(i)).getHandler());
-        }
-        pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size());
-        for (int i = 0; i < mPinLockedRegistrants.size(); i++) {
-            pw.println("  mPinLockedRegistrants[" + i + "]="
-                    + ((Registrant)mPinLockedRegistrants.get(i)).getHandler());
-        }
-        pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
-        for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
-            pw.println("  mNetworkLockedRegistrants[" + i + "]="
-                    + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler());
-        }
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UiccCardApplication: ");
+        pw.increaseIndent();
+        pw.println("mUiccProfile=" + mUiccProfile);
+        pw.println("mAppState=" + mAppState);
+        pw.println("mAppType=" + mAppType);
+        pw.println("mPersoSubState=" + mPersoSubState);
+        pw.println("mAid=" + mAid);
+        pw.println("mAppLabel=" + mAppLabel);
+        pw.println("mPin1Replaced=" + mPin1Replaced);
+        pw.println("mPin1State=" + mPin1State);
+        pw.println("mPin2State=" + mPin2State);
+        pw.println("mIccFdnEnabled=" + mIccFdnEnabled);
+        pw.println("mDesiredFdnEnabled=" + mDesiredFdnEnabled);
+        pw.println("mIccLockEnabled=" + mIccLockEnabled);
+        pw.println("mDesiredPinLocked=" + mDesiredPinLocked);
+        pw.println("mIccRecords=" + mIccRecords);
+        pw.println("mIccFh=" + mIccFh);
+        pw.println("mDestroyed=" + mDestroyed);
+        pw.decreaseIndent();
         pw.flush();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 7d87e5f..596ccf6 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -28,6 +28,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -426,8 +427,8 @@
                 if (ar.exception == null && ar.result != null) {
                     mChannelId = ((int[]) ar.result)[0];
                     mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2, P3,
-                            DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId,
-                                    mAIDInUse));
+                            DATA, false /*isEs10Command*/, obtainMessage(
+                                    EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId, mAIDInUse));
                 } else {
                     if (shouldRetry(ar, mRetryCount)) {
                         log("should retry");
@@ -483,7 +484,7 @@
                                 }
                             } else {
                                 mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND,
-                                        P1, P2_EXTENDED_DATA, P3, DATA,
+                                        P1, P2_EXTENDED_DATA, P3, DATA, false /*isEs10Command*/,
                                         obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE,
                                                 mChannelId, mAIDInUse));
                                 break;
@@ -518,7 +519,7 @@
                     }
                 }
 
-                mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage(
+                mUiccProfile.iccCloseLogicalChannel(mChannelId, false /*isEs10*/, obtainMessage(
                         EVENT_CLOSE_LOGICAL_CHANNEL_DONE, 0, mAIDInUse));
                 mChannelId = -1;
                 break;
@@ -693,16 +694,20 @@
     /**
      * Dumps info to Dumpsys - useful for debugging.
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccCarrierPrivilegeRules: " + this);
-        pw.println(" mState=" + getStateString(mState.get()));
-        pw.println(" mStatusMessage=");
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UiccCarrierPrivilegeRules:");
+        pw.increaseIndent();
+        pw.println("mState=" + getStateString(mState.get()));
+        pw.println("mStatusMessage=");
         mStatusMessage.dump(fd, pw, args);
         if (mAccessRules != null) {
-            pw.println(" mAccessRules: ");
+            pw.println("mAccessRules: ");
+            pw.increaseIndent();
             for (UiccAccessRule ar : mAccessRules) {
                 pw.println("  rule='" + ar + "'");
             }
+            pw.decreaseIndent();
         } else {
             pw.println(" mAccessRules: null");
         }
@@ -712,6 +717,7 @@
         } else {
             pw.println(" mUiccPkcs15: null");
         }
+        pw.decreaseIndent();
         pw.flush();
     }
 
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 7fe2d1c..566bec2 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -34,12 +34,12 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.os.Registrant;
 import android.os.RegistrantList;
 import android.preference.PreferenceManager;
 import android.sysprop.TelephonyProperties;
 import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.SimState;
@@ -48,6 +48,7 @@
 import android.telephony.UiccSlotMapping;
 import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
 import android.util.Log;
 
@@ -62,11 +63,11 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.RadioConfig;
-import com.android.internal.telephony.SubscriptionInfoUpdater;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.euicc.EuiccCard;
+import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
@@ -76,6 +77,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 /**
@@ -741,38 +743,6 @@
         }
     }
 
-    static void updateInternalIccStateForInactivePort(
-            Context context, int prevActivePhoneId, String iccId) {
-        if (SubscriptionManager.isValidPhoneId(prevActivePhoneId)) {
-            // Mark SIM state as ABSENT on previously phoneId.
-            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
-                    Context.TELEPHONY_SERVICE);
-            telephonyManager.setSimStateForPhone(prevActivePhoneId,
-                    IccCardConstants.State.ABSENT.toString());
-        }
-
-        SubscriptionInfoUpdater subInfoUpdator = PhoneFactory.getSubscriptionInfoUpdater();
-        if (subInfoUpdator != null) {
-            subInfoUpdator.updateInternalIccStateForInactivePort(prevActivePhoneId, iccId);
-        } else {
-            Rlog.e(LOG_TAG, "subInfoUpdate is null.");
-        }
-    }
-
-    static void updateInternalIccState(Context context, IccCardConstants.State state, String reason,
-            int phoneId) {
-        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
-                Context.TELEPHONY_SERVICE);
-        telephonyManager.setSimStateForPhone(phoneId, state.toString());
-
-        SubscriptionInfoUpdater subInfoUpdator = PhoneFactory.getSubscriptionInfoUpdater();
-        if (subInfoUpdator != null) {
-            subInfoUpdator.updateInternalIccState(getIccStateIntentString(state), reason, phoneId);
-        } else {
-            Rlog.e(LOG_TAG, "subInfoUpdate is null.");
-        }
-    }
-
     /**
      * Update SIM state for the inactive eSIM port.
      *
@@ -787,7 +757,8 @@
                         IccCardConstants.State.ABSENT.toString());
             }
 
-            SubscriptionManagerService.getInstance().updateSimStateForInactivePort(phoneId);
+            SubscriptionManagerService.getInstance().updateSimStateForInactivePort(phoneId,
+                    TextUtils.emptyIfNull(iccId));
         });
     }
 
@@ -986,7 +957,7 @@
             log("updateSimState: phoneId=" + phoneId + ", state=" + state + ", reason="
                     + reason);
             if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-                Rlog.e(LOG_TAG, "updateInternalIccState: Invalid phone id " + phoneId);
+                Rlog.e(LOG_TAG, "updateSimState: Invalid phone id " + phoneId);
                 return;
             }
 
@@ -1058,10 +1029,10 @@
 
         IccCardStatus status = (IccCardStatus)ar.result;
 
-        logWithLocalLog("onGetIccCardStatusDone: phoneId " + index + " IccCardStatus: " + status);
+        logWithLocalLog("onGetIccCardStatusDone: phoneId-" + index + " IccCardStatus: " + status);
 
         int slotId = status.mSlotPortMapping.mPhysicalSlotIndex;
-        if (VDBG) log("onGetIccCardStatusDone: phoneId " + index + " physicalSlotIndex " + slotId);
+        if (VDBG) log("onGetIccCardStatusDone: phoneId-" + index + " physicalSlotIndex " + slotId);
         if (slotId == INVALID_SLOT_ID) {
             slotId = index;
         }
@@ -1092,6 +1063,14 @@
             return;
         }
 
+        UiccPort port = card.getUiccPort(status.mSlotPortMapping.mPortIndex);
+        if (port == null) {
+            if (DBG) log("mUiccSlots[" + slotId + "] has no UiccPort with index["
+                    + status.mSlotPortMapping.mPortIndex + "]. Notifying IccChangedRegistrants");
+            mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
+            return;
+        }
+
         String cardString = null;
         boolean isEuicc = mUiccSlots[slotId].isEuicc();
         if (isEuicc) {
@@ -1753,6 +1732,18 @@
         return mUseRemovableEsimAsDefault;
     }
 
+    /**
+     * Returns the MEP mode supported by the UiccSlot associated with slotIndex.
+     * @param slotIndex physical slot index
+     * @return MultipleEnabledProfilesMode supported by the slot
+     */
+    public IccSlotStatus.MultipleEnabledProfilesMode getSupportedMepMode(int slotIndex) {
+        synchronized (mLock) {
+            UiccSlot slot = getUiccSlot(slotIndex);
+            return slot != null ? slot.getSupportedMepMode()
+                    : IccSlotStatus.MultipleEnabledProfilesMode.NONE;
+        }
+    }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void log(String string) {
@@ -1774,35 +1765,40 @@
         sLocalLog.log(data);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccController: " + this);
-        pw.println(" mContext=" + mContext);
-        pw.println(" mInstance=" + mInstance);
-        pw.println(" mIccChangedRegistrants: size=" + mIccChangedRegistrants.size());
-        for (int i = 0; i < mIccChangedRegistrants.size(); i++) {
-            pw.println("  mIccChangedRegistrants[" + i + "]="
-                    + ((Registrant)mIccChangedRegistrants.get(i)).getHandler());
+    private List<String> getPrintableCardStrings() {
+        if (!ArrayUtils.isEmpty(mCardStrings)) {
+            return mCardStrings.stream().map(SubscriptionInfo::getPrintableId).collect(
+                    Collectors.toList());
         }
-        pw.println();
-        pw.flush();
-        pw.println(" mIsCdmaSupported=" + isCdmaSupported(mContext));
-        pw.println(" mHasBuiltInEuicc=" + mHasBuiltInEuicc);
-        pw.println(" mHasActiveBuiltInEuicc=" + mHasActiveBuiltInEuicc);
-        pw.println(" mCardStrings=" + mCardStrings);
-        pw.println(" mDefaultEuiccCardId=" + mDefaultEuiccCardId);
-        pw.println(" mPhoneIdToSlotId=" + Arrays.toString(mPhoneIdToSlotId));
-        pw.println(" mUseRemovableEsimAsDefault=" + mUseRemovableEsimAsDefault);
-        pw.println(" mUiccSlots: size=" + mUiccSlots.length);
+        return mCardStrings;
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("mIsCdmaSupported=" + isCdmaSupported(mContext));
+        pw.println("mHasBuiltInEuicc=" + mHasBuiltInEuicc);
+        pw.println("mHasActiveBuiltInEuicc=" + mHasActiveBuiltInEuicc);
+        pw.println("mCardStrings=" + getPrintableCardStrings());
+        pw.println("mDefaultEuiccCardId=" + mDefaultEuiccCardId);
+        pw.println("mPhoneIdToSlotId=" + Arrays.toString(mPhoneIdToSlotId));
+        pw.println("mUseRemovableEsimAsDefault=" + mUseRemovableEsimAsDefault);
+        pw.println("mUiccSlots: size=" + mUiccSlots.length);
+        pw.increaseIndent();
         for (int i = 0; i < mUiccSlots.length; i++) {
             if (mUiccSlots[i] == null) {
-                pw.println("  mUiccSlots[" + i + "]=null");
+                pw.println("mUiccSlots[" + i + "]=null");
             } else {
-                pw.println("  mUiccSlots[" + i + "]=" + mUiccSlots[i]);
+                pw.println("mUiccSlots[" + i + "]:");
+                pw.increaseIndent();
                 mUiccSlots[i].dump(fd, pw, args);
+                pw.decreaseIndent();
             }
         }
-        pw.println(" sLocalLog= ");
-        sLocalLog.dump(fd, pw, args);
+        pw.decreaseIndent();
+        pw.println();
+        pw.println("sLocalLog= ");
+        pw.increaseIndent();
         mPinStorage.dump(fd, pw, args);
+        sLocalLog.dump(fd, pw, args);
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPkcs15.java b/src/java/com/android/internal/telephony/uicc/UiccPkcs15.java
index 9543908..be045c4 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPkcs15.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPkcs15.java
@@ -81,7 +81,7 @@
         private void selectFile() {
             if (mChannelId >= 0) {
                 mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, 0x00, 0xA4, 0x00, 0x04, 0x02,
-                        mFileId, obtainMessage(EVENT_SELECT_FILE_DONE));
+                        mFileId, false /*isEs10Command*/, obtainMessage(EVENT_SELECT_FILE_DONE));
             } else {
                 log("EF based");
             }
@@ -90,7 +90,7 @@
         private void readBinary() {
             if (mChannelId >=0 ) {
                 mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, 0x00, 0xB0, 0x00, 0x00, 0x00,
-                        "", obtainMessage(EVENT_READ_BINARY_DONE));
+                        "",  false /*isEs10Command*/, obtainMessage(EVENT_READ_BINARY_DONE));
             } else {
                 log("EF based");
             }
@@ -281,8 +281,8 @@
     private void cleanUp() {
         log("cleanUp");
         if (mChannelId >= 0) {
-            mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage(
-                    EVENT_CLOSE_LOGICAL_CHANNEL_DONE));
+            mUiccProfile.iccCloseLogicalChannel(mChannelId, false /*isEs10*/,
+                    obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE));
             mChannelId = -1;
         }
         mLoadedCallback.sendToTarget();
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPort.java b/src/java/com/android/internal/telephony/uicc/UiccPort.java
index 0152dda..d89eab1 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPort.java
@@ -22,6 +22,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.SubscriptionInfo;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -216,12 +217,12 @@
     /**
      * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
      * @deprecated Please use
-     * {@link UiccProfile#iccCloseLogicalChannel(int, Message)} instead.
+     * {@link UiccProfile#iccCloseLogicalChannel(int, boolean, Message)} instead.
      */
     @Deprecated
     public void iccCloseLogicalChannel(int channel, Message response) {
         if (mUiccProfile != null) {
-            mUiccProfile.iccCloseLogicalChannel(channel, response);
+            mUiccProfile.iccCloseLogicalChannel(channel, false /*isEs10*/, response);
         } else {
             loge("iccCloseLogicalChannel Failed!");
         }
@@ -230,15 +231,15 @@
     /**
      * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
      * @deprecated Please use {@link
-     * UiccProfile#iccTransmitApduLogicalChannel(int, int, int, int, int, int, String, Message)}
-     * instead.
+     * UiccProfile#iccTransmitApduLogicalChannel(int, int, int, int, int, int, String,
+     * boolean, 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);
+                    data, false /*isEs10Command*/, response);
         } else {
             loge("iccTransmitApduLogicalChannel Failed!");
         }
@@ -358,18 +359,19 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         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);
+        pw.increaseIndent();
+        pw.println("mPortIdx=" + mPortIdx);
+        pw.println("mCi=" + mCi);
+        pw.println("mIccid=" + SubscriptionInfo.getPrintableId(mIccid));
+        pw.println("mPhoneId=" + mPhoneId);
+        pw.println("mPhysicalSlotIndex=" + mPhysicalSlotIndex);
         synchronized (mOpenChannelRecords) {
-            pw.println(" mOpenChannelRecords=" + mOpenChannelRecords);
+            pw.println("mOpenChannelRecords=" + mOpenChannelRecords);
         }
-        pw.println();
+        pw.println("mUiccProfile");
         if (mUiccProfile != null) {
             mUiccProfile.dump(fd, pw, args);
         }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 289de25..83db022 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -51,6 +51,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CarrierAppUtils;
@@ -62,7 +63,6 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyStatsLog;
 import com.android.internal.telephony.cat.CatService;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
@@ -80,6 +80,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -124,6 +125,8 @@
     private final int mPhoneId;
     private final PinStorage mPinStorage;
 
+    private final CarrierConfigManager mCarrierConfigManager;
+
     private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 1;
     private static final int EVENT_ICC_LOCKED = 2;
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -184,14 +187,19 @@
     };
     private boolean mUserUnlockReceiverRegistered;
 
-    private final BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_CONFIG_CHANGED));
-            }
-        }
-    };
+    private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            new CarrierConfigManager.CarrierConfigChangeListener() {
+                @Override
+                public void onCarrierConfigChanged(int logicalSlotIndex, int subscriptionId,
+                        int carrierId, int specificCarrierId) {
+                    if (logicalSlotIndex == mPhoneId) {
+                        log("onCarrierConfigChanged: slotIndex=" + logicalSlotIndex
+                                + ", subId=" + subscriptionId + ", carrierId=" + carrierId);
+                        handleCarrierNameOverride();
+                        handleSimCountryIsoOverride();
+                    }
+                }
+            };
 
     @VisibleForTesting
     public final Handler mHandler = new Handler() {
@@ -340,9 +348,10 @@
         ci.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
         resetProperties();
 
-        IntentFilter intentfilter = new IntentFilter();
-        intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        c.registerReceiver(mCarrierConfigChangedReceiver, intentfilter);
+        mCarrierConfigManager = c.getSystemService(CarrierConfigManager.class);
+        // Listener callback directly handles config change and thus runs on handler thread
+        mCarrierConfigManager.registerCarrierConfigChangeListener(mHandler::post,
+                mCarrierConfigChangeListener);
     }
 
     /**
@@ -375,7 +384,11 @@
             InstallCarrierAppUtils.unregisterPackageInstallReceiver(mContext);
 
             mCi.unregisterForOffOrNotAvailable(mHandler);
-            mContext.unregisterReceiver(mCarrierConfigChangedReceiver);
+
+            if (mCarrierConfigManager != null && mCarrierConfigChangeListener != null) {
+                mCarrierConfigManager.unregisterCarrierConfigChangeListener(
+                        mCarrierConfigChangeListener);
+            }
 
             if (mCatService != null) mCatService.dispose();
             for (UiccCardApplication app : mUiccApplications) {
@@ -447,7 +460,16 @@
             return;
         }
 
-        PersistableBundle config = configLoader.getConfigForSubId(subId);
+        PersistableBundle config =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mContext,
+                        subId,
+                        CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL,
+                        CarrierConfigManager.KEY_CARRIER_NAME_STRING);
+        if (config.isEmpty()) {
+            loge("handleCarrierNameOverride: fail to get carrier configs.");
+            return;
+        }
         boolean preferCcName = config.getBoolean(
                 CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
         String ccName = config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
@@ -511,30 +533,26 @@
             return;
         }
 
-        PersistableBundle config = configLoader.getConfigForSubId(subId);
+        PersistableBundle config =
+                CarrierConfigManager.getCarrierConfigSubset(
+                        mContext, subId, CarrierConfigManager.KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING);
+        if (config.isEmpty()) {
+            loge("handleSimCountryIsoOverride: fail to get carrier configs.");
+            return;
+        }
         String iso = config.getString(CarrierConfigManager.KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING);
         if (!TextUtils.isEmpty(iso)
                 && !iso.equals(TelephonyManager.getSimCountryIsoForPhone(mPhoneId))) {
             mTelephonyManager.setSimCountryIsoForPhone(mPhoneId, iso);
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                SubscriptionManagerService.getInstance().setCountryIso(subId, iso);
-            } else {
-                SubscriptionController.getInstance().setCountryIso(iso, subId);
-            }
+            SubscriptionManagerService.getInstance().setCountryIso(subId, iso);
         }
     }
 
     private void updateCarrierNameForSubscription(int subId, int nameSource) {
         /* update display name with carrier override */
-        SubscriptionInfo subInfo;
-
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            subInfo = SubscriptionManagerService.getInstance().getActiveSubscriptionInfo(subId,
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        } else {
-            subInfo = SubscriptionController.getInstance().getActiveSubscriptionInfo(
-                    subId, mContext.getOpPackageName(), mContext.getAttributionTag());
-        }
+        SubscriptionInfo subInfo = SubscriptionManagerService.getInstance()
+                .getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
+                        mContext.getAttributionTag());
 
         if (subInfo == null) {
             return;
@@ -545,13 +563,8 @@
 
         if (!TextUtils.isEmpty(newCarrierName) && !newCarrierName.equals(oldSubName)) {
             log("sim name[" + mPhoneId + "] = " + newCarrierName);
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                SubscriptionManagerService.getInstance().setDisplayNameUsingSrc(
-                        newCarrierName, subId, nameSource);
-            } else {
-                SubscriptionController.getInstance().setDisplayNameUsingSrc(
-                        newCarrierName, subId, nameSource);
-            }
+            SubscriptionManagerService.getInstance().setDisplayNameUsingSrc(
+                    newCarrierName, subId, nameSource);
         }
     }
 
@@ -808,13 +821,8 @@
             }
             log("setExternalState: set mPhoneId=" + mPhoneId + " mExternalState=" + mExternalState);
 
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                UiccController.getInstance().updateSimState(mPhoneId, mExternalState,
-                        getIccStateReason(mExternalState));
-            } else {
-                UiccController.updateInternalIccState(mContext, mExternalState,
-                        getIccStateReason(mExternalState), mPhoneId);
-            }
+            UiccController.getInstance().updateSimState(mPhoneId, mExternalState,
+                    getIccStateReason(mExternalState));
         }
     }
 
@@ -1415,7 +1423,7 @@
         Set<String> uninstalledCarrierPackages = new ArraySet<>();
         List<UiccAccessRule> accessRules = rules.getAccessRules();
         for (UiccAccessRule accessRule : accessRules) {
-            String certHexString = accessRule.getCertificateHexString().toUpperCase();
+            String certHexString = accessRule.getCertificateHexString().toUpperCase(Locale.ROOT);
             String pkgName = certPackageMap.get(certHexString);
             if (!TextUtils.isEmpty(pkgName) && !isPackageBundled(mContext, pkgName)) {
                 uninstalledCarrierPackages.add(pkgName);
@@ -1445,7 +1453,7 @@
             String[] keyValue = keyValueString.split(keyValueDelim);
 
             if (keyValue.length == 2) {
-                map.put(keyValue[0].toUpperCase(), keyValue[1]);
+                map.put(keyValue[0].toUpperCase(Locale.ROOT), keyValue[1]);
             } else {
                 loge("Incorrect length of key-value pair in carrier app allow list map.  "
                         + "Length should be exactly 2");
@@ -1605,9 +1613,9 @@
     /**
      * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
      */
-    public void iccCloseLogicalChannel(int channel, Message response) {
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response) {
         logWithLocalLog("iccCloseLogicalChannel: " + channel);
-        mCi.iccCloseLogicalChannel(channel,
+        mCi.iccCloseLogicalChannel(channel, isEs10,
                 mHandler.obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, response));
     }
 
@@ -1615,9 +1623,9 @@
      * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
      */
     public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
-            int p1, int p2, int p3, String data, Message response) {
-        mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
-                data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response));
+            int p1, int p2, int p3, String data, boolean isEs10Command, Message response) {
+        mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3, data, isEs10Command,
+                mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response));
     }
 
     /**
@@ -1711,42 +1719,34 @@
      */
     public boolean setOperatorBrandOverride(String brand) {
         log("setOperatorBrandOverride: " + brand);
-        log("current iccId: " + SubscriptionInfo.givePrintableIccid(getIccId()));
+        log("current iccId: " + SubscriptionInfo.getPrintableId(getIccId()));
 
         String iccId = getIccId();
         if (TextUtils.isEmpty(iccId)) {
             return false;
         }
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            int subId = SubscriptionManager.getSubscriptionId(getPhoneId());
-            SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
-                    .getSubscriptionInfoInternal(subId);
-            if (subInfo == null) {
-                loge("setOperatorBrandOverride: Cannot find subscription info for sub " + subId);
-                return false;
-            }
+        int subId = SubscriptionManager.getSubscriptionId(getPhoneId());
+        SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+                .getSubscriptionInfoInternal(subId);
+        if (subInfo == null) {
+            loge("setOperatorBrandOverride: Cannot find subscription info for sub " + subId);
+            return false;
+        }
 
-            List<SubscriptionInfo> subInfos = new ArrayList<>();
-            subInfos.add(subInfo.toSubscriptionInfo());
-            String groupUuid = subInfo.getGroupUuid();
-            if (!TextUtils.isEmpty(groupUuid)) {
-                subInfos.addAll(SubscriptionManagerService.getInstance()
-                        .getSubscriptionsInGroup(ParcelUuid.fromString(groupUuid),
-                                mContext.getOpPackageName(), mContext.getFeatureId()));
-            }
+        List<SubscriptionInfo> subInfos = new ArrayList<>();
+        subInfos.add(subInfo.toSubscriptionInfo());
+        String groupUuid = subInfo.getGroupUuid();
+        if (!TextUtils.isEmpty(groupUuid)) {
+            subInfos.addAll(SubscriptionManagerService.getInstance()
+                    .getSubscriptionsInGroup(ParcelUuid.fromString(groupUuid),
+                            mContext.getOpPackageName(), mContext.getFeatureId()));
+        }
 
-            if (subInfos.stream().noneMatch(info -> TextUtils.equals(IccUtils.stripTrailingFs(
-                    info.getIccId()), IccUtils.stripTrailingFs(iccId)))) {
-                loge("iccId doesn't match current active subId.");
-                return false;
-            }
-        } else {
-            if (!SubscriptionController.getInstance().checkPhoneIdAndIccIdMatch(
-                    getPhoneId(), iccId)) {
-                loge("iccId doesn't match current active subId.");
-                return false;
-            }
+        if (subInfos.stream().noneMatch(info -> TextUtils.equals(IccUtils.stripTrailingFs(
+                info.getIccId()), IccUtils.stripTrailingFs(iccId)))) {
+            loge("iccId doesn't match current active subId.");
+            return false;
         }
 
         SharedPreferences.Editor spEditor =
@@ -1851,27 +1851,29 @@
     /**
      * Dump
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccProfile:");
-        pw.println(" mCi=" + mCi);
-        pw.println(" mCatService=" + mCatService);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.increaseIndent();
+        pw.println("mCatService=" + mCatService);
         for (int i = 0; i < mOperatorBrandOverrideRegistrants.size(); i++) {
-            pw.println("  mOperatorBrandOverrideRegistrants[" + i + "]="
+            pw.println("mOperatorBrandOverrideRegistrants[" + i + "]="
                     + ((Registrant) mOperatorBrandOverrideRegistrants.get(i)).getHandler());
         }
-        pw.println(" mUniversalPinState=" + mUniversalPinState);
-        pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
-        pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
-        pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
-        pw.println(" mUiccApplications: length=" + mUiccApplications.length);
+        pw.println("mUniversalPinState=" + mUniversalPinState);
+        pw.println("mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
+        pw.println("mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
+        pw.println("mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
+        pw.println("mUiccApplications: length=" + mUiccApplications.length);
+        pw.increaseIndent();
         for (int i = 0; i < mUiccApplications.length; i++) {
             if (mUiccApplications[i] == null) {
-                pw.println("  mUiccApplications[" + i + "]=" + null);
+                pw.println("mUiccApplications[" + i + "]=" + null);
             } else {
-                pw.println("  mUiccApplications[" + i + "]="
+                pw.println("mUiccApplications[" + i + "]="
                         + mUiccApplications[i].getType() + " " + mUiccApplications[i]);
             }
         }
+        pw.decreaseIndent();
         pw.println();
         // Print details of all applications
         for (UiccCardApplication app : mUiccApplications) {
@@ -1892,28 +1894,31 @@
         }
         // Print UiccCarrierPrivilegeRules and registrants.
         if (mCarrierPrivilegeRules == null) {
-            pw.println(" mCarrierPrivilegeRules: null");
+            pw.println("mCarrierPrivilegeRules: null");
         } else {
-            pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules);
+            pw.println("mCarrierPrivilegeRules: ");
+            pw.increaseIndent();
             mCarrierPrivilegeRules.dump(fd, pw, args);
+            pw.decreaseIndent();
         }
         if (mTestOverrideCarrierPrivilegeRules != null) {
-            pw.println(" mTestOverrideCarrierPrivilegeRules: "
+            pw.println("mTestOverrideCarrierPrivilegeRules: "
                     + mTestOverrideCarrierPrivilegeRules);
             mTestOverrideCarrierPrivilegeRules.dump(fd, pw, args);
         }
         pw.flush();
 
-        pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
+        pw.println("mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
         for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
             pw.println("  mNetworkLockedRegistrants[" + i + "]="
                     + ((Registrant) mNetworkLockedRegistrants.get(i)).getHandler());
         }
-        pw.println(" mCurrentAppType=" + mCurrentAppType);
-        pw.println(" mUiccCard=" + mUiccCard);
-        pw.println(" mUiccApplication=" + mUiccApplication);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mExternalState=" + mExternalState);
+        pw.println("mCurrentAppType=" + mCurrentAppType);
+        pw.println("mUiccCard=" + mUiccCard);
+        pw.println("mUiccApplication=" + mUiccApplication);
+        pw.println("mIccRecords=" + mIccRecords);
+        pw.println("mExternalState=" + mExternalState);
+        pw.decreaseIndent();
         pw.flush();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 2490efa..db10271 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -33,6 +33,8 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
 import android.view.WindowManager;
 
 import com.android.internal.R;
@@ -41,7 +43,9 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.uicc.euicc.EuiccCard;
+import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
@@ -79,7 +83,6 @@
     private final Object mLock = new Object();
     private boolean mActive;
     private boolean mStateIsUnknown = true;
-    private CardState mCardState;
     private Context mContext;
     private UiccCard mUiccCard;
     private boolean mIsEuicc;
@@ -87,12 +90,17 @@
     private String mEid;
     private AnswerToReset mAtr;
     private boolean mIsRemovable;
+    private MultipleEnabledProfilesMode mSupportedMepMode;
+
     // 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<>();
+    // IccCardStatus and IccSlotStatus events order is not guaranteed. Inorder to handle MEP mode,
+    // map each available portIdx with CardState for card state checking
+    private HashMap<Integer, CardState> mCardState = new HashMap<>();
 
     private static final int EVENT_CARD_REMOVED = 13;
     private static final int EVENT_CARD_ADDED = 14;
@@ -101,28 +109,31 @@
         if (DBG) log("Creating");
         mContext = c;
         mActive = isActive;
-        mCardState = null;
+        mSupportedMepMode = MultipleEnabledProfilesMode.NONE;
     }
 
     /**
      * Update slot. The main trigger for this is a change in the ICC Card status.
      */
     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;
+            CardState oldState = mCardState.get(ics.mSlotPortMapping.mPortIndex);
+            mCardState.put(ics.mSlotPortMapping.mPortIndex, ics.mCardState);
             mIccIds.put(ics.mSlotPortMapping.mPortIndex, ics.iccid);
             parseAtr(ics.atr);
             mIsRemovable = isSlotRemovable(slotIndex);
+            // Update supported MEP mode in IccCardStatus if the CardState is present.
+            if (ics.mCardState.isCardPresent()) {
+                updateSupportedMepMode(ics.mSupportedMepMode);
+            }
 
             int radioState = ci.getRadioState();
             if (DBG) {
                 log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState);
             }
 
-            if (absentStateUpdateNeeded(oldState)) {
+            if (absentStateUpdateNeeded(oldState, ics.mSlotPortMapping.mPortIndex)) {
                 updateCardStateAbsent(ci.getRadioState(), phoneId,
                         ics.mSlotPortMapping.mPortIndex);
             // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to
@@ -130,7 +141,8 @@
             //   1. mCardState is changing from ABSENT to non ABSENT.
             //   2. The latest mCardState is not ABSENT, but there is no UiccCard instance.
             } else if ((oldState == null || oldState == CardState.CARDSTATE_ABSENT
-                    || mUiccCard == null) && mCardState != CardState.CARDSTATE_ABSENT) {
+                    || mUiccCard == null) && mCardState.get(ics.mSlotPortMapping.mPortIndex)
+                    != CardState.CARDSTATE_ABSENT) {
                 // No notification while we are just powering up
                 if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE
                         && mLastRadioState.getOrDefault(ics.mSlotPortMapping.mPortIndex,
@@ -141,14 +153,17 @@
                 }
 
                 // card is present in the slot now; create new mUiccCard
-                if (mUiccCard != null) {
+                if (mUiccCard != null && (!mIsEuicc
+                        || ArrayUtils.isEmpty(mUiccCard.getUiccPortList()))) {
                     loge("update: mUiccCard != null when card was present; disposing it now");
                     mUiccCard.dispose();
+                    mUiccCard = null;
                 }
 
                 if (!mIsEuicc) {
                     // Uicc does not support MEP, passing false by default.
-                    mUiccCard = new UiccCard(mContext, ci, ics, phoneId, mLock, false);
+                    mUiccCard = new UiccCard(mContext, ci, ics, phoneId, mLock,
+                            MultipleEnabledProfilesMode.NONE);
                 } else {
                     // The EID should be reported with the card status, but in case it's not we want
                     // to catch that here
@@ -156,8 +171,14 @@
                         loge("update: eid is missing. ics.eid="
                                 + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, ics.eid));
                     }
-                    mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock,
-                            isMultipleEnabledProfileSupported());
+                    if (mUiccCard == null) {
+                        mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock,
+                                getSupportedMepMode());
+                    } else {
+                        // In MEP case, UiccCard instance is already created, just call update API.
+                        // UiccPort initialization is handled inside UiccCard.
+                        mUiccCard.update(mContext, ci, ics, phoneId);
+                    }
                 }
             } else {
                 if (mUiccCard != null) {
@@ -172,37 +193,30 @@
      * Update slot based on IccSlotStatus.
      */
     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;
             parseAtr(iss.atr);
-            mCardState = iss.cardState;
             mEid = iss.eid;
             mIsRemovable = isSlotRemovable(slotIndex);
 
             for (int i = 0; i < simPortInfos.length; i++) {
                 int phoneId = iss.mSimPortInfos[i].mLogicalSlotIndex;
+                CardState oldState = mCardState.get(i);
+                mCardState.put(i, iss.cardState);
                 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.
-                    if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                        UiccController.getInstance().updateSimStateForInactivePort(
-                                mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
-                                iss.mSimPortInfos[i].mIccId);
-                    } else {
-                        UiccController.updateInternalIccStateForInactivePort(mContext,
-                                mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
-                                iss.mSimPortInfos[i].mIccId);
-                    }
+                    UiccController.getInstance().updateSimStateForInactivePort(
+                            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)) {
+                    if (absentStateUpdateNeeded(oldState, i)) {
                         int radioState = SubscriptionManager.isValidPhoneId(phoneId) ?
                                 ci[phoneId].getRadioState() :
                                 TelephonyManager.RADIO_POWER_UNAVAILABLE;
@@ -229,10 +243,28 @@
                 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
+            updateSupportedMepMode(iss.mSupportedMepMode);
+            // Since the MEP capability is related to supported MEP mode, thus need to
             // update the flag after UiccCard creation.
             if (mUiccCard != null) {
-                mUiccCard.updateSupportMultipleEnabledProfile(isMultipleEnabledProfileSupported());
+                mUiccCard.updateSupportedMepMode(getSupportedMepMode());
+            }
+        }
+    }
+
+    private void updateSupportedMepMode(MultipleEnabledProfilesMode mode) {
+        mSupportedMepMode = mode;
+        // If SupportedMepMode is MultipleEnabledProfilesMode.NONE, validate ATR and
+        // num of ports to handle backward compatibility for < RADIO_HAL_VERSION_2_1.
+        if (mode == MultipleEnabledProfilesMode.NONE) {
+            // 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.
+            if (mPortIdxToPhoneId.size() > 1
+                    && mAtr != null && mAtr.isMultipleEnabledProfilesSupported()) {
+                // Set MEP-B mode in case if modem sends wrong mode even though supports MEP.
+                Log.i(TAG, "Modem does not send proper supported MEP mode or older HAL version");
+                mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B;
             }
         }
     }
@@ -306,16 +338,14 @@
 
     /* 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();
+        synchronized (mLock) {
+            return mSupportedMepMode.isMepMode();
+        }
     }
 
-    private boolean absentStateUpdateNeeded(CardState oldState) {
+    private boolean absentStateUpdateNeeded(CardState oldState, int portIndex) {
         return (oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null)
-                && mCardState == CardState.CARDSTATE_ABSENT;
+                && mCardState.get(portIndex) == CardState.CARDSTATE_ABSENT;
     }
 
     private void updateCardStateAbsent(int radioState, int phoneId, int portIndex) {
@@ -328,15 +358,12 @@
             sendMessage(obtainMessage(EVENT_CARD_REMOVED, null));
         }
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            UiccController.getInstance().updateSimState(phoneId, IccCardConstants.State.ABSENT,
-                    null);
-        } else {
-            UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT,
-                    null, phoneId);
-        }
-        // no card present in the slot now; dispose card and make mUiccCard null
-        nullifyUiccCard(false /* sim state is not unknown */);
+        UiccController.getInstance().updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
+        // no card present in the slot now; dispose port and then card if needed.
+        disposeUiccCardIfNeeded(false /* sim state is not unknown */, portIndex);
+        // If SLOT_STATUS is the last event, wrong subscription is getting invalidate during
+        // slot switch event. To avoid it, reset the phoneId corresponding to the portIndex.
+        mPortIdxToPhoneId.put(portIndex, INVALID_PHONE_ID);
         mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE);
     }
 
@@ -351,8 +378,23 @@
         mUiccCard = null;
     }
 
+    private void disposeUiccCardIfNeeded(boolean isStateUnknown, int portIndex) {
+        if (mUiccCard != null) {
+            // First dispose UiccPort corresponding to the portIndex
+            mUiccCard.disposePort(portIndex);
+            if (ArrayUtils.isEmpty(mUiccCard.getUiccPortList())) {
+                // No UiccPort objects are found, safe to dispose the card
+                nullifyUiccCard(isStateUnknown);
+            }
+        } else {
+            mStateIsUnknown = isStateUnknown;
+        }
+    }
+
     public boolean isStateUnknown() {
-        if (mCardState == null || mCardState == CardState.CARDSTATE_ABSENT) {
+        // CardState is not specific to any port index, use default port.
+        CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX);
+        if (cardState == null || cardState == CardState.CARDSTATE_ABSENT) {
             // mStateIsUnknown is valid only in this scenario.
             return mStateIsUnknown;
         }
@@ -563,11 +605,9 @@
      */
     public CardState getCardState() {
         synchronized (mLock) {
-            if (mCardState == null) {
-                return CardState.CARDSTATE_ABSENT;
-            } else {
-                return mCardState;
-            }
+            // CardState is not specific to any port index, use default port.
+            CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX);
+            return cardState == null ? CardState.CARDSTATE_ABSENT : cardState;
         }
     }
 
@@ -581,24 +621,27 @@
     }
 
     /**
+     * Returns the supported MEP mode.
+     */
+    public MultipleEnabledProfilesMode getSupportedMepMode() {
+        synchronized (mLock) {
+            return mSupportedMepMode;
+        }
+    }
+    /**
      * Processes radio state unavailable event
      */
     public void onRadioStateUnavailable(int phoneId) {
-        nullifyUiccCard(true /* sim state is unknown */);
+        int portIndex = getPortIndexFromPhoneId(phoneId);
+        disposeUiccCardIfNeeded(true /* sim state is unknown */, portIndex);
 
         if (phoneId != INVALID_PHONE_ID) {
-            if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-                UiccController.getInstance().updateSimState(phoneId,
-                        IccCardConstants.State.UNKNOWN, null);
-            } else {
-                UiccController.updateInternalIccState(
-                        mContext, IccCardConstants.State.UNKNOWN, null, phoneId);
-            }
-            mLastRadioState.put(getPortIndexFromPhoneId(phoneId),
-                    TelephonyManager.RADIO_POWER_UNAVAILABLE);
+            UiccController.getInstance().updateSimState(phoneId,
+                    IccCardConstants.State.UNKNOWN, null);
         }
-
-        mCardState = null;
+        mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE);
+        // Reset CardState
+        mCardState.put(portIndex, null);
     }
 
     private void log(String msg) {
@@ -612,32 +655,41 @@
     private Map<Integer, String> getPrintableIccIds() {
         Map<Integer, String> printableIccIds = mIccIds.entrySet().stream()
                 .collect(Collectors.toMap(Map.Entry::getKey,
-                        e -> SubscriptionInfo.givePrintableIccid(e.getValue())));
+                        e -> SubscriptionInfo.getPrintableId(e.getValue())));
         return printableIccIds;
     }
 
     /**
      * Dump
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccSlot:");
-        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(" mCardState=" + mCardState);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        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("mCardState=" + mCardState);
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
         if (mUiccCard != null) {
-            pw.println(" mUiccCard=" + mUiccCard);
+            pw.println("mUiccCard=");
             mUiccCard.dump(fd, pw, args);
         } else {
-            pw.println(" mUiccCard=null");
+            pw.println("mUiccCard=null");
         }
         pw.println();
         pw.flush();
     }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "[UiccSlot: mActive=" + mActive + ", mIccId=" + getPrintableIccIds() + ", mIsEuicc="
+                + mIsEuicc + ", MEP=" + isMultipleEnabledProfileSupported() + ", mPortIdxToPhoneId="
+                + mPortIdxToPhoneId + ", mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid)
+                + ", mCardState=" + mCardState + " mSupportedMepMode=" + mSupportedMepMode + "]";
+    }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UsimFileHandler.java b/src/java/com/android/internal/telephony/uicc/UsimFileHandler.java
old mode 100755
new mode 100644
diff --git a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
index fc58d3c..ea2bf42 100644
--- a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
+++ b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
@@ -157,4 +157,8 @@
     protected Object[] getValues() {
         return UsimService.values();
     }
+
+    public byte[] getUSIMServiceTable() {
+        return mServiceTable;
+    }
 }
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..698fbc8 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc.euicc;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -23,10 +24,12 @@
 import android.os.RegistrantList;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
@@ -43,8 +46,8 @@
     private RegistrantList mEidReadyRegistrants;
 
     public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            boolean isSupportsMultipleEnabledProfiles) {
-        super(c, ci, ics, phoneId, lock, isSupportsMultipleEnabledProfiles);
+            MultipleEnabledProfilesMode supportedMepMode) {
+        super(c, ci, ics, phoneId, lock, supportedMepMode);
         if (TextUtils.isEmpty(ics.eid)) {
             loge("no eid given in constructor for phone " + phoneId);
             loadEidAndNotifyRegistrants();
@@ -55,17 +58,17 @@
     }
 
     /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
+     * Updates MEP(Multiple Enabled Profile) supported mode flag.
      *
      * <p>If IccSlotStatus comes later, the number of ports reported is only known after the
-     * UiccCard creation which will impact UICC MEP capability.
+     * UiccCard creation which will impact UICC MEP capability in case of old HAL version.
      */
     @Override
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        mIsSupportsMultipleEnabledProfiles = supported;
+    public void updateSupportedMepMode(MultipleEnabledProfilesMode supportedMepMode) {
+        mSupportedMepMode = supportedMepMode;
         for (UiccPort port : mUiccPorts.values()) {
             if (port instanceof EuiccPort) {
-                ((EuiccPort) port).updateSupportMultipleEnabledProfile(supported);
+                ((EuiccPort) port).updateSupportedMepMode(supportedMepMode);
             } else {
                 loge("eUICC card has non-euicc port object:" + port.toString());
             }
@@ -175,10 +178,14 @@
         }
     }
 
+    @NonNull
     @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        super.dump(fd, printWriter, args);
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("EuiccCard:");
-        pw.println(" mEid=" + mEid);
+        pw.increaseIndent();
+        pw.println("mEid=" + mEid);
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
index 639915a..3bd66f8 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
@@ -28,6 +28,7 @@
 import android.telephony.euicc.EuiccNotification;
 import android.telephony.euicc.EuiccRulesAuthTable;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
@@ -35,7 +36,9 @@
 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.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.PortUtils;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.asn1.Asn1Decoder;
@@ -101,9 +104,6 @@
     private static final String DEV_CAP_NR5GC = "nr5gc";
     private static final String DEV_CAP_EUTRAN5GC = "eutran5gc";
 
-    private static final String ATR_ESIM_OS_V_M5 =
-            "3B9F97C00AB1FE453FC6838031E073FE211F65D002341569810F21";
-
     // These interfaces are used for simplifying the code by leveraging lambdas.
     private interface ApduRequestBuilder {
         void build(RequestBuilder requestBuilder)
@@ -127,11 +127,10 @@
     private EuiccSpecVersion mSpecVersion;
     private volatile String mEid;
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public boolean mIsSupportsMultipleEnabledProfiles;
-    private String mAtr;
+    public MultipleEnabledProfilesMode mSupportedMepMode;
 
     public EuiccPort(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            UiccCard card, boolean isSupportsMultipleEnabledProfiles) {
+            UiccCard card, MultipleEnabledProfilesMode supportedMepMode) {
         super(c, ci, ics, phoneId, lock, card);
         // TODO: Set supportExtendedApdu based on ATR.
         mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */);
@@ -141,8 +140,7 @@
             mEid = ics.eid;
             mCardId = ics.eid;
         }
-        mAtr = ics.atr;
-        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
+        mSupportedMepMode = supportedMepMode;
     }
 
     /**
@@ -165,18 +163,17 @@
             if (!TextUtils.isEmpty(ics.eid)) {
                 mEid = ics.eid;
             }
-            mAtr = ics.atr;
             super.update(c, ci, ics, uiccCard);
         }
     }
 
     /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
+     * Updates MEP(Multiple Enabled Profile) supported mode flag.
      * The flag can be updated after the port creation.
      */
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        logd("updateSupportMultipleEnabledProfile");
-        mIsSupportsMultipleEnabledProfiles = supported;
+    public void updateSupportedMepMode(MultipleEnabledProfilesMode supportedMepMode) {
+        logd("updateSupportedMepMode");
+        mSupportedMepMode = supportedMepMode;
     }
 
     /**
@@ -187,13 +184,8 @@
      * @since 1.1.0 [GSMA SGP.22]
      */
     public void getAllProfiles(AsyncResultCallback<EuiccProfileInfo[]> callback, Handler handler) {
-        byte[] profileTags;
-        if (mIsSupportsMultipleEnabledProfiles) {
-            profileTags = ATR_ESIM_OS_V_M5.equals(mAtr)
-                    ? Tags.EUICC_PROFILE_MEP_TAGS : Tags.EUICC_PROFILE_MEP_TAGS_WITH_9F20;
-        } else {
-            profileTags = Tags.EUICC_PROFILE_TAGS;
-        }
+        byte[] profileTags = mSupportedMepMode.isMepMode() ? Tags.EUICC_PROFILE_MEP_TAGS
+                : Tags.EUICC_PROFILE_TAGS;
         sendApdu(
                 newRequestProvider((RequestBuilder requestBuilder) ->
                         requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
@@ -234,13 +226,8 @@
      */
     public final void getProfile(String iccid, AsyncResultCallback<EuiccProfileInfo> callback,
             Handler handler) {
-        byte[] profileTags;
-        if (mIsSupportsMultipleEnabledProfiles) {
-            profileTags = ATR_ESIM_OS_V_M5.equals(mAtr)
-                    ? Tags.EUICC_PROFILE_MEP_TAGS : Tags.EUICC_PROFILE_MEP_TAGS_WITH_9F20;
-        } else {
-            profileTags = Tags.EUICC_PROFILE_TAGS;
-        }
+        byte[] profileTags = mSupportedMepMode.isMepMode() ? Tags.EUICC_PROFILE_MEP_TAGS
+                : Tags.EUICC_PROFILE_TAGS;
         sendApdu(
                 newRequestProvider((RequestBuilder requestBuilder) ->
                         requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
@@ -295,7 +282,7 @@
                             return null;
                         case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
                             logd("Profile is already disabled, iccid: "
-                                    + SubscriptionInfo.givePrintableIccid(iccid));
+                                    + SubscriptionInfo.getPrintableId(iccid));
                             return null;
                         default:
                             throw new EuiccCardErrorException(
@@ -319,11 +306,20 @@
         sendApduWithSimResetErrorWorkaround(
                 newRequestProvider((RequestBuilder requestBuilder) -> {
                     byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
-                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_ENABLE_PROFILE)
+                    Asn1Node.Builder builder = 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());
+                            .addChildAsBoolean(Tags.TAG_CTX_1, refresh);
+                    // Port index should be added only in case of MEP-A1 mode.
+                    if (mSupportedMepMode.isMepA1Mode()) {
+                        // In case of MEP-A1 and MEP-A2, profiles are selected on eSIM Ports 1 and
+                        // higher (refer as target port). Hence, convert the portIndex to
+                        // target port index before adding.
+                        builder.addChildAsInteger(Tags.TAG_CTX_2,
+                                PortUtils.convertToHalPortIndex(mSupportedMepMode,
+                                        super.getPortIdx()));
+                    }
+                    requestBuilder.addStoreData(builder.build().toHex());
                 }),
                 response -> {
                     int result;
@@ -334,7 +330,7 @@
                             return null;
                         case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
                             logd("Profile is already enabled, iccid: "
-                                    + SubscriptionInfo.givePrintableIccid(iccid));
+                                    + SubscriptionInfo.getPrintableId(iccid));
                             return null;
                         default:
                             throw new EuiccCardErrorException(
@@ -1262,10 +1258,8 @@
             // 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)
-                    || (profileNode.hasChild(Tags.TAG_PORT_9F20)
-                    && profileNode.getChild(Tags.TAG_PORT_9F20).asInteger() >= 0)) {
+            if (profileNode.hasChild(Tags.TAG_PORT)
+                    && profileNode.getChild(Tags.TAG_PORT).asInteger() >= 0) {
                 profileBuilder.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED);
             } else {
                 // noinspection WrongConstant
@@ -1430,10 +1424,13 @@
     }
 
     @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        super.dump(fd, printWriter, args);
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("EuiccPort:");
-        pw.println(" mEid=" + mEid);
-        pw.println(" mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
+        pw.increaseIndent();
+        pw.println("mEid=" + mEid);
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
+        pw.decreaseIndent();
     }
 }
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 3aa9ef9..befc7f9 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/Tags.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/Tags.java
@@ -84,10 +84,7 @@
     static final int TAG_PROFILE_NAME = 0x92;
     static final int TAG_OPERATOR_ID = 0xB7;
     static final int TAG_CARRIER_PRIVILEGE_RULES = 0xBF76;
-    // TODO: PORT TAG(9F20 OR 9F24) will be used based on ATR Strings because not all MEP capable
-    //  devices have M5 OS. Once modem team is ready, revert back to 9F24 TAG only.
     static final int TAG_PORT = 0x9F24;
-    static final int TAG_PORT_9F20 = 0x9F20;
 
     // Tags from the RefArDo data standard - https://source.android.com/devices/tech/config/uicc
     static final int TAG_REF_AR_DO = 0xE2;
@@ -129,22 +126,5 @@
             (byte) (TAG_PORT % 256),
     };
 
-    // TAG list for Euicc Profile with 9F20 tag.
-    // TODO: This is temporary change, should be removed once all devices are upgraded to M5 OS.
-    static final byte[] EUICC_PROFILE_MEP_TAGS_WITH_9F20 = 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_9F20 / 256),
-            (byte) (TAG_PORT_9F20 % 256),
-    };
     private Tags() {}
 }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduCommand.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduCommand.java
index 7a8978f..8fbeb44 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduCommand.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduCommand.java
@@ -43,6 +43,12 @@
     /** Command data of an APDU as defined in GlobalPlatform Card Specification v.2.3. */
     public final String cmdHex;
 
+    /**
+     * isEs10 indicates that the current streaming APDU contains an ES10 command or it is a regular
+     * APDU. (As per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A1)
+     */
+    public final boolean isEs10;
+
     /** The parameters are defined as in GlobalPlatform Card Specification v.2.3. */
     ApduCommand(int channel, int cla, int ins, int p1, int p2, int p3, String cmdHex) {
         this.channel = channel;
@@ -52,11 +58,14 @@
         this.p2 = p2;
         this.p3 = p3;
         this.cmdHex = cmdHex;
+        // TODO: Currently ApduCommand is used for ES10 commands, so updating to true by default.
+        //  Modify it in case used for non ES10 commands in future.
+        this.isEs10 = true;
     }
 
     @Override
     public String toString() {
         return "ApduCommand(channel=" + channel + ", cla=" + cla + ", ins=" + ins + ", p1=" + p1
-                + ", p2=" + p2 + ", p3=" + p3 + ", cmd=" + cmdHex + ")";
+                + ", p2=" + p2 + ", p3=" + p3 + ", cmd=" + cmdHex + ", isEs10=" + isEs10 + ")";
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/CloseLogicalChannelInvocation.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/CloseLogicalChannelInvocation.java
index 82ddb80..a69977b 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/CloseLogicalChannelInvocation.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/CloseLogicalChannelInvocation.java
@@ -43,7 +43,10 @@
     @Override
     protected void sendRequestMessage(Integer channel, Message msg) {
         Rlog.v(LOG_TAG, "Channel: " + channel);
-        mCi.iccCloseLogicalChannel(channel, msg);
+        // TODO: Currently CloseLogicalChannelInvocation is used from ApduSender for closing the
+        //  channel opened on ISD-R. Hence passing isEs10 as true by default.
+        //  Should modify the logic in future if the ApduSender is used with non ISD-R AID.
+        mCi.iccCloseLogicalChannel(channel, true /*isEs10*/, msg);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/TransmitApduLogicalChannelInvocation.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/TransmitApduLogicalChannelInvocation.java
index 09de54a..ca75beb 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/TransmitApduLogicalChannelInvocation.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/TransmitApduLogicalChannelInvocation.java
@@ -48,7 +48,8 @@
     protected void sendRequestMessage(ApduCommand command, Message msg) {
         Rlog.v(LOG_TAG, "Send: " + command);
         mCi.iccTransmitApduLogicalChannel(command.channel, command.cla | command.channel,
-                command.ins, command.p1, command.p2, command.p3, command.cmdHex, msg);
+                command.ins, command.p1, command.p2, command.p3, command.cmdHex, command.isEs10,
+                msg);
     }
 
     @Override
diff --git a/tests/telephonytests/assets/eccdata b/tests/telephonytests/assets/eccdata
index 4c5959b..bd9ff47 100644
--- a/tests/telephonytests/assets/eccdata
+++ b/tests/telephonytests/assets/eccdata
Binary files differ
diff --git a/tests/telephonytests/assets/eccdata_input.txt b/tests/telephonytests/assets/eccdata_input.txt
index 8dcfa75..6f8632c 100644
--- a/tests/telephonytests/assets/eccdata_input.txt
+++ b/tests/telephonytests/assets/eccdata_input.txt
@@ -10,6 +10,57 @@
     types: MOUNTAIN_RESCUE
     types: MIEC
     types: AIEC
+    routing: NORMAL
+    normal_routing_mncs: "05"
+  }
+  eccs {
+    phone_number: "888"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+    types: MARINE_GUARD
+    types: MOUNTAIN_RESCUE
+    types: MIEC
+    types: AIEC
+    routing: NORMAL
+    normal_routing_mncs: "45"
+    normal_routing_mncs: "47"
+    normal_routing_mncs: "05"
+  }
+  eccs {
+    phone_number: "654321"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+    types: MARINE_GUARD
+    types: MOUNTAIN_RESCUE
+    types: MIEC
+    types: AIEC
+    routing: EMERGENCY
+    normal_routing_mncs: ""
+  }
+  eccs {
+    phone_number: "7654321"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+    types: MARINE_GUARD
+    types: MOUNTAIN_RESCUE
+    types: MIEC
+    types: AIEC
+    routing: NORMAL
+    normal_routing_mncs: ""
+  }
+  eccs {
+    phone_number: "4321"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+    types: MARINE_GUARD
+    types: MOUNTAIN_RESCUE
+    types: MIEC
+    types: AIEC
+    routing: NORMAL
   }
   ecc_fallback: "911"
 }
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index af80bd7..56ce6bc 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -16,9 +16,13 @@
 
 package android.telephony.ims;
 
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+
 import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -147,7 +151,33 @@
         ImsReasonInfo info = new ImsReasonInfo();
         mRegistration.onDeregistered(info);
 
-        verify(mCallback).onDeregistered(eq(info));
+        verify(mCallback).onDeregistered(eq(info), anyInt(), anyInt());
+    }
+
+    @SmallTest
+    @Test
+    public void testRegistrationCallbackOnDeregisteredWithSuggestedAction() throws RemoteException {
+        ImsReasonInfo info = new ImsReasonInfo();
+        mRegistration.onDeregistered(info,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_LTE);
+
+        verify(mCallback).onDeregistered(eq(info),
+                eq(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK), eq(REGISTRATION_TECH_LTE));
+    }
+
+    @SmallTest
+    @Test
+    public void testRegistrationCallbackOnDeregisteredWithRegistrationAttributes()
+            throws RemoteException {
+        ImsReasonInfo info = new ImsReasonInfo();
+        SipDetails details = new SipDetails.Builder(SipDetails.METHOD_REGISTER)
+                .setCSeq(1).setSipResponseCode(200, "OK")
+                .setSipResponseReasonHeader(10, "reasonText")
+                .setCallId("testCallId").build();
+
+        mRegistration.onDeregistered(info, details);
+
+        verify(mCallback).onDeregisteredWithDetails(eq(info), anyInt(), anyInt(), eq(details));
     }
 
     @SmallTest
@@ -218,10 +248,10 @@
 
         // The original callback that has been registered should get LTE tech in disconnected
         // message
-        verify(mCallback).onDeregistered(eq(info));
+        verify(mCallback).onDeregistered(eq(info), anyInt(), anyInt());
         // A callback that has just been registered should get NONE for tech in disconnected
         // message
-        verify(mCallback2).onDeregistered(eq(info));
+        verify(mCallback2).onDeregistered(eq(info), anyInt(), anyInt());
     }
 
     @SmallTest
@@ -231,7 +261,7 @@
 
         mRegistration.onDeregistered(info);
 
-        verify(mCallback).onDeregistered(eq(info));
+        verify(mCallback).onDeregistered(eq(info), anyInt(), anyInt());
         assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_NONE,
                 mRegBinder.getRegistrationTechnology());
     }
@@ -242,7 +272,7 @@
         mRegBinder.addRegistrationCallback(mCallback2);
         // Verify that if we have never set the registration state, we do not callback immediately
         // with onUnregistered.
-        verify(mCallback2, never()).onDeregistered(any(ImsReasonInfo.class));
+        verify(mCallback2, never()).onDeregistered(any(ImsReasonInfo.class), anyInt(), anyInt());
     }
 
     @SmallTest
diff --git a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index 5af871c..b002b35 100644
--- a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -151,13 +152,27 @@
 
         mFeature.incomingCall(session);
         ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class);
-        verify(mListener).onIncomingCall(captor.capture(), any());
+        verify(mListener).onIncomingCall(captor.capture(), eq(null), any());
 
         assertEquals(sessionBinder, captor.getValue());
     }
 
     @SmallTest
     @Test
+    public void testNewIncomingCallReturnListener() throws Exception {
+        IImsCallSession sessionBinder = Mockito.mock(IImsCallSession.class);
+        ImsCallSessionImplBase session = new ImsCallSessionImplBase();
+        session.setServiceImpl(sessionBinder);
+        String callId = "callID";
+        Bundle extra = new Bundle();
+        mFeature.incomingCall(session, callId, extra);
+        ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class);
+        verify(mListener).onIncomingCall(captor.capture(), eq(callId), eq(extra));
+        assertEquals(sessionBinder, captor.getValue());
+    }
+
+    @SmallTest
+    @Test
     public void testSetTtyMessageMessenger() throws Exception {
         Message resultMessage = Message.obtain(mHandler, TEST_TTY_RESULT);
         resultMessage.replyTo = mHandlerMessenger;
diff --git a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
index 9ee1e30..1269cc8 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
@@ -64,6 +64,11 @@
         notifyIncomingCall(c, new Bundle());
     }
 
+    public ImsCallSessionListener incomingCall(
+            ImsCallSessionImplBase c, String callId, Bundle extra) {
+        return notifyIncomingCall(c, callId, extra);
+    }
+
     @Override
     public ImsCallProfile createCallProfile(int callSessionType, int callType) {
         return super.createCallProfile(callSessionType, callType);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CallStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/CallStateTest.java
new file mode 100644
index 0000000..4e319a1
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/CallStateTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.telephony.CallQuality;
+import android.telephony.CallState;
+import android.telephony.PreciseCallState;
+import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Simple GTS test verifying the parceling and unparceling of CallAttributes.
+ */
+public class CallStateTest extends AndroidTestCase {
+
+
+    @SmallTest
+    public void testParcelUnparcelPreciseCallState() {
+        CallState data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_INCOMING)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(null)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_RINGING)
+                .setImsCallSessionId("1")
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NONE)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_NONE).build();
+
+        Parcel parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CallState unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertEquals("PreciseCallState is not equal after parceled/unparceled",
+                data.getCallState(),
+                unparceledData.getCallState());
+    }
+
+    @SmallTest
+    public void testParcelUnparcelCallQuality() {
+        CallQuality quality = new CallQuality();
+        CallState data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_IDLE)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(null)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_FOREGROUND)
+                .setImsCallSessionId(null)
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NONE)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_NONE).build();
+
+
+        Parcel parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CallState unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertNull(unparceledData.getCallQuality());
+
+        data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_IDLE)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(quality)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_FOREGROUND)
+                .setImsCallSessionId(null)
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NONE)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_NONE).build();
+
+
+        parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertEquals("CallQuality is not equal after parceled/unparceled",
+                data.getCallQuality(),
+                unparceledData.getCallQuality());
+    }
+
+    @SmallTest
+    public void testParcelUnparcelNetworkTypeAndClassification() {
+        CallQuality quality = new CallQuality();
+        CallState data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_DIALING)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(null)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_FOREGROUND)
+                .setImsCallSessionId("3")
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NONE)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_NONE).build();
+
+        Parcel parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CallState unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertEquals("NetworkType is not equal after parceled/unparceled",
+                data.getNetworkType(),
+                unparceledData.getNetworkType());
+        assertEquals("Call classification is not equal after parceled/unparceled",
+                data.getCallClassification(),
+                unparceledData.getCallClassification());
+    }
+
+    @Test
+    public void testParcelUnparcelImsCallInfo() {
+        CallQuality quality = new CallQuality();
+        CallState data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_DIALING)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(null)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_FOREGROUND)
+                .setImsCallSessionId(null)
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NORMAL)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_VOICE).build();
+
+        Parcel parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        CallState unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertNull(unparceledData.getImsCallSessionId());
+
+        assertEquals("Ims call service type is not equal after parceled/unparceled",
+                data.getImsCallServiceType(),
+                unparceledData.getImsCallServiceType());
+
+        assertEquals("Ims call type is not equal after parceled/unparceled",
+                data.getImsCallType(),
+                unparceledData.getImsCallType());
+
+        data = new CallState.Builder(PreciseCallState.PRECISE_CALL_STATE_ACTIVE)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setCallQuality(quality)
+                .setCallClassification(CallState.CALL_CLASSIFICATION_FOREGROUND)
+                .setImsCallSessionId("2")
+                .setImsCallServiceType(ImsCallProfile.SERVICE_TYPE_NORMAL)
+                .setImsCallType(ImsCallProfile.CALL_TYPE_VT).build();
+
+        parcel = Parcel.obtain();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        unparceledData = CallState.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        assertEquals("Ims call session ID is not equal after parceled/unparceled",
+                data.getImsCallSessionId(),
+                unparceledData.getImsCallSessionId());
+
+        assertEquals("Ims call service type is not equal after parceled/unparceled",
+                data.getImsCallServiceType(),
+                unparceledData.getImsCallServiceType());
+
+        assertEquals("Ims call type is not equal after parceled/unparceled",
+                data.getImsCallType(),
+                unparceledData.getImsCallType());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CallWaitingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CallWaitingControllerTest.java
new file mode 100644
index 0000000..eb18adb
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/CallWaitingControllerTest.java
@@ -0,0 +1,477 @@
+/*
+ * 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;
+
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_FIRST_CHANGE;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_FIRST_POWER_UP;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_IMS_ONLY;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_NONE;
+import static android.telephony.CarrierConfigManager.ImsSs.CALL_WAITING_SYNC_USER_CHANGE;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT;
+import static android.telephony.CarrierConfigManager.ImsSs.KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsSs.SUPPLEMENTARY_SERVICE_CW;
+
+import static com.android.internal.telephony.CallWaitingController.KEY_CS_SYNC;
+import static com.android.internal.telephony.CallWaitingController.KEY_STATE;
+import static com.android.internal.telephony.CallWaitingController.KEY_SUB_ID;
+import static com.android.internal.telephony.CallWaitingController.PREFERENCE_TBCW;
+import static com.android.internal.telephony.CallWaitingController.TERMINAL_BASED_ACTIVATED;
+import static com.android.internal.telephony.CallWaitingController.TERMINAL_BASED_NOT_ACTIVATED;
+import static com.android.internal.telephony.CallWaitingController.TERMINAL_BASED_NOT_SUPPORTED;
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_DATA;
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE;
+import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.test.suitebuilder.annotation.SmallTest;
+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;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class CallWaitingControllerTest extends TelephonyTest {
+    private static final int FAKE_SUB_ID = 1;
+
+    private static final int GET_DONE = 1;
+
+    private CallWaitingController mCWC;
+    private GetTestHandler mHandler;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(this.getClass().getSimpleName());
+        mSimulatedCommands.setRadioPower(true, null);
+        mPhone.mCi = this.mSimulatedCommands;
+        doReturn(FAKE_SUB_ID).when(mPhone).getSubId();
+
+        mCWC = new CallWaitingController(mPhone);
+        logd("CallWaitingController initiated, waiting for Power on");
+        /* Make sure radio state is power on before dial.
+         * When radio state changed from off to on, CallTracker
+         * will poll result from RIL. Avoid dialing triggered at the same*/
+        processAllMessages();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mCWC = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testSetTerminalBasedCallWaitingSupported() {
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_NONE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_SUPPORTED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_SUPPORTED);
+    }
+
+    @Test
+    @SmallTest
+    public void testInitialize() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_ACTIVATED, CALL_WAITING_SYNC_NONE);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_NONE, true);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), any());
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_NOT_ACTIVATED, CALL_WAITING_SYNC_NONE);
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        bundle = getConfigBundle(false, CALL_WAITING_SYNC_NONE, false);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), any());
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_SUPPORTED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_SUPPORTED);
+    }
+
+    @Test
+    @SmallTest
+    public void testCarrierConfigChanged() {
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_NONE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+
+        bundle = getConfigBundle(false, CALL_WAITING_SYNC_NONE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, false);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_SUPPORTED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_SUPPORTED);
+    }
+
+
+    private static class GetTestHandler extends Handler {
+        public int[] resp;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case GET_DONE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    resp = (int[]) ar.result;
+                    break;
+                default:
+            }
+        }
+
+        public void reset() {
+            resp = null;
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testGetCallWaitingSyncNone() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        assertFalse(mCWC.getCallWaiting(null));
+
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_NONE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        mHandler = new GetTestHandler();
+
+        assertTrue(mCWC.setCallWaiting(true, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_VOICE, mHandler.resp[1]);
+
+        mHandler.reset();
+
+        assertTrue(mCWC.setCallWaiting(false, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_NOT_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_NONE, mHandler.resp[1]);
+    }
+
+    @Test
+    @SmallTest
+    public void testSetCallWaitingSyncNone() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        assertFalse(mCWC.setCallWaiting(true, SERVICE_CLASS_VOICE, null));
+
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_NONE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        assertTrue(mCWC.setCallWaiting(true, SERVICE_CLASS_VOICE, null));
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        assertTrue(mCWC.setCallWaiting(false, SERVICE_CLASS_VOICE | SERVICE_CLASS_DATA, null));
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+
+        assertFalse(mCWC.setCallWaiting(true, SERVICE_CLASS_DATA, null));
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+
+        assertFalse(mCWC.setCallWaiting(true, SERVICE_CLASS_NONE, null));
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+    }
+
+    @Test
+    @SmallTest
+    public void testSyncUserChange() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_ACTIVATED, CALL_WAITING_SYNC_USER_CHANGE);
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_USER_CHANGE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        mHandler = new GetTestHandler();
+
+        mSimulatedCommands.setCallWaiting(false, SERVICE_CLASS_VOICE, null);
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_NOT_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_NONE, mHandler.resp[1]);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+
+        mHandler.reset();
+
+        mSimulatedCommands.setCallWaiting(true, SERVICE_CLASS_VOICE, null);
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_VOICE, mHandler.resp[1]);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        mHandler.reset();
+
+        assertTrue(mCWC.setCallWaiting(false, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+    }
+
+    @Test
+    @SmallTest
+    public void testSyncFirstPowerUp() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_NOT_ACTIVATED, CALL_WAITING_SYNC_FIRST_POWER_UP);
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_FIRST_POWER_UP, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+        assertFalse(mCWC.getSyncState());
+
+        mCWC.notifyRegisteredToNetwork();
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getSyncState());
+    }
+
+    @Test
+    @SmallTest
+    public void testSyncFirstChange() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_NOT_ACTIVATED, CALL_WAITING_SYNC_FIRST_CHANGE);
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_FIRST_CHANGE, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+        mCWC.setImsRegistrationState(false);
+
+        assertFalse(mCWC.getSyncState());
+
+        mSimulatedCommands.setCallWaiting(false, SERVICE_CLASS_VOICE, null);
+        mCWC.getCallWaiting(null);
+        mTestableLooper.processAllMessages();
+
+        assertFalse(mCWC.getSyncState());
+
+        mSimulatedCommands.setCallWaiting(true, SERVICE_CLASS_VOICE, null);
+        mCWC.getCallWaiting(null);
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getSyncState());
+
+        assertTrue(mCWC.setCallWaiting(true, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mSimulatedCommands.mCallWaitActivated);
+
+        assertTrue(mCWC.setCallWaiting(false, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        // Local setting changed, but no change in CS network.
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mSimulatedCommands.mCallWaitActivated);
+    }
+
+    @Test
+    @SmallTest
+    public void testSyncImsOnly() {
+        mCWC.setTerminalBasedCallWaitingSupported(false);
+        setPreference(mPhone.getPhoneId(), FAKE_SUB_ID,
+                TERMINAL_BASED_ACTIVATED, CALL_WAITING_SYNC_IMS_ONLY);
+        mCWC.setTerminalBasedCallWaitingSupported(true);
+        PersistableBundle bundle = getConfigBundle(true, CALL_WAITING_SYNC_IMS_ONLY, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(bundle);
+        mCWC.updateCarrierConfig(FAKE_SUB_ID, true);
+
+        mSimulatedCommands.setCallWaiting(false, SERVICE_CLASS_VOICE, null);
+
+        // IMS is registered
+        mCWC.setImsRegistrationState(true);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        mHandler = new GetTestHandler();
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        // result carries the service state from IMS service
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_VOICE, mHandler.resp[1]);
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        mHandler.reset();
+
+        // IMS is not registered
+        mCWC.setImsRegistrationState(false);
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        // result carries the service state from CS
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_NOT_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_NONE, mHandler.resp[1]);
+
+        // service state not synchronized between CS and IMS
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_SUPPORTED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_ACTIVATED);
+
+        mHandler.reset();
+
+        // IMS is registered
+        mCWC.setImsRegistrationState(true);
+
+        assertTrue(mCWC.setCallWaiting(false, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+
+        // IMS is not registered
+        mCWC.setImsRegistrationState(false);
+
+        assertTrue(mCWC.setCallWaiting(true, SERVICE_CLASS_VOICE, null));
+        mTestableLooper.processAllMessages();
+
+        assertTrue(mCWC.getCallWaiting(mHandler.obtainMessage(GET_DONE)));
+        mTestableLooper.processAllMessages();
+
+        // result carries the service state from CS
+        assertNotNull(mHandler.resp);
+        assertEquals(2, mHandler.resp.length);
+        assertEquals(TERMINAL_BASED_ACTIVATED, mHandler.resp[0]);
+        assertEquals(SERVICE_CLASS_VOICE, mHandler.resp[1]);
+
+        // service state not synchronized between CS and IMS
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(false) == TERMINAL_BASED_NOT_ACTIVATED);
+        assertTrue(mCWC.getTerminalBasedCallWaitingState(true) == TERMINAL_BASED_NOT_SUPPORTED);
+        assertTrue(retrieveStatePreference(mPhone.getSubId()) == TERMINAL_BASED_NOT_ACTIVATED);
+    }
+
+    private PersistableBundle getConfigBundle(boolean provisioned,
+            int preference, boolean defaultState) {
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putIntArray(KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY,
+                provisioned ? new int[] { SUPPLEMENTARY_SERVICE_CW } : new int[] { });
+        bundle.putInt(KEY_TERMINAL_BASED_CALL_WAITING_SYNC_TYPE_INT, preference);
+        bundle.putBoolean(KEY_TERMINAL_BASED_CALL_WAITING_DEFAULT_ENABLED_BOOL, defaultState);
+        return bundle;
+    }
+
+    private int retrieveStatePreference(int subId) {
+        SharedPreferences sp =
+                mContext.getSharedPreferences(PREFERENCE_TBCW, Context.MODE_PRIVATE);
+        return sp.getInt(KEY_STATE + subId, TERMINAL_BASED_NOT_SUPPORTED);
+    }
+
+    private void setPreference(int phoneId, int subId, int state, int syncPreference) {
+        SharedPreferences sp =
+                mContext.getSharedPreferences(PREFERENCE_TBCW, Context.MODE_PRIVATE);
+
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putInt(KEY_SUB_ID + phoneId, subId);
+        editor.putInt(KEY_STATE + subId, state);
+        editor.putInt(KEY_CS_SYNC + phoneId, syncPreference);
+        editor.apply();
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
index 0b7da6f..40e1821 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
@@ -45,6 +45,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 
 import java.security.PublicKey;
@@ -61,6 +62,8 @@
 
     private CarrierKeyDownloadManager mCarrierKeyDM;
 
+    private PersistableBundle mBundle;
+
     private final 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-----";
@@ -83,11 +86,23 @@
             "{ \"carrier-keys\": [ { \"key-identifier\": \"key1=value\", "
                     + "\"public-key\": \"" + CERT + "\"}]}";
 
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+
     @Before
     public void setUp() throws Exception {
         logd("CarrierActionAgentTest +Setup!");
         super.setUp(getClass().getSimpleName());
+        mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
+
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mCarrierKeyDM = new CarrierKeyDownloadManager(mPhone);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
+
         processAllMessages();
         logd("CarrierActionAgentTest -Setup!");
     }
@@ -322,7 +337,7 @@
     }
 
     /**
-     * Test sending the ACTION_CARRIER_CONFIG_CHANGED intent.
+     * Test notifying the carrier config change from listener.
      * Verify that the right mnc/mcc gets stored in the preferences.
      **/
     @Test
@@ -337,16 +352,16 @@
 
         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);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         assertEquals("310260", mCarrierKeyDM.mMccMncForDownload);
         assertEquals(1, mCarrierKeyDM.mCarrierId);
     }
 
     /**
-     * Tests sending the ACTION_CARRIER_CONFIG_CHANGED intent with an empty key.
+     * Tests notifying carrier config change from listener with an empty key.
      * Verify that the carrier keys are removed if IMSI_KEY_DOWNLOAD_URL_STRING is null.
      */
     @Test
@@ -359,9 +374,9 @@
         bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3);
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, null);
 
-        Intent mIntent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mIntent.putExtra(PhoneConstants.PHONE_KEY, 0);
-        mContext.sendBroadcast(mIntent);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         assertNull(mCarrierKeyDM.mMccMncForDownload);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
index 07011a3..06b63a2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
@@ -17,8 +17,6 @@
 package com.android.internal.telephony;
 
 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;
@@ -30,10 +28,8 @@
 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;
@@ -44,7 +40,6 @@
 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;
@@ -55,9 +50,6 @@
 import android.content.pm.Signature;
 import android.content.pm.UserInfo;
 import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.service.carrier.CarrierService;
@@ -76,8 +68,8 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
-import org.mockito.Mock;
 
 import java.security.MessageDigest;
 import java.util.ArrayList;
@@ -91,7 +83,6 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CarrierPrivilegesTrackerTest extends TelephonyTest {
-    private static final int REGISTRANT_WHAT = 1;
     private static final int PHONE_ID = 2;
     private static final int PHONE_ID_INCORRECT = 3;
     private static final int SUB_ID = 4;
@@ -129,11 +120,9 @@
                     | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                     | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
 
-    @Mock private Signature mSignature;
-
     private PersistableBundle mCarrierConfigs;
-    private CarrierPrivilegesTrackerTestHandler mHandler;
     private CarrierPrivilegesTracker mCarrierPrivilegesTracker;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     @Before
     public void setUp() throws Exception {
@@ -144,7 +133,6 @@
         when(mPhone.getSubId()).thenReturn(SUB_ID);
 
         mCarrierConfigs = new PersistableBundle();
-        mHandler = new CarrierPrivilegesTrackerTestHandler();
 
         // set mock behavior so CarrierPrivilegeTracker initializes with no privileged UIDs
         setupCarrierConfigRules();
@@ -154,7 +142,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mHandler = null;
         mCarrierPrivilegesTracker = null;
         mCarrierConfigs =  null;
         super.tearDown();
@@ -164,7 +151,8 @@
     private void setupCarrierConfigRules(String... rules) {
         mCarrierConfigs.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, rules);
         mCarrierConfigs.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-        when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfigs);
+        when(mCarrierConfigManager.getConfigForSubId(eq(SUB_ID), any()))
+                .thenReturn(mCarrierConfigs);
     }
 
     private static String carrierConfigRuleString(String certificateHash, String... packageNames) {
@@ -222,13 +210,17 @@
      * #setupInstalledPackages}.
      */
     private CarrierPrivilegesTracker createCarrierPrivilegesTracker() throws Exception {
+        // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         CarrierPrivilegesTracker cpt =
                 new CarrierPrivilegesTracker(mTestableLooper.getLooper(), mPhone, mContext);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
         mTestableLooper.processAllMessages();
 
-        cpt.registerCarrierPrivilegesListener(mHandler, REGISTRANT_WHAT, null);
         mTestableLooper.processAllMessages();
-        mHandler.reset();
 
         return cpt;
     }
@@ -252,29 +244,6 @@
         mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
     }
 
-    private class CarrierPrivilegesTrackerTestHandler extends Handler {
-        public int[] privilegedUids;
-        public int numUidUpdates;
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case REGISTRANT_WHAT:
-                    AsyncResult asyncResult = (AsyncResult) msg.obj;
-                    privilegedUids = (int[]) asyncResult.result;
-                    numUidUpdates++;
-                    break;
-                default:
-                    fail("Unexpected msg received. what=" + msg.what);
-            }
-        }
-
-        void reset() {
-            privilegedUids = null;
-            numUidUpdates = 0;
-        }
-    }
-
     private void verifyCurrentState(Set<String> expectedPackageNames, int[] expectedUids) {
         assertEquals(
                 expectedPackageNames, mCarrierPrivilegesTracker.getPackagesWithCarrierPrivileges());
@@ -290,11 +259,6 @@
         }
     }
 
-    private void verifyRegistrantUpdates(@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()) {
@@ -330,56 +294,6 @@
     }
 
     @Test
-    public void testRegisterListener() throws Exception {
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-        // mHandler registered in createCarrierPrivilegesTracker(), so reset it
-        mHandler = new CarrierPrivilegesTrackerTestHandler();
-
-        mCarrierPrivilegesTracker.registerCarrierPrivilegesListener(
-                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());
-    }
-
-    @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)));
-        mHandler.reset();
-        reset(mTelephonyRegistryManager);
-
-        mCarrierPrivilegesTracker.unregisterCarrierPrivilegesListener(mHandler);
-        mTestableLooper.processAllMessages();
-
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of());
-
-        // 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())));
-    }
-
-    @Test
     public void testCarrierConfigUpdated() throws Exception {
         // Start with packages installed and no certs
         setupInstalledPackages(
@@ -389,11 +303,10 @@
         setupCarrierConfigRules(
                 carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
 
-        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
+        sendCarrierConfigChanged(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)));
     }
@@ -403,11 +316,10 @@
         // Start with privileges. Incorrect phoneId shouldn't affect certs
         setupCarrierPrivilegesTrackerWithCarrierConfigUids();
 
-        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID_INCORRECT);
+        sendCarrierConfigChanged(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)));
     }
@@ -417,11 +329,10 @@
         // Start with privileges, verify clearing certs clears UIDs
         setupCarrierPrivilegesTrackerWithCarrierConfigUids();
 
-        sendCarrierConfigChangedIntent(INVALID_SUBSCRIPTION_ID, PHONE_ID);
+        sendCarrierConfigChanged(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),
@@ -434,13 +345,13 @@
         setupCarrierPrivilegesTrackerWithCarrierConfigUids();
 
         mCarrierConfigs.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
-        when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfigs);
+        when(mCarrierConfigManager.getConfigForSubId(eq(SUB_ID), any()))
+                .thenReturn(mCarrierConfigs);
 
-        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
+        sendCarrierConfigChanged(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())));
     }
 
@@ -456,11 +367,10 @@
                 carrierConfigRuleString(getHash(CERT_1), PACKAGE_1),
                 carrierConfigRuleString(getHash(CERT_2), PACKAGE_1));
 
-        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
+        sendCarrierConfigChanged(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))));
 
@@ -469,11 +379,10 @@
                 carrierConfigRuleString(getHash(CERT_1), PACKAGE_1),
                 carrierConfigRuleString(getHash(CERT_2), PACKAGE_1, PACKAGE_2));
 
-        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
+        sendCarrierConfigChanged(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)));
     }
@@ -492,7 +401,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(
                 List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
     }
@@ -511,7 +419,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(
                 List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
     }
@@ -527,7 +434,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(
                 List.of(
                         new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
@@ -545,7 +451,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(
                 List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
     }
@@ -568,7 +473,6 @@
 
         // 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),
@@ -597,7 +501,6 @@
 
         // 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());
     }
 
@@ -618,7 +521,6 @@
 
         // 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())));
     }
@@ -640,7 +542,6 @@
 
         // 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())));
     }
@@ -667,7 +568,6 @@
 
         // 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))));
     }
@@ -727,7 +627,6 @@
         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))));
 
@@ -741,7 +640,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(
                 List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
     }
@@ -758,7 +656,6 @@
         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))));
     }
@@ -778,7 +675,6 @@
         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)));
     }
@@ -799,7 +695,6 @@
         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)));
     }
@@ -824,7 +719,6 @@
         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))));
     }
@@ -848,7 +742,6 @@
         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))));
     }
@@ -867,7 +760,6 @@
         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))));
     }
@@ -882,7 +774,6 @@
         mTestableLooper.processAllMessages();
 
         verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(null /* expectedUidUpdates */, 0 /* expectedUidUpdates */);
         verifyCarrierPrivilegesChangedUpdates(List.of());
     }
 
@@ -938,7 +829,6 @@
 
         // 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),
@@ -950,7 +840,6 @@
 
         // 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)));
     }
@@ -966,7 +855,6 @@
 
         // 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),
@@ -979,7 +867,6 @@
 
         // 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)));
     }
@@ -1137,11 +1024,93 @@
         verify(mPackageManager).queryIntentServices(any(), anyInt());
     }
 
-    private void sendCarrierConfigChangedIntent(int subId, int phoneId) {
-        mContext.sendBroadcast(
-                new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
-                        .putExtra(EXTRA_SUBSCRIPTION_INDEX, subId)
-                        .putExtra(EXTRA_SLOT_INDEX, phoneId));
+    @Test
+    public void testSetCarrierServiceOverride_noCarrierPrivileges() throws Exception {
+        // Setup one package, without a matching cert to grant carrier privileges
+        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1));
+        ResolveInfo carrierService = new ResolveInfoBuilder().setService(PACKAGE_1).build();
+
+        doReturn(List.of(carrierService))
+                .when(mPackageManager)
+                .queryIntentServices(any(), anyInt());
+        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
+
+        // Set override, and verify the carrier service package was not set due to a lack of a
+        // matching cert.
+        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
+        mCarrierPrivilegesTracker.setTestOverrideCarrierServicePackage(PACKAGE_1);
+        mTestableLooper.processAllMessages();
+
+        assertNull(mCarrierPrivilegesTracker.getCarrierServicePackageName());
+        assertEquals(Process.INVALID_UID, mCarrierPrivilegesTracker.getCarrierServicePackageUid());
+    }
+
+    @Test
+    public void testSetCarrierServiceOverride_withCarrierConfigCarrierPrivileges()
+            throws Exception {
+        // Setup two packages with matching carrier config certificates
+        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
+        setupInstalledPackages(
+                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
+                new PackageCertInfo(PACKAGE_2, CERT_1, USER_1, UID_2));
+        ResolveInfo service1 = new ResolveInfoBuilder().setService(PACKAGE_1).build();
+        ResolveInfo service2 = new ResolveInfoBuilder().setService(PACKAGE_2).build();
+
+        doReturn(List.of(service1, service2))
+                .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);
+
+        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
+
+        // Set override, and verify the carrier service package was truly set.
+        mCarrierPrivilegesTracker.setTestOverrideCarrierServicePackage(PACKAGE_1);
+        mTestableLooper.processAllMessages();
+
+        assertEquals(PACKAGE_1, mCarrierPrivilegesTracker.getCarrierServicePackageName());
+        assertEquals(UID_1, mCarrierPrivilegesTracker.getCarrierServicePackageUid());
+
+        // Set other package as override, and verify the carrier service package was truly set.
+        mCarrierPrivilegesTracker.setTestOverrideCarrierServicePackage(PACKAGE_2);
+        mTestableLooper.processAllMessages();
+
+        assertEquals(PACKAGE_2, mCarrierPrivilegesTracker.getCarrierServicePackageName());
+        assertEquals(UID_2, mCarrierPrivilegesTracker.getCarrierServicePackageUid());
+
+        // Clear override, and verify that everything went back to null.
+        mCarrierPrivilegesTracker.setTestOverrideCarrierServicePackage(null);
+        mTestableLooper.processAllMessages();
+
+        assertNull(mCarrierPrivilegesTracker.getCarrierServicePackageName());
+        assertEquals(Process.INVALID_UID, mCarrierPrivilegesTracker.getCarrierServicePackageUid());
+    }
+
+    @Test
+    public void testSetCarrierServiceOverride_invalidPackage() throws Exception {
+        // Setup one package, without a matching cert to grant carrier privileges
+        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
+        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1));
+        ResolveInfo carrierService = new ResolveInfoBuilder().setService(PACKAGE_1).build();
+
+        doReturn(List.of(carrierService))
+                .when(mPackageManager)
+                .queryIntentServices(any(), anyInt());
+        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
+
+        // Set override, and expect that an invalid package name would not be selected as the
+        // carrier config service.
+        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
+        mCarrierPrivilegesTracker.setTestOverrideCarrierServicePackage("invalid.package");
+        mTestableLooper.processAllMessages();
+
+        assertNull(mCarrierPrivilegesTracker.getCarrierServicePackageName());
+        assertEquals(Process.INVALID_UID, mCarrierPrivilegesTracker.getCarrierServicePackageUid());
+    }
+
+    private void sendCarrierConfigChanged(int subId, int phoneId) {
+        mCarrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
     }
 
     private void sendSimCardStateChangedIntent(int phoneId, int simState) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
index 07cf0b9..fadbff1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
@@ -28,7 +29,6 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -43,9 +43,11 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Map;
+import java.util.concurrent.Executor;
 
 /**
  * Unit tests for {@link com.android.internal.telephony.CarrierServiceStateTracker}.
@@ -57,6 +59,7 @@
 
     private CarrierServiceStateTracker mSpyCarrierSST;
     private CarrierServiceStateTracker mCarrierSST;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private static final int SUB_ID = 1;
 
@@ -68,10 +71,18 @@
         MockitoAnnotations.initMocks(this);
         logd(LOG_TAG + "Setup!");
         super.setUp(getClass().getSimpleName());
+        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
         mBundle = mContextFixture.getCarrierConfigBundle();
         when(mPhone.getSubId()).thenReturn(SUB_ID);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
 
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mCarrierSST = new CarrierServiceStateTracker(mPhone, mSST);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
         mSpyCarrierSST = spy(mCarrierSST);
 
         mNotificationManager = (NotificationManager) mContext.getSystemService(
@@ -140,8 +151,8 @@
     @SmallTest
     public void testSendPrefNetworkNotification() {
         logd(LOG_TAG + ":testSendPrefNetworkNotification()");
-        Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mContext.sendBroadcast(intent);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */, SUB_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         Map<Integer, CarrierServiceStateTracker.NotificationType> notificationTypeMap =
@@ -190,8 +201,8 @@
     @SmallTest
     public void testSendEmergencyNetworkNotification() {
         logd(LOG_TAG + ":testSendEmergencyNetworkNotification()");
-        Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mContext.sendBroadcast(intent);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */, SUB_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         Map<Integer, CarrierServiceStateTracker.NotificationType> notificationTypeMap =
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
index e070b06..4dfadd2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
@@ -61,6 +61,7 @@
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.Executor;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -70,6 +71,8 @@
 
     private CarrierSignalAgent mCarrierSignalAgentUT;
     private PersistableBundle mBundle;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+
     private static final String PCO_RECEIVER = "pak/PCO_RECEIVER";
     private static final String DC_ERROR_RECEIVER = "pak/DC_ERROR_RECEIVER";
     private static final String LEGACY_RECEIVER = "old.pkg/LEGACY_RECEIVER";
@@ -103,6 +106,7 @@
         FAKE_DEFAULT_NETWORK_INTENT.putExtra(
                 TelephonyManager.EXTRA_DEFAULT_NETWORK_AVAILABLE, true);
     }
+    private static final int PHONE_ID = 0;
 
     // Mocked classes
     ResolveInfo mResolveInfo;
@@ -112,8 +116,17 @@
         logd("CarrierSignalAgentTest +Setup!");
         super.setUp(getClass().getSimpleName());
         mResolveInfo = mock(ResolveInfo.class);
+        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
         mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
+
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mCarrierSignalAgentUT = new CarrierSignalAgent(mPhone);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
 
         ComponentName legacyReceiverComponent = ComponentName.unflattenFromString(LEGACY_RECEIVER);
         ApplicationInfo fakeLegacyApplicationInfo = new ApplicationInfo();
@@ -159,9 +172,10 @@
         verify(mContext, times(count)).sendBroadcast(mCaptorIntent.capture());
 
         // Trigger carrier config reloading
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
-        count++;
 
         // Verify no broadcast has been sent due to no manifest receivers
         mCarrierSignalAgentUT.notifyCarrierSignalReceivers(intent);
@@ -208,14 +222,16 @@
                 });
 
         // Trigger carrier config reloading
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         // Verify broadcast has been sent to two different registered manifest receivers
         doReturn(new ArrayList<>(Arrays.asList(mResolveInfo)))
                 .when(mPackageManager).queryBroadcastReceivers((Intent) any(), anyInt());
 
-        int broadcastCount = 1;
+        int broadcastCount = 0;
         {
             mCarrierSignalAgentUT.notifyCarrierSignalReceivers(new Intent(FAKE_PCO_INTENT));
             broadcastCount++;
@@ -325,9 +341,10 @@
         verify(mContext, times(count)).sendBroadcast(mCaptorIntent.capture());
 
         // Trigger carrier config reloading
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
-        count++;
 
         // Verify broadcast has been sent to registered components
         mCarrierSignalAgentUT.notifyCarrierSignalReceivers(intent);
@@ -362,9 +379,10 @@
                 argThat(o -> Objects.equals(o.getAction(), ACTION_CARRIER_SIGNAL_PCO_VALUE)),
                 anyInt());
 
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
-        count++;
 
         // Wake signal for PAK_PCO_RECEIVER
         mCarrierSignalAgentUT.notifyCarrierSignalReceivers(
@@ -417,7 +435,9 @@
                 CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
                 new String[]{ PCO_RECEIVER + ":" + ACTION_CARRIER_SIGNAL_PCO_VALUE + ","
                         + ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED });
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         // verify no reset action on initial config load
         verify(mCarrierActionAgent, times(0)).sendMessageAtTime(any(Message.class), anyLong());
@@ -427,7 +447,9 @@
                 CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
                 new String[]{ PCO_RECEIVER + ":" + ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED
                         + "," + ACTION_CARRIER_SIGNAL_PCO_VALUE});
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         // verify no reset action for the same config (different order)
         verify(mCarrierActionAgent, times(0)).sendMessageAtTime(any(Message.class), anyLong());
@@ -437,7 +459,9 @@
                 CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
                 new String[]{ DC_ERROR_RECEIVER + ":" + ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED
                         + "," + ACTION_CARRIER_SIGNAL_PCO_VALUE});
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
         // verify there is no reset action
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java
new file mode 100644
index 0000000..40be490
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2023 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.CellBroadcastConfigTracker.mergeRangesAsNeeded;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.AsyncResult;
+import android.os.Message;
+import android.telephony.CellBroadcastIdRange;
+import android.telephony.SmsCbMessage;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+
+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.Arrays;
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public final class CellBroadcastConfigTrackerTest extends TelephonyTest {
+
+    private CommandsInterface mSpyCi;
+    private CellBroadcastConfigTracker mTracker;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        mSpyCi = spy(mSimulatedCommands);
+        mPhone = new GsmCdmaPhone(mContext, mSpyCi, mNotifier, true, 0,
+            PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
+        mTracker = CellBroadcastConfigTracker.make(mPhone, mPhone, true);
+        mPhone.mCellBroadcastConfigTracker = mTracker;
+        processAllMessages();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mPhone.removeCallbacksAndMessages(null);
+        mPhone = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testSetCellBroadcastIdRangesSuccess() throws Exception {
+        final int[][] channelValues = {
+            {0, 999}, {1000, 1003}, {1004, 0x0FFF}, {0x1000, 0x10FF}, {0x1100, 0x112F},
+            {0x1130, 0x1900}, {0x1901, 0x9FFF}, {0xA000, 0xFFFE}, {0xFFFF, 0xFFFF}};
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+        for (int i = 0; i < channelValues.length; i++) {
+            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    SmsCbMessage.MESSAGE_FORMAT_3GPP, i > 0 ? true : false));
+        }
+
+        List<SmsBroadcastConfigInfo> gsmConfigs = new ArrayList<>();
+        gsmConfigs.add(new SmsBroadcastConfigInfo(0, 999, 0, 255, false));
+        gsmConfigs.add(new SmsBroadcastConfigInfo(1000, 0xFFFF, 0, 255, true));
+
+        ArgumentCaptor<SmsBroadcastConfigInfo[]> gsmCaptor = ArgumentCaptor.forClass(
+                SmsBroadcastConfigInfo[].class);
+        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);
+
+        mockCommandInterface();
+
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
+        List<SmsBroadcastConfigInfo> gsmArgs = Arrays.asList(
+                (SmsBroadcastConfigInfo[]) gsmCaptor.getValue());
+        assertEquals(gsmConfigs, gsmArgs);
+
+        Message msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastActivation(eq(true), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, never()).setCdmaBroadcastConfig(any(), any());
+        verify(mSpyCi, never()).setCdmaBroadcastActivation(anyBoolean(), any());
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));
+
+        //Verify to set cdma config and activate, but no more for gsm as no change
+        for (int i = 0; i < channelValues.length; i++) {
+            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    SmsCbMessage.MESSAGE_FORMAT_3GPP2, i > 0 ? true : false));
+        }
+        List<CdmaSmsBroadcastConfigInfo> cdmaConfigs = new ArrayList<>();
+        cdmaConfigs.add(new CdmaSmsBroadcastConfigInfo(0, 999, 1, false));
+        cdmaConfigs.add(new CdmaSmsBroadcastConfigInfo(1000, 0xFFFF, 1, true));
+        ArgumentCaptor<CdmaSmsBroadcastConfigInfo[]> cdmaCaptor = ArgumentCaptor.forClass(
+                CdmaSmsBroadcastConfigInfo[].class);
+
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastConfig(any(), any());
+        verify(mSpyCi, times(1)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
+        List<CdmaSmsBroadcastConfigInfo> cdmaArgs = Arrays.asList(
+                (CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue());
+        assertEquals(cdmaConfigs, cdmaArgs);
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastActivation(anyBoolean(), any());
+        verify(mSpyCi, times(1)).setCdmaBroadcastActivation(eq(true), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));
+
+        // Verify not to set cdma or gsm config as the config is not changed
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setCdmaBroadcastConfig(any(), any());
+        verify(mSpyCi, times(1)).setCdmaBroadcastActivation(anyBoolean(), any());
+        verify(mSpyCi, times(1)).setGsmBroadcastConfig(any(), any());
+        verify(mSpyCi, times(1)).setGsmBroadcastActivation(anyBoolean(), any());
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));
+
+        // Verify to reset ranges with empty ranges list
+        mPhone.setCellBroadcastIdRanges(new ArrayList<>(), r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
+        assertEquals(0, ((SmsBroadcastConfigInfo[]) gsmCaptor.getValue()).length);
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Verify to deavtivate gsm broadcast on empty ranges
+        verify(mSpyCi, times(1)).setGsmBroadcastActivation(eq(false), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
+        assertEquals(0, ((CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue()).length);
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Verify to deavtivate cdma broadcast on empty ranges
+        verify(mSpyCi, times(1)).setCdmaBroadcastActivation(eq(false), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertTrue(mPhone.getCellBroadcastIdRanges().isEmpty());
+
+        //Verify to set gsm and cdma config then activate again
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+
+        processAllMessages();
+
+        verify(mSpyCi, times(3)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
+        gsmArgs = Arrays.asList((SmsBroadcastConfigInfo[]) gsmCaptor.getValue());
+        assertEquals(gsmConfigs, gsmArgs);
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setGsmBroadcastActivation(eq(true), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(3)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
+        cdmaArgs = Arrays.asList((CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue());
+        assertEquals(cdmaConfigs, cdmaArgs);
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setCdmaBroadcastActivation(eq(true), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));
+    }
+
+    @Test
+    public void testSetCellBroadcastIdRangesFailure() throws Exception {
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+
+        // Verify to throw exception for invalid ranges
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, false));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mPhone.setCellBroadcastIdRanges(ranges, r -> {}));
+
+        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);
+        ranges.clear();
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP2, true));
+
+        mockCommandInterface();
+
+        // Verify the result on setGsmBroadcastConfig failure
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastConfig(any(), msgCaptor.capture());
+
+        Message msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg).exception = new RuntimeException();
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(0)).setGsmBroadcastActivation(anyBoolean(), any());
+        verify(mSpyCi, times(0)).setCdmaBroadcastConfig(any(), any());
+        verify(mSpyCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());
+        assertTrue(mPhone.getCellBroadcastIdRanges().isEmpty());
+
+        // Verify the result on setGsmBroadcastActivation failure
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setGsmBroadcastConfig(any(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setGsmBroadcastActivation(anyBoolean(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg).exception = new RuntimeException();
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(0)).setCdmaBroadcastConfig(any(), any());
+        verify(mSpyCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());
+        assertTrue(mPhone.getCellBroadcastIdRanges().isEmpty());
+
+        // Verify the result on setCdmaBroadcastConfig failure
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG == r));
+        processAllMessages();
+
+        verify(mSpyCi, times(3)).setGsmBroadcastConfig(any(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(2)).setGsmBroadcastActivation(anyBoolean(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setCdmaBroadcastConfig(any(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg).exception = new RuntimeException();
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());
+
+        List<CellBroadcastIdRange> ranges3gpp = new ArrayList<>();
+        ranges3gpp.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), ranges3gpp);
+
+        // Verify the result on setCdmaBroadcastActivation failure
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION == r));
+        processAllMessages();
+
+        // Verify no more calls as there is no change of ranges for 3gpp
+        verify(mSpyCi, times(3)).setGsmBroadcastConfig(any(), any());
+        verify(mSpyCi, times(2)).setGsmBroadcastActivation(anyBoolean(), any());
+        verify(mSpyCi, times(2)).setCdmaBroadcastConfig(any(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg);
+        msg.sendToTarget();
+        processAllMessages();
+
+        verify(mSpyCi, times(1)).setCdmaBroadcastActivation(anyBoolean(), msgCaptor.capture());
+
+        msg = msgCaptor.getValue();
+        assertNotNull(msg);
+        AsyncResult.forMessage(msg).exception = new RuntimeException();
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), ranges3gpp);
+    }
+
+    @Test
+    public void testClearCellBroadcastConfigOnRadioOff() {
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
+
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+        processAllMessages();
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), ranges);
+
+        mPhone.sendEmptyMessage(Phone.EVENT_RADIO_OFF_OR_NOT_AVAILABLE);
+        processAllMessages();
+
+        // Verify the config is reset
+        assertTrue(mPhone.getCellBroadcastIdRanges().isEmpty());
+    }
+
+    @Test
+    public void testClearCellBroadcastConfigOnSubscriptionChanged() {
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
+
+        mPhone.setCellBroadcastIdRanges(ranges, r -> assertTrue(
+                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
+        processAllMessages();
+
+        assertEquals(mPhone.getCellBroadcastIdRanges(), ranges);
+
+        mTracker.mSubChangedListener.onSubscriptionsChanged();
+        processAllMessages();
+
+        // Verify the config is not reset when the sub id is not changed
+        assertEquals(mPhone.getCellBroadcastIdRanges(), ranges);
+
+        mTracker.mSubId = mTracker.mSubId % SubscriptionManager.DEFAULT_SUBSCRIPTION_ID + 1;
+
+        mTracker.mSubChangedListener.onSubscriptionsChanged();
+        processAllMessages();
+
+        // Verify the config is reset when the sub id is changed
+        assertTrue(mPhone.getCellBroadcastIdRanges().isEmpty());
+    }
+
+    @Test
+    public void testMergeCellBroadcastIdRangesAsNeeded() {
+        final int[][] channelValues = {
+                {0, 999}, {1000, 1003}, {1004, 0x0FFF}, {0x1000, 0x10FF}, {0x1100, 0x112F},
+                {0x1130, 0x1900}, {0x1901, 0x9FFF}, {0xA000, 0xFFFE}, {0xFFFF, 0xFFFF}};
+        final int[] typeValues = {
+                SmsCbMessage.MESSAGE_FORMAT_3GPP, SmsCbMessage.MESSAGE_FORMAT_3GPP2};
+        final boolean[] enabledValues = {true, false};
+
+        List<CellBroadcastIdRange> ranges = new ArrayList<>();
+        for (int i = 0; i < channelValues.length; i++) {
+            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    typeValues[0], enabledValues[0]));
+        }
+
+        ranges = mergeRangesAsNeeded(ranges);
+
+        assertEquals(1, ranges.size());
+        assertEquals(ranges.get(0).getStartId(), channelValues[0][0]);
+        assertEquals(ranges.get(0).getEndId(), channelValues[channelValues.length - 1][0]);
+
+        // Verify not to merge the ranges with different types.
+        ranges.clear();
+        for (int i = 0; i < channelValues.length; i++) {
+            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    typeValues[0], enabledValues[0]));
+            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    typeValues[1], enabledValues[0]));
+        }
+
+        ranges = mergeRangesAsNeeded(ranges);
+
+        assertEquals(2, ranges.size());
+        assertEquals(ranges.get(0).getStartId(), channelValues[0][0]);
+        assertEquals(ranges.get(0).getEndId(), channelValues[channelValues.length - 1][0]);
+        assertEquals(ranges.get(1).getStartId(), channelValues[0][0]);
+        assertEquals(ranges.get(1).getEndId(), channelValues[channelValues.length - 1][0]);
+        assertTrue(ranges.get(0).getType() != ranges.get(1).getType());
+
+        // Verify to throw IllegalArgumentException if the same range is enabled and disabled
+        // in the range list.
+        final List<CellBroadcastIdRange> ranges2 = new ArrayList<>();
+        for (int i = 0; i < channelValues.length; i++) {
+            ranges2.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    typeValues[0], enabledValues[0]));
+            ranges2.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
+                    typeValues[0], enabledValues[1]));
+        }
+
+        assertThrows(IllegalArgumentException.class, () ->
+                mergeRangesAsNeeded(ranges2));
+    }
+
+    @Test
+    public void testMakeCellBroadcastConfigTracker() {
+        Phone phone = spy(mPhone);
+        CellBroadcastConfigTracker tracker = CellBroadcastConfigTracker.make(phone, phone, false);
+        processAllMessages();
+
+        verify(phone, never()).registerForRadioOffOrNotAvailable(any(), anyInt(), any());
+        verify(mSubscriptionManager, never()).addOnSubscriptionsChangedListener(
+                any(), eq(tracker.mSubChangedListener));
+
+        tracker.start();
+        processAllMessages();
+
+        verify(phone, times(1)).registerForRadioOffOrNotAvailable(any(), anyInt(), any());
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(), eq(tracker.mSubChangedListener));
+
+        tracker = CellBroadcastConfigTracker.make(phone, phone, true);
+        processAllMessages();
+
+        verify(phone, times(2)).registerForRadioOffOrNotAvailable(any(), anyInt(), any());
+        verify(mSubscriptionManager, times(1)).addOnSubscriptionsChangedListener(
+                any(), eq(tracker.mSubChangedListener));
+    }
+
+    private void mockCommandInterface() {
+        doNothing().when(mSpyCi).setGsmBroadcastConfig(any(), any());
+        doNothing().when(mSpyCi).setGsmBroadcastActivation(anyBoolean(), any());
+        doNothing().when(mSpyCi).setCdmaBroadcastConfig(any(), any());
+        doNothing().when(mSpyCi).setCdmaBroadcastActivation(anyBoolean(), any());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
index 47f545f..11d57bf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
-import android.hardware.radio.V1_6.NrSignalStrength;
+import android.hardware.radio.network.NrSignalStrength;
 import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -55,9 +55,11 @@
     private static final int CSICQI_TABLE_INDEX = 1;
     private static final ArrayList<Byte> CSICQI_REPORT =
             new ArrayList<>(Arrays.asList((byte) 3, (byte) 2, (byte) 1));
+    private static final byte[] CSICQI_REPORT_PRIMITIVE = new byte[] {(byte) 3, (byte) 2, (byte) 1};
     private static final int SSRSRP = -112;
     private static final int SSRSRQ = -13;
     private static final int SSSINR = 32;
+    private static final int TIMING_ADVANCE = 10;
 
     // Mocked classes
     ServiceState mSS;
@@ -83,7 +85,7 @@
     public void testGetMethod() {
         // GIVEN an instance of CellSignalStrengthNr
         CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN the get method should return correct value
         assertThat(css.getCsiRsrp()).isEqualTo(CSIRSRP);
@@ -95,20 +97,22 @@
         assertThat(css.getSsRsrq()).isEqualTo(SSRSRQ);
         assertThat(css.getSsSinr()).isEqualTo(SSSINR);
         assertThat(css.getDbm()).isEqualTo(SSRSRP);
+        assertThat(css.getTimingAdvanceMicros()).isEqualTo(TIMING_ADVANCE);
     }
 
     @Test
     public void testGetMethodWithHal() {
         // GIVEN an instance of NrSignalStrength with some positive values
         NrSignalStrength nrSignalStrength = new NrSignalStrength();
-        nrSignalStrength.base.csiRsrp = -CSIRSRP;
-        nrSignalStrength.base.csiRsrq = -CSIRSRQ;
-        nrSignalStrength.base.csiSinr = CSISINR;
+        nrSignalStrength.csiRsrp = -CSIRSRP;
+        nrSignalStrength.csiRsrq = -CSIRSRQ;
+        nrSignalStrength.csiSinr = CSISINR;
         nrSignalStrength.csiCqiTableIndex = CSICQI_TABLE_INDEX;
-        nrSignalStrength.csiCqiReport = CSICQI_REPORT;
-        nrSignalStrength.base.ssRsrp = -SSRSRP;
-        nrSignalStrength.base.ssRsrq = -SSRSRQ;
-        nrSignalStrength.base.ssSinr = SSSINR;
+        nrSignalStrength.csiCqiReport = CSICQI_REPORT_PRIMITIVE;
+        nrSignalStrength.ssRsrp = -SSRSRP;
+        nrSignalStrength.ssRsrq = -SSRSRQ;
+        nrSignalStrength.ssSinr = SSSINR;
+        nrSignalStrength.timingAdvance = TIMING_ADVANCE;
 
         // THEN the get method should return the correct value
         CellSignalStrengthNr css = RILUtils.convertHalNrSignalStrength(nrSignalStrength);
@@ -121,20 +125,22 @@
         assertThat(css.getSsRsrq()).isEqualTo(SSRSRQ);
         assertThat(css.getSsSinr()).isEqualTo(SSSINR);
         assertThat(css.getDbm()).isEqualTo(SSRSRP);
+        assertThat(css.getTimingAdvanceMicros()).isEqualTo(TIMING_ADVANCE);
     }
 
     @Test
     public void testUnavailableValueWithHal() {
         // GIVEN an instance of NrSignalStrength
         NrSignalStrength nrSignalStrength = new NrSignalStrength();
-        nrSignalStrength.base.csiRsrp = CellInfo.UNAVAILABLE;
-        nrSignalStrength.base.csiRsrq = CellInfo.UNAVAILABLE;
-        nrSignalStrength.base.csiSinr = CellInfo.UNAVAILABLE;
+        nrSignalStrength.csiRsrp = CellInfo.UNAVAILABLE;
+        nrSignalStrength.csiRsrq = CellInfo.UNAVAILABLE;
+        nrSignalStrength.csiSinr = CellInfo.UNAVAILABLE;
         nrSignalStrength.csiCqiTableIndex = CellInfo.UNAVAILABLE;
-        nrSignalStrength.csiCqiReport = new ArrayList<Byte>();
-        nrSignalStrength.base.ssRsrp = CellInfo.UNAVAILABLE;
-        nrSignalStrength.base.ssRsrq = CellInfo.UNAVAILABLE;
-        nrSignalStrength.base.ssSinr = CellInfo.UNAVAILABLE;
+        nrSignalStrength.csiCqiReport = new byte[]{};
+        nrSignalStrength.ssRsrp = CellInfo.UNAVAILABLE;
+        nrSignalStrength.ssRsrq = CellInfo.UNAVAILABLE;
+        nrSignalStrength.ssSinr = CellInfo.UNAVAILABLE;
+        nrSignalStrength.timingAdvance = CellInfo.UNAVAILABLE;
 
         // THEN the get method should return unavailable value
         CellSignalStrengthNr css = RILUtils.convertHalNrSignalStrength(nrSignalStrength);
@@ -147,15 +153,16 @@
         assertThat(css.getSsRsrq()).isEqualTo(CellInfo.UNAVAILABLE);
         assertThat(css.getSsSinr()).isEqualTo(CellInfo.UNAVAILABLE);
         assertThat(css.getDbm()).isEqualTo(CellInfo.UNAVAILABLE);
+        assertThat(css.getTimingAdvanceMicros()).isEqualTo(CellInfo.UNAVAILABLE);
     }
 
     @Test
     public void testEquals_sameParameters() {
         // GIVEN an instance of CellSignalStrengthNr and another object with the same parameters
         CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
         CellSignalStrengthNr anotherCss = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN this two objects are equivalent
         assertThat(css).isEqualTo(anotherCss);
@@ -166,10 +173,10 @@
         // GIVEN an instance of CellSignalStrengthNr and another object with some different
         // parameters
         CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
         CellSignalStrengthNr anotherCss = new CellSignalStrengthNr(ANOTHER_CSIRSRP,
                 ANOTHER_CSIRSRQ, CSISINR, CSICQI_TABLE_INDEX, CSICQI_REPORT,
-                SSRSRP, SSRSRQ, SSSINR);
+                SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN this two objects are different
         assertThat(css).isNotEqualTo(anotherCss);
@@ -179,7 +186,7 @@
     public void testAusLevel_validValue() {
         // GIVEN an instance of CellSignalStrengthNr with valid csirsrp
         CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN the asu level is in range [0, 97]
         assertThat(css.getAsuLevel()).isIn(Range.range(0, BoundType.CLOSED, 97, BoundType.CLOSED));
@@ -189,7 +196,7 @@
     public void testAsuLevel_invalidValue() {
         // GIVEN an instance of CellSignalStrengthNr with invalid csirsrp
         CellSignalStrengthNr css = new CellSignalStrengthNr(INVALID_CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, INVALID_SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, INVALID_SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN the asu level is unknown
         assertThat(css.getAsuLevel()).isEqualTo(CellSignalStrengthNr.UNKNOWN_ASU_LEVEL);
@@ -200,7 +207,7 @@
         for (int ssRsrp = -156; ssRsrp <= -31; ssRsrp++) {
             // GIVEN an instance of CellSignalStrengthNr with valid csirsrp
             CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                    CSICQI_TABLE_INDEX, CSICQI_REPORT, ssRsrp, SSRSRQ, SSSINR);
+                    CSICQI_TABLE_INDEX, CSICQI_REPORT, ssRsrp, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
             // THEN the signal level is valid
             assertThat(css.getLevel()).isIn(Range.range(
@@ -213,7 +220,7 @@
     public void testSignalLevel_invalidValue() {
         // GIVEN an instance of CellSignalStrengthNr with invalid csirsrp
         CellSignalStrengthNr css = new CellSignalStrengthNr(INVALID_CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // THEN the signal level is unknown
         assertThat(css.getLevel()).isEqualTo(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
@@ -223,7 +230,7 @@
     public void testParcel() {
         // GIVEN an instance of CellSignalStrengthNr
         CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR,
-                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR);
+                CSICQI_TABLE_INDEX, CSICQI_REPORT, SSRSRP, SSRSRQ, SSSINR, TIMING_ADVANCE);
 
         // WHEN write the object to parcel and create another object with that parcel
         Parcel parcel = Parcel.obtain();
@@ -241,6 +248,7 @@
         assertThat(anotherCss.getSsRsrp()).isEqualTo(SSRSRP);
         assertThat(anotherCss.getSsRsrq()).isEqualTo(SSRSRQ);
         assertThat(anotherCss.getSsSinr()).isEqualTo(SSSINR);
+        assertThat(anotherCss.getTimingAdvanceMicros()).isEqualTo(TIMING_ADVANCE);
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
old mode 100755
new mode 100644
index d1e643e..0bce5cb
--- a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
@@ -20,12 +20,16 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 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.when;
 
 import android.os.Handler;
 import android.os.Looper;
 
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -39,6 +43,9 @@
 
     // Mocked classes
     protected Call mCall;
+    protected EmergencyNumberTracker mEmergencyNumberTracker2;
+    protected Connection.PhoneFactoryProxy mPhoneFactoryProxy;
+    protected Connection mTestConnection;
 
     private class TestConnection extends Connection {
 
@@ -117,7 +124,15 @@
         super.setUp(getClass().getSimpleName());
         mCall = mock(Call.class);
         doReturn(mPhone).when(mCall).getPhone();
+        doReturn(mPhone).when(mCT).getPhone();
         replaceInstance(Handler.class, "mLooper", mCT, Looper.getMainLooper());
+
+        mEmergencyNumberTracker2 = mock(EmergencyNumberTracker.class);
+        doReturn(mEmergencyNumberTracker2).when(mPhone2).getEmergencyNumberTracker();
+
+        mTestConnection = new TestConnection(TEST_PHONE_TYPE);
+        mPhoneFactoryProxy = mock(Connection.PhoneFactoryProxy.class);
+        mTestConnection.setPhoneFactoryProxy(mPhoneFactoryProxy);
     }
 
     @After
@@ -156,5 +171,24 @@
         assertTrue(connection.hasKnownUserIntentEmergency());
     }
 
+    @Test
+    public void testSetEmergencyCallInfo() {
+        //Replicate Dual-SIM:
+        Phone [] phones = {mPhone, mPhone2};
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(phones);
+        doReturn(1).when(mPhone).getPhoneId();
+        doReturn(2).when(mPhone2).getPhoneId();
+
+        //Replicate behavior when a number is an emergency number
+        // on the secondary SIM but not on the default SIM:
+        when(mPhone.getEmergencyNumberTracker().getEmergencyNumber(any())).thenReturn(null);
+        when(mEmergencyNumberTracker2.getEmergencyNumber(any()))
+                .thenReturn(getTestEmergencyNumber());
+
+        //Ensure the connection is considered as an emergency call:
+        mTestConnection.setEmergencyCallInfo(mCT);
+        assertTrue(mTestConnection.isEmergencyCall());
+    }
+
     // TODO Verify more methods in Connection
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 82ade73..ea19b62 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -176,6 +176,11 @@
                     mKeyValuePairs.put(request, (String)args.get("value"));
                     mNumKeyValuePairs++;
                     break;
+                case Settings.CALL_METHOD_PUT_CONFIG:
+                    logd("PUT_config called");
+                    logd("adding config flag: " + request + "-" + args.getString("value"));
+                    mFlags.put(request, args.getString("value"));
+                    break;
                 case Settings.CALL_METHOD_LIST_CONFIG:
                     logd("LIST_config: " + mFlags);
                     Bundle result = new Bundle();
@@ -351,6 +356,8 @@
                 return Context.POWER_SERVICE;
             } else if (serviceClass == EuiccManager.class) {
                 return Context.EUICC_SERVICE;
+            } else if (serviceClass == AlarmManager.class) {
+                return Context.ALARM_SERVICE;
             }
             return super.getSystemServiceName(serviceClass);
         }
@@ -773,6 +780,7 @@
 
         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
+        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
         doAnswer(invocation -> mNetworkId++).when(mNetwork).getNetId();
         doReturn(mNetwork).when(mConnectivityManager).registerNetworkAgent(
                 any(), any(), any(), any(), any(), any(), anyInt());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DataSpecificRegistrationInfoTest.java b/tests/telephonytests/src/com/android/internal/telephony/DataSpecificRegistrationInfoTest.java
new file mode 100644
index 0000000..50390cc
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/DataSpecificRegistrationInfoTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import android.os.Parcel;
+import android.telephony.DataSpecificRegistrationInfo;
+import android.telephony.LteVopsSupportInfo;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/** Unit tests for {@link DataSpecificRegistrationInfo}. */
+public class DataSpecificRegistrationInfoTest {
+    @Test
+    @SmallTest
+    public void testBuilder() {
+        DataSpecificRegistrationInfo dsri =
+                new DataSpecificRegistrationInfo.Builder(3)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .build();
+
+        assertEquals(3, dsri.maxDataCalls);
+        assertEquals(false, dsri.isDcNrRestricted);
+        assertEquals(true, dsri.isNrAvailable);
+        assertEquals(true, dsri.isEnDcAvailable);
+        assertNull(dsri.getVopsSupportInfo());
+
+        LteVopsSupportInfo vopsInfo = new LteVopsSupportInfo(
+                LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED);
+        dsri = new DataSpecificRegistrationInfo.Builder(5)
+                .setDcNrRestricted(true)
+                .setVopsSupportInfo(vopsInfo)
+                .build();
+
+        assertEquals(5, dsri.maxDataCalls);
+        assertEquals(true, dsri.isDcNrRestricted);
+        assertEquals(false, dsri.isNrAvailable);
+        assertEquals(false, dsri.isEnDcAvailable);
+        assertEquals(vopsInfo, dsri.getVopsSupportInfo());
+    }
+
+    @Test
+    @SmallTest
+    public void testParcel() {
+        DataSpecificRegistrationInfo dsri =
+                new DataSpecificRegistrationInfo.Builder(3)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setLteAttachResultType(DataSpecificRegistrationInfo.LTE_ATTACH_TYPE_COMBINED)
+                .setLteAttachExtraInfo(DataSpecificRegistrationInfo.LTE_ATTACH_EXTRA_INFO_SMS_ONLY)
+                .build();
+
+        Parcel p = Parcel.obtain();
+        dsri.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        DataSpecificRegistrationInfo newDsri =
+                DataSpecificRegistrationInfo.CREATOR.createFromParcel(p);
+        assertEquals(dsri, newDsri);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index 6a05d4f..2f4182a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -16,6 +16,7 @@
 package com.android.internal.telephony;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
@@ -30,8 +31,11 @@
 import android.telephony.PreciseDisconnectCause;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.telephony.imsphone.ImsPhoneCall;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -53,6 +57,9 @@
     GsmCdmaCall mForeGroundCall;
     GsmCdmaCall mBackGroundCall;
     GsmCdmaCall mRingingCall;
+    ImsPhoneCall mImsForeGroundCall;
+    ImsPhoneCall mImsBackGroundCall;
+    ImsPhoneCall mImsRingingCall;
 
     @Before
     public void setUp() throws Exception {
@@ -62,6 +69,9 @@
         mForeGroundCall = mock(GsmCdmaCall.class);
         mBackGroundCall = mock(GsmCdmaCall.class);
         mRingingCall = mock(GsmCdmaCall.class);
+        mImsForeGroundCall = mock(ImsPhoneCall.class);
+        mImsBackGroundCall = mock(ImsPhoneCall.class);
+        mImsRingingCall = mock(ImsPhoneCall.class);
         mDefaultPhoneNotifierUT = new DefaultPhoneNotifier(mContext);
     }
 
@@ -168,61 +178,144 @@
 
     @Test @SmallTest
     public void testNotifyPreciseCallState() throws Exception {
-
         //mock forground/background/ringing call and call state
         doReturn(Call.State.IDLE).when(mForeGroundCall).getState();
         doReturn(Call.State.IDLE).when(mBackGroundCall).getState();
         doReturn(Call.State.IDLE).when(mRingingCall).getState();
 
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
         verify(mTelephonyRegistryManager, times(0)).notifyPreciseCallState(
-                anyInt(), anyInt(), anyInt(), anyInt(), anyInt());
+                anyInt(), anyInt(), any(), any(), any(), any());
 
         doReturn(mForeGroundCall).when(mPhone).getForegroundCall();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
         verify(mTelephonyRegistryManager, times(0)).notifyPreciseCallState(
-                anyInt(), anyInt(), anyInt(), anyInt(), anyInt());
+                anyInt(), anyInt(), any(), any(), any(), any());
 
         doReturn(mBackGroundCall).when(mPhone).getBackgroundCall();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
         verify(mTelephonyRegistryManager, times(0)).notifyPreciseCallState(
-                anyInt(), anyInt(), anyInt(), anyInt(), anyInt());
+                anyInt(), anyInt(), any(), any(), any(), any());
 
         doReturn(mRingingCall).when(mPhone).getRingingCall();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
-        verify(mTelephonyRegistryManager, times(1)).notifyPreciseCallState(
-                mPhone.getPhoneId(),
-                mPhone.getSubId(),
-                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                PreciseCallState.PRECISE_CALL_STATE_IDLE);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
+        ArgumentCaptor<int[]> captor = ArgumentCaptor.forClass(int[].class);
+        int phoneId = mPhone.getPhoneId();
+        int subId = mPhone.getSubId();
+        verify(mTelephonyRegistryManager).notifyPreciseCallState(
+                eq(phoneId), eq(subId), captor.capture(), eq(null), eq(null), eq(null));
+        final int[] callStates = captor.getValue();
+        assertEquals(3, callStates.length);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates[/*ringing call*/ 0]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates[/*foreground call*/ 1]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates[/*background call*/ 2]);
 
         doReturn(Call.State.ACTIVE).when(mForeGroundCall).getState();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
-        verify(mTelephonyRegistryManager, times(1)).notifyPreciseCallState(
-                mPhone.getPhoneId(),
-                mPhone.getSubId(),
-                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
-                PreciseCallState.PRECISE_CALL_STATE_IDLE);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
+        ArgumentCaptor<int[]> captor1 = ArgumentCaptor.forClass(int[].class);
+        phoneId = mPhone.getPhoneId();
+        subId = mPhone.getSubId();
+        verify(mTelephonyRegistryManager, times(2)).notifyPreciseCallState(
+                eq(phoneId), eq(subId), captor1.capture(), eq(null), eq(null), eq(null));
+        final int[] callStates1 = captor1.getValue();
+        assertEquals(3, callStates1.length);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates1[/*ringing call*/ 0]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+                callStates1[/*foreground call*/ 1]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates1[/*background call*/ 2]);
 
         doReturn(Call.State.HOLDING).when(mBackGroundCall).getState();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
-        verify(mTelephonyRegistryManager, times(1)).notifyPreciseCallState(
-                mPhone.getPhoneId(),
-                mPhone.getSubId(),
-                PreciseCallState.PRECISE_CALL_STATE_IDLE,
-                PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
-                PreciseCallState.PRECISE_CALL_STATE_HOLDING);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
+        ArgumentCaptor<int[]> captor2 = ArgumentCaptor.forClass(int[].class);
+        verify(mTelephonyRegistryManager, times(3)).notifyPreciseCallState(
+                eq(phoneId), eq(subId), captor2.capture(), eq(null), eq(null), eq(null));
+        final int[] callStates2 = captor2.getValue();
+        assertEquals(3, callStates2.length);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates2[/*ringing call*/ 0]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+                callStates2[/*foreground call*/ 1]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+                callStates2[/*background call*/ 2]);
 
         doReturn(Call.State.ALERTING).when(mRingingCall).getState();
-        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone);
+        mDefaultPhoneNotifierUT.notifyPreciseCallState(mPhone, null, null, null);
+        ArgumentCaptor<int[]> captor3 = ArgumentCaptor.forClass(int[].class);
+        verify(mTelephonyRegistryManager, times(4)).notifyPreciseCallState(
+                eq(phoneId), eq(subId), captor3.capture(), eq(null), eq(null), eq(null));
+        final int[] callStates3 = captor3.getValue();
+        assertEquals(3, callStates3.length);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+                callStates3[/*ringing call*/ 0]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+                callStates3[/*foreground call*/ 1]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+                callStates3[/*background call*/ 2]);
+    }
+
+    @Test
+    public void testNotifyPreciseCallStateImsCallInfo() throws Exception {
+        //mock forground/background/ringing call and call state
+        doReturn(Call.State.ACTIVE).when(mImsForeGroundCall).getState();
+        doReturn(Call.State.HOLDING).when(mImsBackGroundCall).getState();
+        doReturn(Call.State.IDLE).when(mImsRingingCall).getState();
+
+        doReturn(mImsForeGroundCall).when(mImsPhone).getForegroundCall();
+        doReturn(mImsBackGroundCall).when(mImsPhone).getBackgroundCall();
+        doReturn(mImsRingingCall).when(mImsPhone).getRingingCall();
+
+        String[] imsCallIds = {null, "1", "2"};
+        int[] imsCallServiceTypes = {ImsCallProfile.SERVICE_TYPE_NONE,
+                ImsCallProfile.SERVICE_TYPE_NORMAL, ImsCallProfile.SERVICE_TYPE_NORMAL};
+        int[] imsCallTypes = {ImsCallProfile.CALL_TYPE_NONE,
+                ImsCallProfile.CALL_TYPE_VOICE, ImsCallProfile.CALL_TYPE_VT};
+
+        mDefaultPhoneNotifierUT
+                .notifyPreciseCallState(mImsPhone, imsCallIds, imsCallServiceTypes, imsCallTypes);
+        ArgumentCaptor<int[]> callStateCaptor = ArgumentCaptor.forClass(int[].class);
+        ArgumentCaptor<String[]> callIdCaptor = ArgumentCaptor.forClass(String[].class);
+        ArgumentCaptor<int[]> callServiceTypeCaptor = ArgumentCaptor.forClass(int[].class);
+        ArgumentCaptor<int[]> callTypeCaptor = ArgumentCaptor.forClass(int[].class);
+        int phoneId = mImsPhone.getPhoneId();
+        int subId = mImsPhone.getSubId();
         verify(mTelephonyRegistryManager, times(1)).notifyPreciseCallState(
-                mPhone.getPhoneId(),
-                mPhone.getSubId(),
-                PreciseCallState.PRECISE_CALL_STATE_ALERTING,
-                PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
-                PreciseCallState.PRECISE_CALL_STATE_HOLDING);
+                eq(phoneId), eq(subId), callStateCaptor.capture(), callIdCaptor.capture(),
+                callServiceTypeCaptor.capture(), callTypeCaptor.capture());
+        final int[] callStates = callStateCaptor.getValue();
+        final String[] callIds = callIdCaptor.getValue();
+        final int[] callServiceTypes = callServiceTypeCaptor.getValue();
+        final int[] callTypes = callTypeCaptor.getValue();
+        assertEquals(3, callStates.length);
+        assertEquals(3, callIds.length);
+        assertEquals(3, callServiceTypes.length);
+        assertEquals(3, callServiceTypes.length);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_IDLE,
+                callStates[/*ringing call*/ 0]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+                callStates[/*foreground call*/ 1]);
+        assertEquals(PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+                callStates[/*background call*/ 2]);
+
+        assertEquals("1", callIds[/*foreground call*/ 1]);
+        assertEquals("2", callIds[/*background call*/ 2]);
+        assertEquals(null, callIds[/*ringing call*/ 0]);
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NORMAL,
+                callServiceTypes[/*foreground call*/ 1]);
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NORMAL,
+                callServiceTypes[/*background call*/ 2]);
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NONE,
+                callServiceTypes[/*ringing call*/ 0]);
+        assertEquals(ImsCallProfile.CALL_TYPE_VOICE,
+                callTypes[/*foreground call*/ 1]);
+        assertEquals(ImsCallProfile.CALL_TYPE_VT,
+                callTypes[/*background call*/ 2]);
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NONE,
+                callServiceTypes[/*ringing call*/ 0]);
     }
 
     @Test @SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
index fa00362..f729b80 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
@@ -18,13 +18,12 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.content.Intent;
 import android.os.AsyncResult;
 import android.os.HandlerThread;
 import android.os.PersistableBundle;
@@ -36,6 +35,7 @@
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
@@ -46,9 +46,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
+import org.mockito.ArgumentCaptor;
 
 import java.util.Collections;
+import java.util.concurrent.Executor;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -65,6 +66,7 @@
     private ServiceStateTrackerTestHandler mSstHandler;
     private SignalStrengthController mSsc;
     private PersistableBundle mBundle;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private class ServiceStateTrackerTestHandler extends HandlerThread {
         private ServiceStateTrackerTestHandler(String name) {
@@ -79,7 +81,16 @@
             doReturn(NUMERIC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(PHONE_ID));
             doReturn(NETWORK).when(mTelephonyManager).getSimOperatorNameForPhone(eq(PHONE_ID));
 
+            // Capture listener registered for ServiceStateTracker to emulate the carrier config
+            // change notification used later. In this test, it's the second one. The first one
+            // comes from RatRatcheter.
+            ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener>
+                    listenerArgumentCaptor = ArgumentCaptor.forClass(
+                    CarrierConfigManager.CarrierConfigChangeListener.class);
             mSst = new ServiceStateTracker(mPhone, mSimulatedCommands);
+            verify(mCarrierConfigManager, atLeast(2)).registerCarrierConfigChangeListener(any(),
+                    listenerArgumentCaptor.capture());
+            mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(1);
             doReturn(mSst).when(mPhone).getServiceStateTracker();
             setReady(true);
         }
@@ -90,6 +101,8 @@
         logd("DisplayInfoControllerTest setup!");
         super.setUp(getClass().getSimpleName());
 
+        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
+        mBundle = mContextFixture.getCarrierConfigBundle();
         mSstHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
         mSstHandler.start();
         waitUntilReady();
@@ -104,18 +117,14 @@
         mSstHandler.join();
         mSstHandler = null;
         mBundle = null;
+        mCarrierConfigChangeListener = null;
         super.tearDown();
     }
 
     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);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID, TelephonyManager.UNKNOWN_CARRIER_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID);
         waitForLastHandlerAction(mSstHandler.getThreadHandler());
     }
 
@@ -172,7 +181,6 @@
     public void testIsRoamingOverride_NonRoamingOperator() {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
 
-        mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putStringArray(
                 CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, new String[] {NUMERIC});
         sendCarrierConfigUpdate();
@@ -194,7 +202,6 @@
     public void testIsRoamingOverride_ForceHomeNetwork() {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
 
-        mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL, true);
         sendCarrierConfigUpdate();
 
@@ -215,7 +222,6 @@
     public void testIsRoamingOverride_RoamingOperator() {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
 
-        mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putStringArray(
                 CarrierConfigManager.KEY_ROAMING_OPERATOR_STRING_ARRAY, new String[] {"60101"});
         sendCarrierConfigUpdate();
@@ -237,7 +243,6 @@
     public void testIsRoamingOverride_NonRoamingGsmOperator() {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
 
-        mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putStringArray(
                 CarrierConfigManager.KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY,
                 new String[] {NUMERIC});
@@ -260,7 +265,6 @@
     public void testIsRoamingOverride_RoamingGsmOperator() {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
 
-        mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putStringArray(
                 CarrierConfigManager.KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, new String[] {NUMERIC});
         sendCarrierConfigUpdate();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index f0c43be..2fdff9e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -41,9 +41,7 @@
 import androidx.test.filters.FlakyTest;
 
 import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -53,6 +51,9 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmCdmaCallTrackerTest extends TelephonyTest {
@@ -66,12 +67,16 @@
     // Mocked classes
     private GsmCdmaConnection mConnection;
     private Handler mHandler;
+    private DomainSelectionResolver mDomainSelectionResolver;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mConnection = mock(GsmCdmaConnection.class);
         mHandler = mock(Handler.class);
+        mDomainSelectionResolver = mock(DomainSelectionResolver.class);
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
         mSimulatedCommands.setRadioPower(true, null);
         mPhone.mCi = this.mSimulatedCommands;
 
@@ -86,6 +91,7 @@
     @After
     public void tearDown() throws Exception {
         mCTUT = null;
+        DomainSelectionResolver.setDomainSelectionResolver(null);
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 2248e3f..c5f20e3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -19,9 +19,14 @@
 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
 import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
 import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED;
+import static com.android.internal.telephony.Phone.EVENT_IMS_DEREGISTRATION_TRIGGERED;
+import static com.android.internal.telephony.Phone.EVENT_RADIO_AVAILABLE;
+import static com.android.internal.telephony.Phone.EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE;
 import static com.android.internal.telephony.Phone.EVENT_SRVCC_STATE_CHANGED;
 import static com.android.internal.telephony.Phone.EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED;
 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+import static com.android.internal.telephony.test.SimulatedCommands.FAKE_IMEI;
+import static com.android.internal.telephony.test.SimulatedCommands.FAKE_IMEISV;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -49,13 +54,18 @@
 
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.hardware.radio.modem.ImeiInfo;
 import android.os.AsyncResult;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
+import android.provider.DeviceConfig;
 import android.telecom.VideoProfile;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
@@ -64,17 +74,24 @@
 import android.telephony.CellIdentityGsm;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.NetworkRegistrationInfo;
+import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.util.Log;
 
 import androidx.test.filters.FlakyTest;
 
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.test.SimulatedCommandsVerifier;
 import com.android.internal.telephony.uicc.AdnRecord;
@@ -104,6 +121,7 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmCdmaPhoneTest extends TelephonyTest {
+    private static final String LOG_TAG = "GsmCdmaPhoneTest";
     private static final String TEST_EMERGENCY_NUMBER = "555";
 
     // Mocked classes
@@ -111,10 +129,16 @@
     private UiccSlot mUiccSlot;
     private CommandsInterface mMockCi;
     private AdnRecordCache adnRecordCache;
+    private DomainSelectionResolver mDomainSelectionResolver;
 
     //mPhoneUnderTest
     private GsmCdmaPhone mPhoneUT;
 
+    // Ideally we would use TestableDeviceConfig, but that's not doable because the Settings
+    // app is not currently debuggable. For now, we use the real device config and ensure that
+    // we reset the cellular_security namespace property to its pre-test value after every test.
+    private DeviceConfig.Properties mPreTestProperties;
+
     private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 1;
     private static final int EVENT_EMERGENCY_CALL_TOGGLE = 2;
     private static final int EVENT_SET_ICC_LOCK_ENABLED = 3;
@@ -138,13 +162,18 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
+        mPreTestProperties = DeviceConfig.getProperties(
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE);
         mTestHandler = Mockito.mock(Handler.class);
         mUiccSlot = Mockito.mock(UiccSlot.class);
         mUiccPort = Mockito.mock(UiccPort.class);
         mMockCi = Mockito.mock(CommandsInterface.class);
         adnRecordCache = Mockito.mock(AdnRecordCache.class);
+        mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class);
         doReturn(false).when(mSST).isDeviceShuttingDown();
         doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
 
         mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
             PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
@@ -162,6 +191,14 @@
     public void tearDown() throws Exception {
         mPhoneUT.removeCallbacksAndMessages(null);
         mPhoneUT = null;
+        DomainSelectionResolver.setDomainSelectionResolver(null);
+        try {
+            DeviceConfig.setProperties(mPreTestProperties);
+        } catch (DeviceConfig.BadConfigException e) {
+            Log.e(LOG_TAG,
+                    "Failed to reset DeviceConfig to pre-test state. Test results may be impacted. "
+                            + e.getMessage());
+        }
         super.tearDown();
     }
 
@@ -958,7 +995,7 @@
         verify(mTelephonyManager).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
                 nullable(String.class));
         // IMEI
-        assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
+        assertEquals(FAKE_IMEI, mPhoneUT.getImei());
         // IMEISV
         assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
         // radio capability
@@ -984,7 +1021,7 @@
         verify(mTelephonyManager, times(2)).setBasebandVersionForPhone(eq(mPhoneUT.getPhoneId()),
                 nullable(String.class));
         // device identity
-        assertEquals(SimulatedCommands.FAKE_IMEI, mPhoneUT.getImei());
+        assertEquals(FAKE_IMEI, mPhoneUT.getImei());
         assertEquals(SimulatedCommands.FAKE_IMEISV, mPhoneUT.getDeviceSvn());
         assertEquals(SimulatedCommands.FAKE_ESN, mPhoneUT.getEsn());
         assertEquals(SimulatedCommands.FAKE_MEID, mPhoneUT.getMeid());
@@ -1055,14 +1092,14 @@
                 getVoiceCallForwardingFlag();
 
         // invalid subId
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionController).
-                getSubId(anyInt());
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
+                .getSubId(anyInt());
         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
 
         // valid subId, sharedPreference not present
         int subId1 = 0;
         int subId2 = 1;
-        doReturn(subId1).when(mSubscriptionController).getSubId(anyInt());
+        doReturn(subId1).when(mSubscriptionManagerService).getSubId(anyInt());
         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
 
         // old sharedPreference present
@@ -1084,7 +1121,7 @@
         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
 
         // check for another subId
-        doReturn(subId2).when(mSubscriptionController).getSubId(anyInt());
+        doReturn(subId2).when(mSubscriptionManagerService).getSubId(anyInt());
         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
 
         // set value for the new subId in sharedPreference
@@ -1093,7 +1130,7 @@
         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
 
         // switching back to previous subId, stored value should still be available
-        doReturn(subId1).when(mSubscriptionController).getSubId(anyInt());
+        doReturn(subId1).when(mSubscriptionManagerService).getSubId(anyInt());
         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
 
         // cleanup
@@ -1126,6 +1163,7 @@
     @SmallTest
     public void testGetEmptyIccCard() {
         doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
+        doReturn(null).when(mUiccController).getUiccSlotForPhone(anyInt());
 
         IccCard iccCard = mPhoneUT.getIccCard();
 
@@ -1252,7 +1290,8 @@
         Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
                 new AsyncResult(null, true, null)).sendToTarget();
         processAllMessages();
-        verify(mSubscriptionController, never()).getSubInfoForIccId(any());
+
+        verify(mSubscriptionManagerService, never()).getAllSubInfoList(anyString(), anyString());
 
         // Have IccId defined. But expected value and current value are the same. So no RIL command
         // should be sent.
@@ -1260,7 +1299,8 @@
         doReturn(iccId).when(mUiccSlot).getIccId(anyInt());
         Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
         processAllMessages();
-        verify(mSubscriptionController).getSubInfoForIccId(iccId);
+        verify(mSubscriptionManagerService).getAllSubInfoList(anyString(),
+                nullable(String.class));
         verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
     }
 
@@ -1296,11 +1336,12 @@
     public void testSetRadioPower() throws Exception {
         mPhoneUT.setRadioPower(false);
         verify(mSST).setRadioPowerForReason(false, false, false, false,
-                Phone.RADIO_POWER_REASON_USER);
+                TelephonyManager.RADIO_POWER_REASON_USER);
 
         // Turn on radio for emergency call.
         mPhoneUT.setRadioPower(true, true, false, true);
-        verify(mSST).setRadioPowerForReason(true, true, false, true, Phone.RADIO_POWER_REASON_USER);
+        verify(mSST).setRadioPowerForReason(true, true, false, true,
+                TelephonyManager.RADIO_POWER_REASON_USER);
     }
 
     @Test
@@ -1308,12 +1349,12 @@
     public void testSetRadioPowerOnForTestEmergencyCall() {
         mPhoneUT.setRadioPower(false);
         verify(mSST).setRadioPowerForReason(false, false, false, false,
-                Phone.RADIO_POWER_REASON_USER);
+                TelephonyManager.RADIO_POWER_REASON_USER);
 
         mPhoneUT.setRadioPowerOnForTestEmergencyCall(false);
         verify(mSST).clearAllRadioOffReasons();
         verify(mSST).setRadioPowerForReason(eq(true), eq(false), anyBoolean(), eq(false),
-                eq(Phone.RADIO_POWER_REASON_USER));
+                eq(TelephonyManager.RADIO_POWER_REASON_USER));
     }
 
     @Test
@@ -1429,8 +1470,8 @@
 
     @Test
     public void testEventCarrierConfigChanged() {
-        doReturn(null).when(mSubscriptionController).getSubscriptionProperty(anyInt(),
-                eq(SubscriptionManager.NR_ADVANCED_CALLING_ENABLED));
+        doReturn(null).when(mSubscriptionManagerService).getSubscriptionProperty(anyInt(),
+                eq(SubscriptionManager.NR_ADVANCED_CALLING_ENABLED), anyString(), anyString());
 
         mPhoneUT.mCi = mMockCi;
         mPhoneUT.sendMessage(mPhoneUT.obtainMessage(Phone.EVENT_CARRIER_CONFIG_CHANGED));
@@ -1499,10 +1540,10 @@
     @SmallTest
     public void testLoadAllowedNetworksFromSubscriptionDatabase_loadTheNullValue_isLoadedTrue() {
         int subId = 1;
-        doReturn(subId).when(mSubscriptionController).getSubId(anyInt());
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(anyInt());
 
-        doReturn(null).when(mSubscriptionController).getSubscriptionProperty(anyInt(),
-                eq(SubscriptionManager.ALLOWED_NETWORK_TYPES));
+        doReturn(null).when(mSubscriptionManagerService).getSubscriptionProperty(anyInt(),
+                eq(SubscriptionManager.ALLOWED_NETWORK_TYPES), anyString(), anyString());
 
         mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
 
@@ -1513,17 +1554,94 @@
     @SmallTest
     public void testLoadAllowedNetworksFromSubscriptionDatabase_subIdNotValid_isLoadedFalse() {
         int subId = -1;
-        doReturn(subId).when(mSubscriptionController).getSubId(anyInt());
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(anyInt());
 
-        when(mSubscriptionController.getSubscriptionProperty(anyInt(),
-                eq(SubscriptionManager.ALLOWED_NETWORK_TYPES))).thenReturn(null);
-
+        when(mSubscriptionManagerService.getSubscriptionProperty(anyInt(),
+                eq(SubscriptionManager.ALLOWED_NETWORK_TYPES), anyString(), anyString()))
+                .thenReturn(null);
 
         mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
 
         assertEquals(false, mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
     }
 
+    @Test
+    public void testLoadAllowedNetworksFromSubscriptionDatabase_allValidData() {
+        int subId = 1;
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(anyInt());
+
+        // 13 == TelephonyManager.NETWORK_TYPE_LTE
+        // NR_BITMASK == 4096 == 1 << (13 - 1)
+        String validSerializedNetworkMap = "user=4096,power=4096,carrier=4096,enable_2g=4096";
+        SubscriptionInfoInternal si = new SubscriptionInfoInternal.Builder()
+                .setId(1)
+                .setAllowedNetworkTypesForReasons(validSerializedNetworkMap)
+                .build();
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(eq(1));
+
+        assertFalse(mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
+        mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
+        assertTrue(mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
+
+        for (int i = 0; i < 4; ++i) {
+            assertEquals(TelephonyManager.NETWORK_TYPE_BITMASK_LTE,
+                    mPhoneUT.getAllowedNetworkTypes(i));
+        }
+    }
+
+    @Test
+    public void testLoadAllowedNetworksFromSubscriptionDatabase_invalidKeys() {
+        int subId = 1;
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(anyInt());
+
+        // 13 == TelephonyManager.NETWORK_TYPE_LTE
+        // NR_BITMASK == 4096 == 1 << (13 - 1)
+        String validSerializedNetworkMap =
+                "user=4096,power=4096,carrier=4096,enable_2g=4096,-1=4096";
+        SubscriptionInfoInternal si = new SubscriptionInfoInternal.Builder()
+                .setId(1)
+                .setAllowedNetworkTypesForReasons(validSerializedNetworkMap)
+                .build();
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(eq(1));
+
+        assertFalse(mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
+        mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
+        assertTrue(mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
+
+        for (int i = 0; i < 4; ++i) {
+            assertEquals(TelephonyManager.NETWORK_TYPE_BITMASK_LTE,
+                    mPhoneUT.getAllowedNetworkTypes(i));
+        }
+    }
+
+    @Test
+    public void testLoadAllowedNetworksFromSubscriptionDatabase_invalidValues() {
+        int subId = 1;
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(anyInt());
+
+        // 19 == TelephonyManager.NETWORK_TYPE_NR
+        // NR_BITMASK == 524288 == 1 << 19
+        String validSerializedNetworkMap = "user=4096,power=4096,carrier=4096,enable_2g=-1";
+        SubscriptionInfoInternal si = new SubscriptionInfoInternal.Builder()
+                .setId(1)
+                .setAllowedNetworkTypesForReasons(validSerializedNetworkMap)
+                .build();
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(eq(1));
+
+        mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
+
+        for (int i = 0; i < 3; ++i) {
+            assertEquals(TelephonyManager.NETWORK_TYPE_BITMASK_LTE,
+                    mPhoneUT.getAllowedNetworkTypes(i));
+        }
+
+        long defaultAllowedNetworkTypes = RadioAccessFamily.getRafFromNetworkType(
+                RILConstants.PREFERRED_NETWORK_MODE);
+        assertEquals(defaultAllowedNetworkTypes, mPhoneUT.getAllowedNetworkTypes(
+                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G));
+
+    }
+
     /**
      * 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.
@@ -1604,7 +1722,7 @@
 
         doReturn(true).when(mTelephonyManager).isEmergencyNumber(anyString());
         doReturn(isEmergencyPerDialedSim).when(mEmergencyNumberTracker).isEmergencyNumber(
-                anyString(), anyBoolean());
+                anyString());
 
         mPhoneUT.setImsPhone(mImsPhone);
     }
@@ -1655,8 +1773,9 @@
     }
 
 
-    private SubscriptionInfo makeSubscriptionInfo(boolean isOpportunistic, int usageSetting) {
-        return new SubscriptionInfo.Builder()
+    private SubscriptionInfoInternal makeSubscriptionInfoInternal(
+            boolean isOpportunistic, int usageSetting) {
+        return new SubscriptionInfoInternal.Builder()
                 .setId(1)
                 .setIccId("xxxxxxxxx")
                 .setSimSlotIndex(1)
@@ -1667,8 +1786,8 @@
                 .setMcc("001")
                 .setMnc("01")
                 .setCountryIso("us")
-                .setEmbedded(true)
-                .setOpportunistic(isOpportunistic)
+                .setEmbedded(1)
+                .setOpportunistic(isOpportunistic ? 1 : 0)
                 .setCarrierId(1)
                 .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING)
                 .setUsageSetting(usageSetting)
@@ -1681,10 +1800,10 @@
         setupUsageSettingResources();
         mPhoneUT.mCi = mMockCi;
 
-        final SubscriptionInfo si = makeSubscriptionInfo(
+        final SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
                 false, SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
 
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
         processAllMessages();
@@ -1705,9 +1824,9 @@
         setupUsageSettingResources();
         mPhoneUT.mCi = mMockCi;
 
-        final SubscriptionInfo si = makeSubscriptionInfo(
+        final SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
                 true, SubscriptionManager.USAGE_SETTING_DEFAULT);
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
         processAllMessages();
@@ -1728,11 +1847,11 @@
         setupUsageSettingResources();
         mPhoneUT.mCi = mMockCi;
 
-        final SubscriptionInfo si = makeSubscriptionInfo(
+        final SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
                 false, SubscriptionManager.USAGE_SETTING_DEFAULT);
 
         assertNotNull(si);
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
+        doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
         processAllMessages();
@@ -2041,7 +2160,7 @@
     }
 
     @Test
-    public void testDial_fdnCheck() throws Exception{
+    public void testDial_fdnCheck() throws Exception {
         // dial setup
         mSST.mSS = mServiceState;
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
@@ -2069,7 +2188,7 @@
             connection = mPhoneUT.dial("1234567890",
                     new PhoneInternalInterface.DialArgs.Builder().build());
             fail("Expected CallStateException with ERROR_FDN_BLOCKED thrown.");
-        } catch(CallStateException e) {
+        } catch (CallStateException e) {
             assertEquals(CallStateException.ERROR_FDN_BLOCKED, e.getError());
         }
 
@@ -2077,8 +2196,383 @@
         fdnCheckCleanup();
     }
 
+    @Test
+    public void testHandleNullCipherAndIntegrityEnabled_radioFeatureUnsupported() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, Boolean.TRUE.toString(),
+                false);
+        mPhoneUT.mCi = mMockCi;
+        assertFalse(mPhoneUT.isNullCipherAndIntegritySupported());
+
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_RADIO_AVAILABLE,
+                new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
+        processAllMessages();
+
+        verify(mMockCi, times(1)).setNullCipherAndIntegrityEnabled(anyBoolean(),
+                any(Message.class));
+
+        // Some ephemeral error occurred in the modem, but the feature was supported
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE,
+                new AsyncResult(null, null,
+                        new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED))));
+        processAllMessages();
+        assertFalse(mPhoneUT.isNullCipherAndIntegritySupported());
+    }
+
+    @Test
+    public void testHandleNullCipherAndIntegrityEnabled_radioSupportsFeature() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, Boolean.TRUE.toString(),
+                false);
+        mPhoneUT.mCi = mMockCi;
+        assertFalse(mPhoneUT.isNullCipherAndIntegritySupported());
+
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_RADIO_AVAILABLE,
+                new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
+        processAllMessages();
+
+        verify(mMockCi, times(1)).setNullCipherAndIntegrityEnabled(anyBoolean(),
+                any(Message.class));
+
+        // Some ephemeral error occurred in the modem, but the feature was supported
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE,
+                new AsyncResult(null, null, null)));
+        processAllMessages();
+        assertTrue(mPhoneUT.isNullCipherAndIntegritySupported());
+    }
+
+    @Test
+    public void testHandleNullCipherAndIntegrityEnabled_featureFlagOn() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, Boolean.TRUE.toString(),
+                false);
+        mPhoneUT.mCi = mMockCi;
+
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_RADIO_AVAILABLE,
+                new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
+        processAllMessages();
+
+        verify(mMockCi, times(1)).setNullCipherAndIntegrityEnabled(anyBoolean(),
+                any(Message.class));
+    }
+
+    @Test
+    public void testHandleNullCipherAndIntegrityEnabled_featureFlagOff() {
+        mPhoneUT.mCi = mMockCi;
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
+                TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, Boolean.FALSE.toString(),
+                false);
+
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_RADIO_AVAILABLE,
+                new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null)));
+        processAllMessages();
+
+        verify(mMockCi, times(0)).setNullCipherAndIntegrityEnabled(anyBoolean(),
+                any(Message.class));
+    }
+
     public void fdnCheckCleanup() {
         doReturn(false).when(mUiccCardApplication3gpp).getIccFdnAvailable();
         doReturn(false).when(mUiccCardApplication3gpp).getIccFdnEnabled();
     }
+
+    @Test
+    @SmallTest
+    public void testTriggerImsDeregistration() throws Exception {
+        replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
+
+        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(EVENT_IMS_DEREGISTRATION_TRIGGERED,
+                new AsyncResult(null,
+                        new int[]{ImsRegistrationImplBase.REASON_SIM_REFRESH}, null)));
+        processAllMessages();
+
+        verify(mImsPhone, times(1)).triggerImsDeregistration(
+                eq(ImsRegistrationImplBase.REASON_SIM_REFRESH));
+    }
+
+    @Test
+    public void testDomainSelectionEmergencyCallCs() throws CallStateException {
+        setupEmergencyCallScenario(false /* USE_ONLY_DIALED_SIM_ECC_LIST */,
+                false /* isEmergencyOnDialedSim */);
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_CS);
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIntentExtras(extras)
+                .build();
+        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, dialArgs);
+
+        verify(mCT).dialGsm(anyString(), any(PhoneInternalInterface.DialArgs.class));
+    }
+
+    @Test
+    public void testDomainSelectionEmergencyCallPs() throws CallStateException {
+        setupEmergencyCallScenario(false /* USE_ONLY_DIALED_SIM_ECC_LIST */,
+                false /* isEmergencyOnDialedSim */);
+
+        doReturn(false).when(mImsPhone).isImsAvailable();
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_PS);
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIntentExtras(extras)
+                .build();
+        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, dialArgs);
+
+        verify(mImsPhone).dial(anyString(), any(PhoneInternalInterface.DialArgs.class));
+
+        extras = dialArgs.intentExtras;
+
+        assertFalse(extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE));
+    }
+
+    @Test
+    public void testDomainSelectionEmergencyCallNon3GppPs() throws CallStateException {
+        setupEmergencyCallScenario(false /* USE_ONLY_DIALED_SIM_ECC_LIST */,
+                false /* isEmergencyOnDialedSim */);
+
+        doReturn(false).when(mImsPhone).isImsAvailable();
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, PhoneConstants.DOMAIN_NON_3GPP_PS);
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIntentExtras(extras)
+                .build();
+        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, dialArgs);
+
+        verify(mImsPhone).dial(anyString(), any(PhoneInternalInterface.DialArgs.class));
+
+        extras = dialArgs.intentExtras;
+
+        assertTrue(extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE));
+        assertEquals(String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN),
+                extras.getString(ImsCallProfile.EXTRA_CALL_RAT_TYPE));
+    }
+
+    @Test
+    public void testDomainSelectionDialCs() throws Exception {
+        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();
+        doReturn(true).when(mImsPhone).isUtEnabled();
+
+        replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_CS);
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIntentExtras(extras)
+                .build();
+        Connection connection = mPhoneUT.dial("1234567890", dialArgs);
+        verify(mCT).dialGsm(eq("1234567890"), any(PhoneInternalInterface.DialArgs.class));
+    }
+
+    @Test
+    public void testDomainSelectionDialPs() throws Exception {
+        mSST.mSS = mServiceState;
+        doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
+
+        mCT.mForegroundCall = mGsmCdmaCall;
+        mCT.mBackgroundCall = mGsmCdmaCall;
+        mCT.mRingingCall = mGsmCdmaCall;
+        doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
+
+        replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_PS);
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIntentExtras(extras)
+                .build();
+        Connection connection = mPhoneUT.dial("1234567890", dialArgs);
+        verify(mImsPhone).dial(eq("1234567890"), any(PhoneInternalInterface.DialArgs.class));
+    }
+
+    @Test
+    public void getImeiType_primary() {
+        Message message = mPhoneUT.obtainMessage(Phone.EVENT_GET_DEVICE_IMEI_DONE);
+        ImeiInfo imeiInfo = new ImeiInfo();
+        imeiInfo.imei = FAKE_IMEI;
+        imeiInfo.svn = FAKE_IMEISV;
+        imeiInfo.type = ImeiInfo.ImeiType.PRIMARY;
+        AsyncResult.forMessage(message, imeiInfo, null);
+        mPhoneUT.handleMessage(message);
+        assertEquals(Phone.IMEI_TYPE_PRIMARY, mPhoneUT.getImeiType());
+        assertEquals(FAKE_IMEI, mPhoneUT.getImei());
+    }
+
+    @Test
+    public void getImeiType_Secondary() {
+        Message message = mPhoneUT.obtainMessage(Phone.EVENT_GET_DEVICE_IMEI_DONE);
+        ImeiInfo imeiInfo = new ImeiInfo();
+        imeiInfo.imei = FAKE_IMEI;
+        imeiInfo.svn = FAKE_IMEISV;
+        imeiInfo.type = ImeiInfo.ImeiType.SECONDARY;
+        AsyncResult.forMessage(message, imeiInfo, null);
+        mPhoneUT.handleMessage(message);
+        assertEquals(Phone.IMEI_TYPE_SECONDARY, mPhoneUT.getImeiType());
+        assertEquals(FAKE_IMEI, mPhoneUT.getImei());
+    }
+
+    @Test
+    public void getImei() {
+        assertTrue(mPhoneUT.isPhoneTypeGsm());
+        Message message = mPhoneUT.obtainMessage(Phone.EVENT_RADIO_AVAILABLE);
+        mPhoneUT.handleMessage(message);
+        verify(mSimulatedCommandsVerifier, times(2)).getImei(nullable(Message.class));
+    }
+
+    @Test
+    public void testSetAllowedNetworkTypes_admin2gRestrictionHonored() throws Exception {
+        // circumvent loading/saving to sim db. it's not behavior under test.
+        TelephonyManager.setupISubForTest(Mockito.mock(SubscriptionManagerService.class));
+        TelephonyManager.enableServiceHandleCaching();
+        mPhoneUT.loadAllowedNetworksFromSubscriptionDatabase();
+
+        // 2g is disabled by admin
+        UserManager userManagerMock = mContext.getSystemService(UserManager.class);
+        when(userManagerMock.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(true);
+        mContext.sendBroadcast(new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED));
+
+        // carrier requests 2g to be enabled
+        mPhoneUT.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER,
+                TelephonyManager.NETWORK_CLASS_BITMASK_2G, null);
+
+        // Assert that 2g was not passed as an allowed network type to the modem
+        ArgumentCaptor<Integer> captureBitMask = ArgumentCaptor.forClass(Integer.class);
+        // One call for the admin restriction update, another by this test
+        verify(mSimulatedCommandsVerifier, times(2)).setAllowedNetworkTypesBitmap(
+                captureBitMask.capture(),
+                nullable(Message.class));
+        assertEquals(0, captureBitMask.getValue() & TelephonyManager.NETWORK_CLASS_BITMASK_2G);
+    }
+
+    @Test
+    @SmallTest
+    public void testEcbm() throws Exception {
+        assertFalse(mPhoneUT.isInEcm());
+
+        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
+                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));
+
+        assertTrue(mPhoneUT.isInEcm());
+        verifyEcbmIntentWasSent(1 /*times*/, true /*inEcm*/);
+        // verify that wakeLock is acquired in ECM
+        assertTrue(mPhoneUT.getWakeLock().isHeld());
+
+        boolean isTestingEmergencyCallbackMode = true;
+        replaceInstance(GsmCdmaPhone.class, "mIsTestingEmergencyCallbackMode", mPhoneUT,
+                isTestingEmergencyCallbackMode);
+        mPhoneUT.exitEmergencyCallbackMode();
+        processAllMessages();
+
+        assertFalse(mPhoneUT.isInEcm());
+        verifyEcbmIntentWasSent(2/*times*/, false /*inEcm*/);
+        // verify wakeLock released
+        assertFalse(mPhoneUT.getWakeLock().isHeld());
+    }
+
+    private void verifyEcbmIntentWasSent(int times, boolean isInEcm) throws Exception {
+        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext, atLeast(times)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
+                any());
+
+        Intent intent = intentArgumentCaptor.getValue();
+        assertNotNull(intent);
+        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
+        assertEquals(isInEcm, intent.getBooleanExtra(
+                TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
+    }
+
+    @Test
+    @SmallTest
+    public void testEcbmWhenDomainSelectionEnabled() throws Exception {
+        DomainSelectionResolver dsResolver = Mockito.mock(DomainSelectionResolver.class);
+        doReturn(true).when(dsResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);
+
+        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
+                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));
+
+        boolean isTestingEmergencyCallbackMode = true;
+        replaceInstance(GsmCdmaPhone.class, "mIsTestingEmergencyCallbackMode", mPhoneUT,
+                isTestingEmergencyCallbackMode);
+        mPhoneUT.exitEmergencyCallbackMode();
+        processAllMessages();
+
+        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testEcbmOnModemResetForNonGsmPhone() throws Exception {
+        switchToCdma();
+        assertFalse(mPhoneUT.isInEcm());
+
+        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
+                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));
+
+        assertTrue(mPhoneUT.isInEcm());
+
+        Message m = mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_MODEM_RESET);
+        AsyncResult.forMessage(m);
+        mPhoneUT.handleMessage(m);
+
+        assertFalse(mPhoneUT.isInEcm());
+        verifyEcbmIntentWasSent(2 /*times*/, false /*inEcm*/);
+    }
+
+    @Test
+    @SmallTest
+    public void testEcbmOnModemResetWhenDomainSelectionEnabled() throws Exception {
+        DomainSelectionResolver dsResolver = Mockito.mock(DomainSelectionResolver.class);
+        doReturn(true).when(dsResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);
+
+        EmergencyStateTracker est = Mockito.mock(EmergencyStateTracker.class);
+        doReturn(true).when(est).isInEcm();
+        replaceInstance(EmergencyStateTracker.class, "INSTANCE", null, est);
+
+        GsmCdmaPhone spyPhone = spy(mPhoneUT);
+        doReturn(true).when(spyPhone).isInEcm();
+        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_MODEM_RESET));
+
+        verify(est).exitEmergencyCallbackMode();
+    }
+
+    @Test
+    public void testGetUserHandle() {
+        UserHandle userHandle = new UserHandle(123);
+        doReturn(userHandle).when(mSubscriptionManager).getSubscriptionUserHandle(anyInt());
+        assertEquals(userHandle, mPhoneUT.getUserHandle());
+
+        doReturn(null).when(mSubscriptionManager).getSubscriptionUserHandle(anyInt());
+        assertNull(mPhoneUT.getUserHandle());
+
+        doThrow(IllegalArgumentException.class).when(mSubscriptionManager)
+                .getSubscriptionUserHandle(anyInt());
+        assertNull(mPhoneUT.getUserHandle());
+    }
+
+    @Test
+    public void testResetNetworkSelectionModeOnSimSwap() {
+        // Set current network selection manual mode.
+        mSimulatedCommands.setNetworkSelectionModeManual("123", 0, null);
+        clearInvocations(mSimulatedCommandsVerifier);
+
+        // SIM loaded.
+        Intent simLoadedIntent = new Intent(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
+        simLoadedIntent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
+        simLoadedIntent.putExtra(TelephonyManager.EXTRA_SIM_STATE,
+                TelephonyManager.SIM_STATE_LOADED);
+        mContext.sendBroadcast(simLoadedIntent);
+
+        processAllFutureMessages();
+        // Verify set network selection mode to be AUTO
+        verify(mSimulatedCommandsVerifier).getNetworkSelectionMode(any(Message.class));
+        verify(mSimulatedCommandsVerifier).setNetworkSelectionModeAutomatic(any(Message.class));
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
index 67d6e5c..4012e98 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
@@ -18,6 +18,15 @@
 
 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.os.AsyncResult;
 import android.os.Message;
 import android.testing.AndroidTestingRunner;
@@ -25,13 +34,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import static org.junit.Assert.assertEquals;
-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;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 
 import org.junit.After;
 import org.junit.Before;
@@ -50,6 +53,8 @@
 
     // Mocked classes
     private SmsPermissions mMockSmsPermissions;
+    protected EmergencyNumberTracker mEmergencyNumberTracker2;
+    protected IccSmsInterfaceManager.PhoneFactoryProxy mPhoneFactoryProxy;
 
     @Before
     public void setUp() throws Exception {
@@ -57,6 +62,12 @@
         mMockSmsPermissions = mock(SmsPermissions.class);
         mIccSmsInterfaceManager = new IccSmsInterfaceManager(mPhone, mContext, mAppOpsManager,
                 mSmsDispatchersController, mMockSmsPermissions);
+
+        mPhoneFactoryProxy = mock(IccSmsInterfaceManager.PhoneFactoryProxy.class);
+        mIccSmsInterfaceManager.setPhoneFactoryProxy(mPhoneFactoryProxy);
+
+        mEmergencyNumberTracker2 = mock(EmergencyNumberTracker.class);
+        doReturn(mEmergencyNumberTracker2).when(mPhone2).getEmergencyNumberTracker();
     }
 
     @After
@@ -144,4 +155,22 @@
             fail("getSmscLatch.await interrupted");
         }
     }
+
+    @Test
+    public void testNotifyIfOutgoingEmergencySmsWithDualSim() {
+        //Replicate Dual-SIM:
+        Phone [] phones = {mPhone, mPhone2};
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(phones);
+        doReturn(1).when(mPhone).getPhoneId();
+        doReturn(2).when(mPhone2).getPhoneId();
+
+        //Replicate behavior when a number is an emergency number
+        // on the secondary SIM but not on the default SIM:
+        when(mPhone.getEmergencyNumberTracker().getEmergencyNumber(any())).thenReturn(null);
+        when(mEmergencyNumberTracker2.getEmergencyNumber(any()))
+                .thenReturn(getTestEmergencyNumber());
+
+        mIccSmsInterfaceManager.notifyIfOutgoingEmergencySms("1234");
+        verify(mEmergencyNumberTracker2).getEmergencyNumber("1234");
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
index fd1c5e0..1c44772 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
@@ -29,10 +29,13 @@
 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;
 
 import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SmsMessage;
 import android.telephony.ims.stub.ImsSmsImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -64,7 +67,9 @@
     private FeatureConnector.Listener<ImsManager> mImsManagerListener;
     private HashMap<String, Object> mTrackerData;
     private ImsSmsDispatcher mImsSmsDispatcher;
+    PersistableBundle mBundle = new PersistableBundle();
     private static final int SUB_0 = 0;
+    private static final String TAG = "ImsSmsDispatcherTest";
 
     @Before
     public void setUp() throws Exception {
@@ -87,6 +92,7 @@
         when(mSmsDispatchersController.isIms()).thenReturn(true);
         mTrackerData = new HashMap<>(1);
         when(mSmsTracker.getData()).thenReturn(mTrackerData);
+        verify(mSmsDispatchersController).setImsManager(mImsManager);
     }
 
     @After
@@ -97,6 +103,85 @@
         super.tearDown();
     }
 
+   /**
+     * Send Memory Availability Notification and verify that the token is correct.
+     */
+    @Test
+    @SmallTest
+    public void testOnMemoryAvailable() throws Exception {
+        int token = mImsSmsDispatcher.mNextToken.get();
+        //Send SMMA
+        mImsSmsDispatcher.onMemoryAvailable();
+        assertEquals(token + 1, mImsSmsDispatcher.mNextToken.get());
+        verify(mImsManager).onMemoryAvailable(eq(token + 1));
+    }
+
+    /**
+     * Receive SEND_STATUS_ERROR_RETRY with onMemoryAvailableResult Api and check if
+     * sending SMMA Notification is retried once
+     */
+    @Test
+    @SmallTest
+    public void testOnMemoryAvailableResultErrorRetry() throws Exception {
+        int token = mImsSmsDispatcher.mNextToken.get();
+        //Send SMMA
+        mImsSmsDispatcher.onMemoryAvailable();
+        assertEquals(token + 1, mImsSmsDispatcher.mNextToken.get());
+        verify(mImsManager).onMemoryAvailable(eq(token + 1));
+        // Retry over IMS
+        mImsSmsDispatcher.getSmsListener().onMemoryAvailableResult(token + 1,
+                ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, SmsResponse.NO_ERROR_CODE);
+        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
+        processAllMessages();
+        verify(mImsManager).onMemoryAvailable(eq(token + 2));
+        //2nd Failure should not retry
+        mImsSmsDispatcher.getSmsListener().onMemoryAvailableResult(token + 2,
+                ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, SmsResponse.NO_ERROR_CODE);
+        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
+        processAllMessages();
+        verify(mImsManager, times(0)).onMemoryAvailable(eq(token + 3));
+
+    }
+    /**
+     * Receive SEND_STATUS_OK with onMemoryAvailableResult Api and check if
+     * sending SMMA Notification behaviour is correct
+     */
+    @Test
+    @SmallTest
+    public void testOnMemoryAvailableResultSuccess() throws Exception {
+        int token = mImsSmsDispatcher.mNextToken.get();
+        //Send SMMA
+        mImsSmsDispatcher.onMemoryAvailable();
+        assertEquals(token + 1, mImsSmsDispatcher.mNextToken.get());
+        verify(mImsManager).onMemoryAvailable(eq(token + 1));
+        // Retry over IMS
+        mImsSmsDispatcher.getSmsListener().onMemoryAvailableResult(token + 1,
+                ImsSmsImplBase.SEND_STATUS_OK, SmsResponse.NO_ERROR_CODE);
+        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
+        processAllMessages();
+        verify(mImsManager, times(0)).onMemoryAvailable(eq(token + 2));
+
+    }
+    /**
+     * Receive SEND_STATUS_ERROR with onMemoryAvailableResult Api and check if
+     * sending SMMA Notification behaviour is correct
+     */
+    @Test
+    @SmallTest
+    public void testOnMemoryAvailableResultError() throws Exception {
+        int token = mImsSmsDispatcher.mNextToken.get();
+        //Send SMMA
+        mImsSmsDispatcher.onMemoryAvailable();
+        assertEquals(token + 1, mImsSmsDispatcher.mNextToken.get());
+        verify(mImsManager).onMemoryAvailable(eq(token + 1));
+        // Retry over IMS
+        mImsSmsDispatcher.getSmsListener().onMemoryAvailableResult(token + 1,
+                ImsSmsImplBase.SEND_STATUS_ERROR, SmsResponse.NO_ERROR_CODE);
+        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
+        processAllMessages();
+        verify(mImsManager, times(0)).onMemoryAvailable(eq(token + 2));
+
+    }
     /**
      * Send an SMS and verify that the token and PDU is correct.
      */
@@ -155,6 +240,13 @@
     @SmallTest
     public void testErrorImsRetry() throws Exception {
         int token = mImsSmsDispatcher.mNextToken.get();
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                .KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT,
+                                2000);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT, 3);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_COUNT_INT, 3);
         mTrackerData.put("pdu", com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(null,
                 "+15555551212", "Test", false).encodedMessage);
         when(mImsManager.getSmsFormat()).thenReturn(SmsMessage.FORMAT_3GPP);
@@ -230,7 +322,10 @@
     @Test
     public void testSendSmswithMessageRef() throws Exception {
         int token = mImsSmsDispatcher.mNextToken.get();
-        int messageRef = mImsSmsDispatcher.nextMessageRef() + 1;
+        int messageRef = mImsSmsDispatcher.nextMessageRef();
+        if (mImsSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += 1;
+        }
 
         when(mImsManager.getSmsFormat()).thenReturn(SmsMessage.FORMAT_3GPP);
         when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
@@ -246,7 +341,10 @@
     @Test
     public void testFallbackGsmRetrywithMessageRef() throws Exception {
         int token = mImsSmsDispatcher.mNextToken.get();
-        int messageRef = mImsSmsDispatcher.nextMessageRef() + 1;
+        int messageRef = mImsSmsDispatcher.nextMessageRef();
+        if (mImsSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += 1;
+        }
 
         when(mImsManager.getSmsFormat()).thenReturn(SmsMessage.FORMAT_3GPP);
         when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
@@ -265,13 +363,28 @@
         ArgumentCaptor<SMSDispatcher.SmsTracker> captor =
                 ArgumentCaptor.forClass(SMSDispatcher.SmsTracker.class);
         verify(mSmsDispatchersController).sendRetrySms(captor.capture());
-        assertTrue(messageRef + 1 == captor.getValue().mMessageRef);
+        if (mImsSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            assertTrue(messageRef + 1 == captor.getValue().mMessageRef);
+        } else {
+            assertTrue(messageRef == captor.getValue().mMessageRef);
+        }
     }
 
     @Test
     public void testErrorImsRetrywithMessageRef() throws Exception {
         int token = mImsSmsDispatcher.mNextToken.get();
-        int messageRef = mImsSmsDispatcher.nextMessageRef() + 1;
+        int messageRef = mImsSmsDispatcher.nextMessageRef();
+        if (mImsSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += 1;
+        }
+
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT,
+                                                2000);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT, 3);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_COUNT_INT, 3);
         when(mImsManager.getSmsFormat()).thenReturn(SmsMessage.FORMAT_3GPP);
         when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
         doReturn(mSmsUsageMonitor).when(mSmsDispatchersController).getUsageMonitor();
@@ -293,7 +406,73 @@
         verify(mImsManager).sendSms(eq(token + 2), eq(messageRef), eq(SmsMessage.FORMAT_3GPP),
                 nullable(String.class), eq(true), byteCaptor.capture());
         byte[] pdu = byteCaptor.getValue();
-        assertEquals(pdu[1], messageRef);
+        assertEquals(messageRef, pdu[1]);
         assertEquals(0x04, (pdu[0] & 0x04));
     }
+
+    @Test
+    public void testErrorImsRetrywithRetryConfig() throws Exception {
+        int token = mImsSmsDispatcher.mNextToken.get();
+        int messageRef = mImsSmsDispatcher.nextMessageRef();
+        if (mImsSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += 1;
+        }
+
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT,
+                                                3000);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT, 2);
+        mContextFixture.getCarrierConfigBundle().putInt(CarrierConfigManager.ImsSms
+                                                .KEY_SMS_MAX_RETRY_COUNT_INT, 3);
+        when(mImsManager.getSmsFormat()).thenReturn(SmsMessage.FORMAT_3GPP);
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
+        doReturn(mSmsUsageMonitor).when(mSmsDispatchersController).getUsageMonitor();
+        mImsSmsDispatcher.sendText("+15555551212", null, "Retry test",
+                null, null, null, null, false,
+                -1, false, -1, false, 0);
+        verify(mImsManager).sendSms(eq(token + 1), eq(messageRef), eq(SmsMessage.FORMAT_3GPP),
+                nullable(String.class), eq(false), (byte[]) any());
+        assertEquals(2, mImsSmsDispatcher.getMaxRetryCountOverIms());
+        assertEquals(3, mImsSmsDispatcher.getMaxSmsRetryCount());
+        assertEquals(3000, mImsSmsDispatcher.getSmsRetryDelayValue());
+        // Retry over IMS
+        mImsSmsDispatcher.getSmsListener().onSendSmsResult(token + 1, messageRef,
+                ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, 0, SmsResponse.NO_ERROR_CODE);
+        waitForMs(mImsSmsDispatcher.getSmsRetryDelayValue() + 200);
+        processAllMessages();
+
+        // Make sure tpmr value is same and retry bit set
+        ArgumentCaptor<byte[]> byteCaptor = ArgumentCaptor.forClass(byte[].class);
+        verify(mImsManager).sendSms(eq(token + 2), eq(messageRef), eq(SmsMessage.FORMAT_3GPP),
+                nullable(String.class), eq(true), byteCaptor.capture());
+        byte[] pdu = byteCaptor.getValue();
+        assertEquals(messageRef, pdu[1]);
+        assertEquals(0x04, (pdu[0] & 0x04));
+        // Retry over IMS for the second time
+        mImsSmsDispatcher.getSmsListener().onSendSmsResult(token + 2, messageRef,
+                ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, 0, SmsResponse.NO_ERROR_CODE);
+        waitForMs(mImsSmsDispatcher.getSmsRetryDelayValue() + 200);
+        processAllMessages();
+        // Make sure tpmr value is same and retry bit set
+        ArgumentCaptor<byte[]> byteCaptor2 = ArgumentCaptor.forClass(byte[].class);
+        verify(mImsManager).sendSms(eq(token + 3), eq(messageRef), eq(SmsMessage.FORMAT_3GPP),
+                nullable(String.class), eq(true), byteCaptor2.capture());
+        byte[] pdu2 = byteCaptor2.getValue();
+        assertEquals(messageRef, pdu2[1]);
+        assertEquals(0x04, (pdu2[0] & 0x04));
+
+        mImsSmsDispatcher.getSmsListener().onSendSmsResult(token + 3, messageRef,
+                ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, 0, SmsResponse.NO_ERROR_CODE);
+        waitForMs(mImsSmsDispatcher.getSmsRetryDelayValue() + 200);
+        processAllMessages();
+        // Make sure tpmr value is same and retry bit set
+        ArgumentCaptor<SMSDispatcher.SmsTracker> captor =
+                ArgumentCaptor.forClass(SMSDispatcher.SmsTracker.class);
+        // Ensure GsmSmsDispatcher calls sendSms
+        verify(mSmsDispatchersController).sendRetrySms(captor.capture());
+
+        assertNotNull(captor.getValue());
+        assertTrue(captor.getValue().mRetryCount > 0);
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
index b11b94e..d251cf5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
@@ -24,8 +24,6 @@
 import android.database.MatrixCursor;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import androidx.test.InstrumentationRegistry;
-
 import com.android.internal.util.HexDump;
 
 import org.junit.After;
@@ -34,7 +32,7 @@
 
 import java.util.Arrays;
 
-public class InboundSmsTrackerTest {
+public class InboundSmsTrackerTest extends TelephonyTest {
     InboundSmsTracker mInboundSmsTracker;
 
     private static final byte[] FAKE_PDU = new byte[]{1, 2, 3};
@@ -50,7 +48,8 @@
 
     @Before
     public void setUp() throws Exception {
-        mInboundSmsTracker = new InboundSmsTracker(InstrumentationRegistry.getContext(),
+        super.setUp(getClass().getSimpleName());
+        mInboundSmsTracker = new InboundSmsTracker(mContext,
                 FAKE_PDU, FAKE_TIMESTAMP, FAKE_DEST_PORT, false,
                 FAKE_ADDRESS, FAKE_DISPLAY_ADDRESS, FAKE_REFERENCE_NUMBER, FAKE_SEQUENCE_NUMBER,
                 FAKE_MESSAGE_COUNT, false, FAKE_MESSAGE_BODY, false /* isClass0 */, FAKE_SUBID,
@@ -58,8 +57,9 @@
     }
 
     @After
-    public void tearDown() {
+    public void tearDown() throws Exception {
         mInboundSmsTracker = null;
+        super.tearDown();
     }
 
     public static MatrixCursor createFakeCursor() {
@@ -108,8 +108,7 @@
     @SmallTest
     public void testInitializationFromDb() {
         Cursor cursor = createFakeCursor();
-        mInboundSmsTracker = new InboundSmsTracker(InstrumentationRegistry.getContext(),
-                cursor, false);
+        mInboundSmsTracker = new InboundSmsTracker(mContext, cursor, false);
         cursor.close();
         testInitialization();
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index 93d584b..f4c19d9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -25,6 +25,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -33,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 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;
@@ -56,6 +58,7 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.telephony.data.DataSettingsManager;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -80,115 +83,178 @@
     private MultiSimSettingController mMultiSimSettingControllerUT;
     private Phone[] mPhones;
     private ParcelUuid mGroupUuid1 = new ParcelUuid(UUID.randomUUID());
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     // Mocked classes
-    private SubscriptionController mSubControllerMock;
-    private ISub mMockedIsub;
     private Phone mPhoneMock1;
     private Phone mPhoneMock2;
     private DataSettingsManager mDataSettingsManagerMock1;
     private DataSettingsManager mDataSettingsManagerMock2;
     private CommandsInterface mMockCi;
 
-    private final SubscriptionInfo mSubInfo1 = new SubscriptionInfo.Builder()
-            .setId(1)
-            .setIccId("subInfo1 IccId")
-            .setSimSlotIndex(0)
-            .setDisplayName("T-mobile")
-            .setCarrierName("T-mobile")
-            .setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER)
-            .setIconTint(255)
-            .setNumber("12345")
-            .setMcc("310")
-            .setMnc("260")
-            .setCountryIso("us")
-            .build();
+    private final SubscriptionInfoInternal[] mSubInfo = new SubscriptionInfoInternal[10];
 
-    private SubscriptionInfo mSubInfo2 = new SubscriptionInfo.Builder(mSubInfo1)
-            .setId(2)
-            .setIccId("subInfo2 IccId")
-            .setGroupUuid(mGroupUuid1.toString())
-            .build();
+    private void initializeSubs() {
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder()
+                .setId(1)
+                .setIccId("subInfo1 IccId")
+                .setSimSlotIndex(0)
+                .setDisplayName("T-mobile")
+                .setCarrierName("T-mobile")
+                .setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER)
+                .setIconTint(255)
+                .setNumber("12345")
+                .setMcc("310")
+                .setMnc("260")
+                .setCountryIso("us")
+                .build();
 
-    private SubscriptionInfo mSubInfo3 = new SubscriptionInfo.Builder(mSubInfo1)
-            .setId(3)
-            .setIccId("subInfo3 IccId")
-            .setGroupUuid(mGroupUuid1.toString())
-            .build();
+        mSubInfo[2] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setId(2)
+                .setIccId("subInfo2 IccId")
+                .setSimSlotIndex(1)
+                .setGroupUuid(mGroupUuid1.toString())
+                .build();
 
-    private SubscriptionInfo mSubInfo4 = new SubscriptionInfo.Builder(mSubInfo1)
-            .setId(4)
-            .setIccId("subInfo4 IccId")
-            .setGroupUuid(mGroupUuid1.toString())
-            .build();
+        mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setId(3)
+                .setIccId("subInfo3 IccId")
+                .setSimSlotIndex(-1)
+                .setGroupUuid(mGroupUuid1.toString())
+                .build();
 
+        mSubInfo[4] = new SubscriptionInfoInternal.Builder(
+                mSubInfo[1])
+                .setId(4)
+                .setIccId("subInfo4 IccId")
+                .setSimSlotIndex(-1)
+                .setGroupUuid(mGroupUuid1.toString())
+                .build();
+    }
+
+    private void setSimSlotIndex(int subId, int simSlotIndex) {
+        mSubInfo[subId] = new SubscriptionInfoInternal.Builder(mSubInfo[subId])
+                .setSimSlotIndex(simSlotIndex).build();
+    }
+
+    private void sendCarrierConfigChanged(int phoneId, int subId) {
+        mCarrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+    }
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSubControllerMock = mock(SubscriptionController.class);
+        initializeSubs();
         mPhoneMock1 = mock(Phone.class);
         mPhoneMock2 = mock(Phone.class);
         mDataSettingsManagerMock1 = mock(DataSettingsManager.class);
         mDataSettingsManagerMock2 = mock(DataSettingsManager.class);
         mMockCi = mock(CommandsInterface.class);
-        mMockedIsub = mock(ISub.class);
 
-        doReturn(mMockedIsub).when(mIBinder).queryLocalInterface(anyString());
+        doReturn(mSubscriptionManagerService).when(mIBinder).queryLocalInterface(anyString());
         doReturn(mPhone).when(mPhone).getImsPhone();
         mServiceManagerMockedServices.put("isub", mIBinder);
 
+        doReturn(mSubscriptionManagerService).when(mIBinder)
+                .queryLocalInterface(anyString());
+
         // Default configuration:
         // DSDS device.
         // Sub 1 is the default sub.
         // Sub 1 is in slot 0; sub 2 is in slot 1.
         doReturn(DUAL_SIM).when(mTelephonyManager).getPhoneCount();
         doReturn(DUAL_SIM).when(mTelephonyManager).getActiveModemCount();
-        doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(1).when(mMockedIsub).getDefaultDataSubId();
-        doReturn(1).when(mSubControllerMock).getDefaultVoiceSubId();
-        doReturn(1).when(mMockedIsub).getDefaultVoiceSubId();
-        doReturn(1).when(mSubControllerMock).getDefaultSmsSubId();
-        doReturn(1).when(mMockedIsub).getDefaultSmsSubId();
-        doReturn(true).when(mSubControllerMock).isActiveSubId(1);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(0).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(0).when(mSubControllerMock).getPhoneId(1);
-        doReturn(0).when(mMockedIsub).getPhoneId(1);
-        doReturn(1).when(mSubControllerMock).getPhoneId(2);
-        doReturn(1).when(mMockedIsub).getPhoneId(2);
-        doReturn(true).when(mSubControllerMock).isOpportunistic(5);
-        doReturn(new SubscriptionInfo.Builder().setId(5).setSimSlotIndex(1).setOpportunistic(true)
-                .build()).when(mSubControllerMock).getSubscriptionInfo(5);
-        doReturn(1).when(mPhoneMock1).getSubId();
-        doReturn(2).when(mPhoneMock2).getSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultVoiceSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultSmsSubId();
         mPhoneMock1.mCi = mSimulatedCommands;
         mPhoneMock2.mCi = mSimulatedCommands;
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock)
-                .getActiveSubscriptionInfoList(anyString(), nullable(String.class));
-        doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mPhones = new Phone[] {mPhoneMock1, mPhoneMock2};
         doReturn(mDataSettingsManagerMock1).when(mPhoneMock1).getDataSettingsManager();
         doReturn(mDataSettingsManagerMock2).when(mPhoneMock2).getDataSettingsManager();
 
-        doReturn(Arrays.asList(mSubInfo1)).when(mSubControllerMock).getSubInfo(
-                eq(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1), any());
-        doReturn(Arrays.asList(mSubInfo2)).when(mSubControllerMock).getSubInfo(
-                eq(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2), any());
-        doReturn(Arrays.asList(mSubInfo3)).when(mSubControllerMock).getSubInfo(
-                eq(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 3), any());
-        doReturn(Arrays.asList(mSubInfo4)).when(mSubControllerMock).getSubInfo(
-                eq(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 4), any());
+        doAnswer(invocation -> {
+            final int subId = (int) invocation.getArguments()[0];
+            if (subId < 0 || subId >= mSubInfo.length) return null;
+            return mSubInfo[subId].toSubscriptionInfo();
+        }).when(mSubscriptionManagerService).getSubscriptionInfo(anyInt());
+
+        doAnswer(invocation -> {
+            final int subId = (int) invocation.getArguments()[0];
+            if (subId < 0 || subId >= mSubInfo.length) return null;
+            return mSubInfo[subId];
+        }).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+        doAnswer(invocation -> {
+            List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>();
+            for (int i = 1; i < mSubInfo.length; i++) {
+                if (mSubInfo[i] != null && mSubInfo[i].isActive()) {
+                    subscriptionInfoList.add(mSubInfo[i].toSubscriptionInfo());
+                }
+            }
+            return subscriptionInfoList;
+        }).when(mSubscriptionManagerService).getActiveSubscriptionInfoList(
+                anyString(), nullable(String.class));
+
+        doAnswer(invocation -> {
+            final boolean visibleOnly = (boolean) invocation.getArguments()[0];
+            List<Integer> subIdList = new ArrayList<>();
+            for (int i = 1; i < mSubInfo.length; i++) {
+                if (mSubInfo[i] != null && mSubInfo[i].isActive()
+                        && (!visibleOnly || mSubInfo[i].isVisible())) {
+                    subIdList.add(i);
+                }
+            }
+            return subIdList.stream().mapToInt(i -> i).toArray();
+        }).when(mSubscriptionManagerService).getActiveSubIdList(anyBoolean());
+
+        doAnswer(invocation -> {
+            final String uuid = (String) invocation.getArguments()[1];
+            List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>();
+            for (int i = 1; i < mSubInfo.length; i++) {
+                if (mSubInfo[i] != null && mSubInfo[i].getGroupUuid().equals(uuid)) {
+                    subscriptionInfoList.add(mSubInfo[i].toSubscriptionInfo());
+                }
+            }
+            return subscriptionInfoList;
+        }).when(mSubscriptionManagerService).getSubscriptionsInGroup(
+                any(), anyString(), nullable(String.class));
+
+        doAnswer(invocation -> {
+            final int subId = (int) invocation.getArguments()[0];
+            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+                return SubscriptionManager.INVALID_PHONE_INDEX;
+            }
+            if (mSubInfo[subId] == null) return SubscriptionManager.INVALID_PHONE_INDEX;
+            return mSubInfo[subId].getSimSlotIndex();
+        }).when(mSubscriptionManagerService).getPhoneId(anyInt());
+
+        doAnswer(invocation -> {
+            for (int i = 1; i < mSubInfo.length; i++) {
+                if (mSubInfo[i] != null && mSubInfo[i].getSimSlotIndex() == 0) return i;
+            }
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }).when(mPhoneMock1).getSubId();
+
+        doAnswer(invocation -> {
+            for (int i = 1; i < mSubInfo.length; i++) {
+                if (mSubInfo[i] != null && mSubInfo[i].getSimSlotIndex() == 1) return i;
+            }
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }).when(mPhoneMock2).getSubId();
 
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubControllerMock);
-        mMultiSimSettingControllerUT = new MultiSimSettingController(mContext, mSubControllerMock);
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+        mMultiSimSettingControllerUT = new MultiSimSettingController(mContext);
         processAllMessages();
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
+        assertNotNull(mCarrierConfigChangeListener);
     }
 
     @After
@@ -199,60 +265,55 @@
         super.tearDown();
     }
 
+    private void markSubscriptionInactive(int subId) {
+        setSimSlotIndex(subId, SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+    }
+
     @Test
     @SmallTest
     public void testSubInfoChangeBeforeAllSubReady() throws Exception {
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultDataSubId();
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultVoiceSubId();
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultSmsSubId();
 
         // Mark sub 2 as inactive.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        markSubscriptionInactive(2);
 
         // Mark subscription ready as false. The below sub info change should be ignored.
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultSmsSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt());
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(0, 1);
         processAllMessages();
 
         // Sub 1 should be default sub silently.
-        verify(mSubControllerMock).setDefaultDataSubId(1);
-        verify(mSubControllerMock).setDefaultVoiceSubId(1);
-        verify(mSubControllerMock).setDefaultSmsSubId(1);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(1);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(1);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(1);
         verifyDismissIntentSent();
     }
 
     @Test
     public void testSubInfoChangeAfterRadioUnavailable() throws Exception {
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
 
         // Ensure all subscription loaded only updates state once
-        clearInvocations(mSubControllerMock);
+        clearInvocations(mSubscriptionManagerService);
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultSmsSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt());
 
         // Notify radio unavailable.
         replaceInstance(BaseCommands.class, "mState", mSimulatedCommands,
@@ -261,95 +322,62 @@
                 MultiSimSettingController.EVENT_RADIO_STATE_CHANGED).sendToTarget();
 
         // Mark all subs as inactive.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(1);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock1).getSubId();
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = new ArrayList<>();
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
-        clearInvocations(mSubControllerMock);
+        markSubscriptionInactive(1);
+        markSubscriptionInactive(2);
+        clearInvocations(mSubscriptionManagerService);
 
         // The below sub info change should be ignored.
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
-        verify(mSubControllerMock, never()).setDefaultSmsSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultSmsSubId(anyInt());
 
         // Send all sub ready notification
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
         processAllMessages();
 
         // Everything should be set to invalid since nothing is active.
-        verify(mSubControllerMock).setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        verify(mSubControllerMock)
+        verify(mSubscriptionManagerService).setDefaultDataSubId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        verify(mSubscriptionManagerService)
                 .setDefaultVoiceSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        verify(mSubControllerMock).setDefaultSmsSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
 
     @Test
     @SmallTest
     public void testSingleActiveDsds() throws Exception {
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultDataSubId();
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultVoiceSubId();
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubControllerMock)
+        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mSubscriptionManagerService)
                 .getDefaultSmsSubId();
 
         // Mark sub 2 as inactive.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        markSubscriptionInactive(2);
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(0, 1);
         processAllMessages();
         verifyDismissIntentSent();
         clearInvocations(mContext);
 
         // Sub 1 should be default sub silently.
         // Sub 1 switches to sub 2 in the same slot.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(1);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(0).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(0).when(mSubControllerMock).getPhoneId(2);
-        doReturn(0).when(mMockedIsub).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(1);
-        doReturn(2).when(mPhoneMock1).getSubId();
-        infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        markSubscriptionInactive(1);
+        setSimSlotIndex(2, 0);
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 2);
+        sendCarrierConfigChanged(0, 2);
         processAllMessages();
 
         // Sub 1 should be default sub silently.
-        verify(mSubControllerMock).setDefaultDataSubId(2);
-        verify(mSubControllerMock).setDefaultVoiceSubId(2);
-        verify(mSubControllerMock).setDefaultSmsSubId(2);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(2);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(2);
         verifyDismissIntentSent();
     }
 
@@ -357,43 +385,26 @@
     @SmallTest
     public void testActivatingSecondSub() throws Exception {
         // Mark sub 2 as inactive.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        markSubscriptionInactive(2);
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(0, 1);
         processAllMessages();
 
         // Sub 1 should be default sub silently.
-        verify(mSubControllerMock).setDefaultDataSubId(1);
-        verify(mSubControllerMock).setDefaultVoiceSubId(1);
-        verify(mSubControllerMock).setDefaultSmsSubId(1);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(1);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(1);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(1);
         verifyDismissIntentSent();
 
         // Mark sub 2 as active in phone[1].
-        clearInvocations(mSubControllerMock);
+        setSimSlotIndex(2, 1);
+        clearInvocations(mSubscriptionManagerService);
         clearInvocations(mContext);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(1).when(mSubControllerMock).getPhoneId(2);
-        doReturn(1).when(mMockedIsub).getPhoneId(2);
-        doReturn(2).when(mPhoneMock2).getSubId();
-        infoList = Arrays.asList(mSubInfo1, mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        mSubInfo[2] = new SubscriptionInfoInternal.Builder().setId(2).setSimSlotIndex(1).build();
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
 
         // Intent should be broadcast to ask default data selection.
@@ -405,23 +416,11 @@
         clearInvocations(mContext);
         // Switch from sub 2 to sub 3 in phone[1]. This should again trigger default data selection
         // dialog.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(3);
-        doReturn(new SubscriptionInfo.Builder().setId(3).setSimSlotIndex(1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(3);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(2);
-        doReturn(1).when(mSubControllerMock).getPhoneId(3);
-        doReturn(3).when(mPhoneMock2).getSubId();
-        infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        markSubscriptionInactive(2);
+        setSimSlotIndex(3, 1);
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 3);
+        sendCarrierConfigChanged(1, 3);
         processAllMessages();
 
         // Intent should be broadcast to ask default data selection.
@@ -438,8 +437,8 @@
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
         // After initialization, sub 2 should have mobile data off.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
         verify(mDataSettingsManagerMock2).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
@@ -447,36 +446,32 @@
         // Enable on non-default sub should trigger setDefaultDataSubId.
         mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
         processAllMessages();
-        verify(mSubControllerMock).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(2);
 
         // Changing default data to sub 2 should trigger disabling data on sub 1.
-        doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(2).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
         mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
         processAllMessages();
         verify(mDataSettingsManagerMock1).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
 
-        doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(1).when(mSubControllerMock).getDefaultSmsSubId();
-        doReturn(2).when(mSubControllerMock).getDefaultVoiceSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultSmsSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultVoiceSubId();
 
         // Taking out SIM 1.
-        clearInvocations(mSubControllerMock);
-        doReturn(false).when(mSubControllerMock).isActiveSubId(1);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        clearInvocations(mSubscriptionManagerService);
+        markSubscriptionInactive(1);
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(
-                1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         processAllMessages();
-        verify(mSubControllerMock).setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        verify(mSubControllerMock).setDefaultSmsSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
+        sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        processAllMessages();
+
+        verify(mSubscriptionManagerService).setDefaultDataSubId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt());
 
         // Verify intent sent to select sub 2 as default for all types.
         Intent intent = captureBroadcastIntent();
@@ -490,15 +485,14 @@
     @SmallTest
     public void testSimpleDsdsFirstBoot() throws Exception {
         // at first boot default is not set
-        doReturn(-1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(-1).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(-1).when(mSubscriptionManagerService).getDefaultDataSubId();
 
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
         // After initialization, sub 2 should have mobile data off.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
         verify(mDataSettingsManagerMock1).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
@@ -515,8 +509,8 @@
                 intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, -1));
 
         // Setting default data should not trigger any more setDataEnabled().
-        doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(2).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
         mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
         processAllMessages();
         verify(mDataSettingsManagerMock1, times(1))
@@ -529,8 +523,7 @@
     @SmallTest
     public void testSimpleDsdsInSuW() throws Exception {
         // at first boot default is not set
-        doReturn(-1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(-1).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(-1).when(mSubscriptionManagerService).getDefaultDataSubId();
 
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
@@ -539,8 +532,8 @@
                 Settings.Global.DEVICE_PROVISIONED, 0);
         // After initialization, sub 2 should have mobile data off.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
         verify(mDataSettingsManagerMock1).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
@@ -558,24 +551,19 @@
     @Test
     @SmallTest
     public void testDsdsGrouping() throws Exception {
-        doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
         doReturn(false).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, true);
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 2, false);
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
 
         // Create subscription grouping.
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(2);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(3);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(4);
-        mSubInfo2 = new SubscriptionInfo.Builder(mSubInfo2).setSimSlotIndex(1).build();
-        mSubInfo3 = new SubscriptionInfo.Builder(mSubInfo3).setSimSlotIndex(-1).build();
-        mSubInfo4 = new SubscriptionInfo.Builder(mSubInfo4).setSimSlotIndex(-1).build();
-        doReturn(Arrays.asList(mSubInfo2, mSubInfo3, mSubInfo4)).when(mSubControllerMock)
+        doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo(), mSubInfo[3].toSubscriptionInfo(),
+                mSubInfo[4].toSubscriptionInfo())).when(mSubscriptionManagerService)
                 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
@@ -588,13 +576,12 @@
                 mContext, Settings.Global.DATA_ROAMING, 3, true));
         assertFalse(GlobalSettingsHelper.getBoolean(
                 mContext, Settings.Global.DATA_ROAMING, 4, true));
-        verify(mSubControllerMock).setDataRoaming(/*enable*/0, /*subId*/2);
+        verify(mSubscriptionManagerService).setDataRoaming(/*enable*/0, /*subId*/2);
         // No user selection needed, no intent should be sent.
         verify(mContext, never()).sendBroadcast(any());
 
         // Making sub 1 default data sub should result in disabling data on sub 2, 3, 4.
-        doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(1).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId();
         mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
         processAllMessages();
         verify(mDataSettingsManagerMock2).setDataEnabled(
@@ -610,25 +597,20 @@
 
         // Switch within group (from sub 2 to sub 3).
         // Default data and default sms should become subscription 3.
-        clearInvocations(mSubControllerMock);
-        doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(2).when(mMockedIsub).getDefaultDataSubId();
-        doReturn(2).when(mSubControllerMock).getDefaultSmsSubId();
-        doReturn(2).when(mMockedIsub).getDefaultSmsSubId();
-        doReturn(1).when(mSubControllerMock).getDefaultVoiceSubId();
-        doReturn(1).when(mMockedIsub).getDefaultVoiceSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        clearInvocations(mSubscriptionManagerService);
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultSmsSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultVoiceSubId();
+        setSimSlotIndex(3, 1);
+        markSubscriptionInactive(2);
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 3);
+        sendCarrierConfigChanged(1, 3);
         processAllMessages();
 
-        verify(mSubControllerMock).setDefaultDataSubId(3);
-        verify(mSubControllerMock).setDefaultSmsSubId(3);
-        verify(mSubControllerMock, never()).setDefaultVoiceSubId(anyInt());
+        verify(mSubscriptionManagerService).setDefaultDataSubId(3);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(3);
+        verify(mSubscriptionManagerService, never()).setDefaultVoiceSubId(anyInt());
         // No user selection needed, no intent should be sent.
         verify(mContext, never()).sendBroadcast(any());
     }
@@ -636,10 +618,8 @@
     @Test
     @SmallTest
     public void testCbrs() throws Exception {
-        replaceInstance(SubscriptionInfo.class, "mIsOpportunistic", mSubInfo1, true);
-        doReturn(true).when(mSubControllerMock).isOpportunistic(1);
-        doReturn(new SubscriptionInfo.Builder(mSubInfo1).setOpportunistic(true).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1]).setOpportunistic(1).build();
+
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 2, false);
@@ -647,28 +627,27 @@
         // Notify subscriptions ready. Sub 2 should become the default. But shouldn't turn off
         // data of oppt sub 1.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
-        verify(mSubControllerMock).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(2);
         verify(mDataSettingsManagerMock1, never()).setDataEnabled(
                 anyInt(), anyBoolean(), anyString());
         verifyDismissIntentSent();
 
-        clearInvocations(mSubControllerMock);
+        clearInvocations(mSubscriptionManagerService);
         clearInvocations(mDataSettingsManagerMock1);
         clearInvocations(mDataSettingsManagerMock2);
-        doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(2).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
         // Toggle data on sub 1 or sub 2. Nothing should happen as they are independent.
         mMultiSimSettingControllerUT.notifyUserDataEnabled(1, false);
         mMultiSimSettingControllerUT.notifyUserDataEnabled(1, true);
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
         mMultiSimSettingControllerUT.notifyUserDataEnabled(2, false);
         mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
         verify(mDataSettingsManagerMock1, never()).setDataEnabled(
                 eq(TelephonyManager.DATA_ENABLED_REASON_USER), anyBoolean(), anyString());
         verify(mDataSettingsManagerMock2, never()).setDataEnabled(
@@ -686,11 +665,8 @@
     @SmallTest
     public void testGroupedCbrs() throws Exception {
         // Mark sub 1 as opportunistic.
-        replaceInstance(SubscriptionInfo.class, "mIsOpportunistic", mSubInfo1, true);
-        replaceInstance(SubscriptionInfo.class, "mGroupUuid", mSubInfo1, mGroupUuid1);
-        doReturn(true).when(mSubControllerMock).isOpportunistic(1);
-        doReturn(new SubscriptionInfo.Builder(mSubInfo1).setOpportunistic(true).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setOpportunistic(1).setGroupUuid(mGroupUuid1.toString()).build();
         // Make opportunistic sub 1 and sub 2 data enabled.
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
@@ -698,16 +674,17 @@
 
         // Notify subscriptions ready. Sub 2 should become the default, as sub 1 is opportunistic.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
-        verify(mSubControllerMock).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(2);
 
         // Mark sub 2 as data off.
         doReturn(false).when(mPhoneMock2).isUserDataEnabled();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, false);
         // Group sub 1 with sub 2.
-        doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
+        doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo()))
+                .when(mSubscriptionManagerService)
                 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
@@ -731,42 +708,29 @@
     @SmallTest
     public void testGroupedPrimaryRemoved() throws Exception {
         // Create subscription grouping of subs 1 and 2.
-        replaceInstance(SubscriptionInfo.class, "mGroupUuid", mSubInfo1, mGroupUuid1);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(1);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(2);
-        doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setGroupUuid(mGroupUuid1.toString()).build();
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
 
         // Defaults not touched, sub 1 is already default.
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
 
         // Take out SIM 1.
-        clearInvocations(mSubControllerMock);
-        doReturn(false).when(mSubControllerMock).isActiveSubId(1);
-        doReturn(new SubscriptionInfo.Builder().setId(1).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(1);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(1);
-        doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock1).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        clearInvocations(mSubscriptionManagerService);
+        markSubscriptionInactive(1);
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(
-                0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        sendCarrierConfigChanged(0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         processAllMessages();
 
         // Sub 2 should be made the default sub silently.
-        verify(mSubControllerMock).setDefaultDataSubId(2);
-        verify(mSubControllerMock).setDefaultVoiceSubId(2);
-        verify(mSubControllerMock).setDefaultSmsSubId(2);
+        verify(mSubscriptionManagerService).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService).setDefaultVoiceSubId(2);
+        verify(mSubscriptionManagerService).setDefaultSmsSubId(2);
         verifyDismissIntentSent();
     }
 
@@ -779,21 +743,22 @@
     @Test
     @SmallTest
     public void testGroupedPrimarySubscriptions() throws Exception {
-        doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(1).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId();
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(false).when(mPhoneMock2).isUserDataEnabled();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, true);
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.DATA_ROAMING, 1, false);
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
 
         // Create subscription grouping.
-        replaceInstance(SubscriptionInfo.class, "mGroupUuid", mSubInfo1, mGroupUuid1);
-        doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setGroupUuid(mGroupUuid1.toString()).build();
+        doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo()))
+                .when(mSubscriptionManagerService).getSubscriptionsInGroup(any(), anyString(),
+                        nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -801,7 +766,7 @@
                 true, PHONE_PACKAGE);
         assertFalse(GlobalSettingsHelper.getBoolean(
                 mContext, Settings.Global.DATA_ROAMING, 2, true));
-        verify(mSubControllerMock).setDataRoaming(/*enable*/0, /*subId*/1);
+        verify(mSubscriptionManagerService).setDataRoaming(/*enable*/0, /*subId*/1);
 
         // Turning off user data on sub 1.
         doReturn(false).when(mPhoneMock1).isUserDataEnabled();
@@ -816,45 +781,34 @@
     public void testCarrierConfigLoading() throws Exception {
         doReturn(true).when(mPhoneMock1).isUserDataEnabled();
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
+        mSubInfo[2] = new SubscriptionInfoInternal.Builder(mSubInfo[2]).setGroupUuid("").build();
+        mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[3]).setGroupUuid("").build();
         // Sub 2 should have mobile data off, but it shouldn't happen until carrier configs are
         // loaded on both subscriptions.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
         processAllMessages();
         verify(mDataSettingsManagerMock2, never()).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(0, 1);
         processAllMessages();
         verify(mDataSettingsManagerMock2, never()).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
         verify(mDataSettingsManagerMock2).setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
 
         // Switch from sub 2 to sub 3 in phone[1].
-        clearInvocations(mSubControllerMock);
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(3);
-        doReturn(new SubscriptionInfo.Builder().setId(3).setSimSlotIndex(1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(3);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mMockedIsub).getPhoneId(2);
-        doReturn(1).when(mSubControllerMock).getPhoneId(3);
-        doReturn(1).when(mMockedIsub).getPhoneId(3);
-        doReturn(3).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
+        clearInvocations(mSubscriptionManagerService);
+        markSubscriptionInactive(2);
+        setSimSlotIndex(3, 1);
 
         // Nothing should happen until carrier config change is notified on sub 3.
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         processAllMessages();
         verify(mContext, never()).sendBroadcast(any());
 
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 3);
+        sendCarrierConfigChanged(1, 3);
         processAllMessages();
         // Intent should be broadcast to ask default data selection.
         Intent intent = captureBroadcastIntent();
@@ -868,26 +822,14 @@
     // b/146446143
     public void testGroupChangeOnInactiveSub_shouldNotMarkAsDefaultDataSub() throws Exception {
         // Make sub1 and sub3 as active sub.
-        doReturn(false).when(mSubControllerMock).isActiveSubId(2);
-        doReturn(new SubscriptionInfo.Builder().setId(2).setSimSlotIndex(-1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(2);
-        doReturn(true).when(mSubControllerMock).isActiveSubId(3);
-        doReturn(new SubscriptionInfo.Builder().setId(3).setSimSlotIndex(1).build())
-                .when(mSubControllerMock).getSubscriptionInfo(3);
-        doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
-        doReturn(1).when(mSubControllerMock).getPhoneId(3);
-        doReturn(1).when(mMockedIsub).getPhoneId(3);
-        doReturn(3).when(mPhoneMock2).getSubId();
-        List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
-        doReturn(Arrays.asList(mSubInfo2, mSubInfo3, mSubInfo4)).when(mSubControllerMock)
+        markSubscriptionInactive(2);
+        setSimSlotIndex(3, 1);
+        doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo(), mSubInfo[3].toSubscriptionInfo(),
+                mSubInfo[4].toSubscriptionInfo())).when(mSubscriptionManagerService)
                 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
 
         // Sub 3 and sub 2's mobile data are enabled, and sub 3 is the default data sub.
-        doReturn(3).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(3).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(3).when(mSubscriptionManagerService).getDefaultDataSubId();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, false);
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, true);
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 3, true);
@@ -896,18 +838,17 @@
         // Sub 2 should have mobile data off, but it shouldn't happen until carrier configs are
         // loaded on both subscriptions.
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 3);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 3);
         processAllMessages();
 
         // Mark sub3 as oppt and notify grouping
-        doReturn(true).when(mSubControllerMock).isOpportunistic(3);
-        doReturn(new SubscriptionInfo.Builder().setId(3).setSimSlotIndex(0).setOpportunistic(true)
-                .build()).when(mSubControllerMock).getSubscriptionInfo(3);
+        mSubInfo[3] = new SubscriptionInfoInternal.Builder(mSubInfo[3]).setOpportunistic(1).build();
+        setSimSlotIndex(3, 0);
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // Shouldn't mark sub 2 as default data, as sub 2 is in active.
-        verify(mSubControllerMock, never()).setDefaultDataSubId(2);
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(2);
     }
 
     @Test
@@ -919,10 +860,9 @@
         doReturn(true).when(mPhoneMock2).isUserDataEnabled();
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
         processAllMessages();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(0, 1);
         // Notify carrier config change on phone1 without specifying subId.
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         processAllMessages();
         // Nothing should happen as carrier config is not ready for sub 2.
         verify(mDataSettingsManagerMock2, never()).setDataEnabled(
@@ -930,13 +870,11 @@
 
         // Still notify carrier config without specifying subId2, but this time subController
         // and CarrierConfigManager have subId 2 active and ready.
-        doReturn(2).when(mSubControllerMock).getSubId(1);
-        doReturn(2).when(mMockedIsub).getSubId(1);
+        doReturn(2).when(mSubscriptionManagerService).getSubId(1);
         CarrierConfigManager cm = (CarrierConfigManager) mContext.getSystemService(
                 mContext.CARRIER_CONFIG_SERVICE);
         doReturn(new PersistableBundle()).when(cm).getConfigForSubId(2);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         processAllMessages();
         // This time user data should be disabled on phone1.
         verify(mDataSettingsManagerMock2).setDataEnabled(
@@ -983,15 +921,14 @@
     @Test
     @SmallTest
     public void testVoiceDataSmsAutoFallback() throws Exception {
-        doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(1).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(1).when(mSubscriptionManagerService).getDefaultDataSubId();
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0,1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(2, 3);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(2, 2);
         processAllMessages();
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
-        verify(mSubControllerMock, never()).getActiveSubInfoCountMax();
-        doReturn(2).when(mSubControllerMock).getActiveSubInfoCountMax();
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).getActiveSubInfoCountMax();
+        doReturn(2).when(mSubscriptionManagerService).getActiveSubInfoCountMax();
         mPhoneMock1.mCi = mMockCi;
         mPhoneMock2.mCi = mMockCi;
         doReturn(TelephonyManager.RADIO_POWER_ON).when(mMockCi).getRadioState();
@@ -1003,41 +940,39 @@
         doReturn(true).when(resources).getBoolean(
                 com.android.internal.R.bool.config_voice_data_sms_auto_fallback);
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0,1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
+        sendCarrierConfigChanged(0, 1);
+        sendCarrierConfigChanged(1, 2);
         processAllMessages();
-        verify(mSubControllerMock).getActiveSubInfoCountMax();
-        verify(mSubControllerMock).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService).getActiveSubInfoCountMax();
+        verify(mSubscriptionManagerService).setDefaultDataSubId(anyInt());
     }
 
     @Test
     public void onSubscriptionGroupChanged_hasActiveSubNotPartOfGroup() {
         // sub1 and sub2 are active subs already
         // Create a subscription group with only sub2
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(2);
-        doReturn(Arrays.asList(mSubInfo2)).when(mSubControllerMock)
+        doReturn(Arrays.asList(mSubInfo[2].toSubscriptionInfo())).when(mSubscriptionManagerService)
                 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // Default data is not modified as sub1 is active sub not part of this groupUuid
-        verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
+        verify(mSubscriptionManagerService, never()).setDefaultDataSubId(anyInt());
     }
 
     @Test
     public void onSubscriptionGroupChanged_allActiveSubArePartOfGroup() throws Exception {
-        doReturn(3).when(mSubControllerMock).getDefaultDataSubId();
-        doReturn(3).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(3).when(mSubscriptionManagerService).getDefaultDataSubId();
         // Create subscription grouping of subs 1 and 2.
-        replaceInstance(SubscriptionInfo.class, "mGroupUuid", mSubInfo1, mGroupUuid1);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(1);
-        doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(2);
+        mSubInfo[1] = new SubscriptionInfoInternal.Builder(mSubInfo[1])
+                .setGroupUuid(mGroupUuid1.toString()).build();
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 1, true);
-        doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
+        doReturn(Arrays.asList(mSubInfo[1].toSubscriptionInfo(), mSubInfo[2].toSubscriptionInfo()))
+                .when(mSubscriptionManagerService)
                 .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
 
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // Default data is set to sub1
-        verify(mSubControllerMock).setDefaultDataSubId(1);
+        verify(mSubscriptionManagerService).syncGroupedSetting(1);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationInfoTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationInfoTest.java
index a275bb8..8dc8ea7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationInfoTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationInfoTest.java
@@ -18,6 +18,7 @@
 
 import static junit.framework.Assert.assertEquals;
 
+import android.compat.testing.PlatformCompatChangeRule;
 import android.os.Parcel;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CellIdentityLte;
@@ -27,13 +28,21 @@
 
 import androidx.test.filters.SmallTest;
 
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 
 import java.util.Arrays;
 
 /** Unit tests for {@link NetworkRegistrationInfo}. */
 public class NetworkRegistrationInfoTest {
 
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
     @Test
     @SmallTest
     public void testParcel() {
@@ -87,4 +96,47 @@
         assertEquals(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING,
                 nri.getNetworkRegistrationState());
     }
+
+    @Test
+    @DisableCompatChanges({NetworkRegistrationInfo.RETURN_REGISTRATION_STATE_EMERGENCY})
+    public void testReturnRegistrationStateEmergencyDisabled() {
+        // LTE
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .build();
+
+        assertEquals(NetworkRegistrationInfo.REGISTRATION_STATE_DENIED, nri.getRegistrationState());
+
+        // NR
+        nri = new NetworkRegistrationInfo.Builder()
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
+                .build();
+
+        assertEquals(NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
+                nri.getRegistrationState());
+    }
+
+    @Test
+    @EnableCompatChanges({NetworkRegistrationInfo.RETURN_REGISTRATION_STATE_EMERGENCY})
+    public void testReturnRegistrationStateEmergencyEnabled() {
+        // LTE
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .build();
+
+        assertEquals(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY,
+                nri.getRegistrationState());
+
+        // NR
+        nri = new NetworkRegistrationInfo.Builder()
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY)
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
+                .build();
+
+        assertEquals(NetworkRegistrationInfo.REGISTRATION_STATE_EMERGENCY,
+                nri.getRegistrationState());
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index 20c5d87..ff696fc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -20,12 +20,12 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
-import android.content.Intent;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.IPowerManager;
@@ -50,7 +50,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -61,21 +60,10 @@
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-@Ignore("b/240911460")
 public class NetworkTypeControllerTest extends TelephonyTest {
-    // private constants copied over from NetworkTypeController
-    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_CHANNEL_CONFIG_NOTIF_CHANGED = 6;
-    private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10;
-    private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
-    private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
-
     private NetworkTypeController mNetworkTypeController;
     private PersistableBundle mBundle;
-    private DataNetworkControllerCallback mDataNetworkControllerCallback;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private IState getCurrentState() throws Exception {
         Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
@@ -89,11 +77,12 @@
         method.invoke(mNetworkTypeController);
     }
 
-    private void broadcastCarrierConfigs() {
-        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());
-        mContext.sendBroadcast(intent);
+    private void sendCarrierConfigChanged() {
+        if (mCarrierConfigChangeListener != null) {
+            mCarrierConfigChangeListener.onCarrierConfigChanged(mPhone.getPhoneId(),
+                    mPhone.getSubId(), TelephonyManager.UNKNOWN_CARRIER_ID,
+                    TelephonyManager.UNKNOWN_CARRIER_ID);
+        }
         processAllMessages();
     }
 
@@ -104,8 +93,8 @@
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
                 "connected_mmwave:5G_Plus,connected:5G,not_restricted_rrc_idle:5G,"
                         + "not_restricted_rrc_con:5G");
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
-        broadcastCarrierConfigs();
+        mBundle.putInt(CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
+        sendCarrierConfigChanged();
 
         replaceInstance(Handler.class, "mLooper", mDisplayInfoController, Looper.myLooper());
         doReturn(RadioAccessFamily.getRafFromNetworkType(
@@ -114,14 +103,14 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         doReturn(new int[] {0}).when(mServiceState).getCellBandwidths();
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
         processAllMessages();
-
-        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
-                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
-        verify(mDataNetworkController).registerDataNetworkControllerCallback(
-                dataNetworkControllerCallbackCaptor.capture());
-        mDataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue();
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
     }
 
     @After
@@ -169,7 +158,6 @@
     @Test
     public void testUpdateOverrideNetworkTypeNrSa() throws Exception {
         // not NR
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
         updateOverrideNetworkType();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
@@ -184,7 +172,6 @@
                 anyInt(), anyInt());
 
         updateOverrideNetworkType();
-
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
     }
@@ -192,7 +179,6 @@
     @Test
     public void testUpdateOverrideNetworkTypeNrSaMmwave() throws Exception {
         // not NR
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
         updateOverrideNetworkType();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
@@ -208,7 +194,6 @@
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
 
         updateOverrideNetworkType();
-
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
     }
@@ -237,7 +222,7 @@
         doReturn("test_patternShowAdvanced").when(mServiceState).getOperatorAlphaLongRaw();
         mBundle.putString(CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING,
                 ".*_patternShowAdvanced");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         updateOverrideNetworkType();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO,
                 mNetworkTypeController.getOverrideNetworkType());
@@ -262,9 +247,7 @@
     @Test
     public void testTransitionToCurrentStateLegacy() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_HSPAP).when(mServiceState).getDataNetworkType();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("legacy", getCurrentState().getName());
     }
@@ -272,10 +255,8 @@
     @Test
     public void testTransitionToCurrentStateRestricted() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("restricted", getCurrentState().getName());
     }
@@ -283,11 +264,10 @@
     @Test
     public void testTransitionToCurrentStateIdle() throws Exception {
         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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
@@ -299,11 +279,11 @@
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
         processAllMessages();
         assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
         setPhysicalLinkStatus(false);
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
@@ -315,28 +295,25 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
 
     @Test
     public void testTransitionToCurrentStateLteConnected() throws Exception {
         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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
@@ -347,14 +324,14 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
+
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
         setPhysicalLinkStatus(true);
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
@@ -367,27 +344,24 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
 
     @Test
     public void testTransitionToCurrentStateNrConnected() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -395,11 +369,10 @@
     @Test
     public void testTransitionToCurrentStateNrConnectedMmwave() 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();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
@@ -408,7 +381,6 @@
     public void testTransitionToCurrentStateNrConnectedMmwaveWithAdditionalBandAndNoMmwave()
             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_HIGH).when(mServiceState).getNrFrequencyRange();
         mBundle.putIntArray(CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY,
@@ -420,9 +392,10 @@
         List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
         lastPhysicalChannelConfigList.add(physicalChannelConfig);
         doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
@@ -431,7 +404,6 @@
     public void testTransitionToCurrentStateNrConnectedWithNoAdditionalBandAndNoMmwave()
             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_HIGH).when(mServiceState).getNrFrequencyRange();
         mBundle.putIntArray(CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY,
@@ -443,9 +415,10 @@
         List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
         lastPhysicalChannelConfigList.add(physicalChannelConfig);
         doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -453,13 +426,11 @@
     @Test
     public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapable() 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, 0);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
@@ -468,13 +439,17 @@
     public void testTransitionToCurrentStateNrConnectedWithPcoAndNoNrAdvancedCapable()
             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();
-        mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(false);
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        sendCarrierConfigChanged();
+
+        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
+                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
+        verify(mDataNetworkController).registerDataNetworkControllerCallback(
+                dataNetworkControllerCallbackCaptor.capture());
+        DataNetworkControllerCallback callback = dataNetworkControllerCallbackCaptor.getValue();
+        callback.onNrAdvancedCapableByPcoChanged(false);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -483,14 +458,17 @@
     public void testTransitionToCurrentStateNrConnectedWithWrongPcoAndNoNrAdvancedCapable()
             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, 0xFF00);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
-        mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(false);
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
+                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
+        verify(mDataNetworkController).registerDataNetworkControllerCallback(
+                dataNetworkControllerCallbackCaptor.capture());
+        DataNetworkControllerCallback callback = dataNetworkControllerCallbackCaptor.getValue();
+        callback.onNrAdvancedCapableByPcoChanged(false);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -499,15 +477,17 @@
     public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableAndPco()
             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();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(true);
+        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
+                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
+        verify(mDataNetworkController).registerDataNetworkControllerCallback(
+                dataNetworkControllerCallbackCaptor.capture());
+        DataNetworkControllerCallback callback = dataNetworkControllerCallbackCaptor.getValue();
+        callback.onNrAdvancedCapableByPcoChanged(true);
         processAllMessages();
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
@@ -515,10 +495,9 @@
     @Test
     public void testEventDataRatChanged() throws Exception {
         testTransitionToCurrentStateLegacy();
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
 
-        mNetworkTypeController.sendMessage(EVENT_DATA_RAT_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -528,7 +507,7 @@
         testTransitionToCurrentStateNrConnected();
         doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState();
 
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("restricted", getCurrentState().getName());
     }
@@ -539,9 +518,8 @@
         testTransitionToCurrentStateNrConnectedMmwave();
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
 
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals("connected", getCurrentState().getName());
     }
 
@@ -551,23 +529,20 @@
         testTransitionToCurrentStateNrConnected();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
 
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
 
     @Test
     public void testNrPhysicalChannelChangeFromNrConnectedMmwaveToLteConnected() throws Exception {
         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_NR_FREQUENCY_CHANGED);
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
-        processAllMessages();
 
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
+                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
 
@@ -579,19 +554,15 @@
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
         processAllMessages();
         testTransitionToCurrentStateNrConnectedMmwave();
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
         setPhysicalLinkStatus(true);
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         processAllMessages();
-
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
 
-
     @Test
     public void testUsingUserDataForRrcDetection_FromNrConnectedMmwaveToLteConnected()
             throws Exception {
@@ -600,34 +571,30 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         processAllMessages();
-
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
     }
 
     @Test
     public void testEventPhysicalChannelChangeFromLteToLteCaInLegacyState() throws Exception {
         testTransitionToCurrentStateLegacy();
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         updateOverrideNetworkType();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
 
         doReturn(true).when(mServiceState).isUsingCarrierAggregation();
         doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
                 mNetworkTypeController.getOverrideNetworkType());
     }
@@ -638,14 +605,13 @@
         mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
                 "connected_mmwave:5G_Plus,connected:5G");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         // 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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
@@ -654,9 +620,9 @@
         // LTE -> LTE+
         doReturn(true).when(mServiceState).isUsingCarrierAggregation();
         doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
                 mNetworkTypeController.getOverrideNetworkType());
     }
@@ -667,14 +633,13 @@
         mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
                 "connected_mmwave:5G_Plus,connected:5G");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         // 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,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
@@ -683,9 +648,9 @@
         // LTE -> LTE+
         doReturn(true).when(mServiceState).isUsingCarrierAggregation();
         doReturn(new int[] {30000}).when(mServiceState).getCellBandwidths();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA,
                 mNetworkTypeController.getOverrideNetworkType());
     }
@@ -694,11 +659,10 @@
     public void testEventPhysicalLinkStatusChanged() throws Exception {
         testTransitionToCurrentStateLteConnected();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
 
         processAllMessages();
-
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
 
@@ -712,10 +676,9 @@
         testTransitionToCurrentStateLteConnectedSupportPhysicalChannelConfig1_6();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
         setPhysicalLinkStatus(false);
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
-
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
-
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
 
@@ -727,15 +690,14 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         testTransitionToCurrentStateLteConnected_usingUserDataForRrcDetection();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
                 new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
 
         processAllMessages();
-
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
     }
 
@@ -745,7 +707,7 @@
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
 
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED,
+        mNetworkTypeController.sendMessage(5 /* EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED */,
                 new AsyncResult(null, false, null));
         processAllMessages();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
@@ -759,9 +721,7 @@
                 mNetworkTypeController.getOverrideNetworkType());
 
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
-
-        mNetworkTypeController.sendMessage(EVENT_RADIO_OFF_OR_UNAVAILABLE);
+        mNetworkTypeController.sendMessage(9 /* EVENT_RADIO_OFF_OR_UNAVAILABLE */);
         processAllMessages();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
@@ -778,7 +738,7 @@
                 TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA)).when(
                 mPhone).getCachedAllowedNetworkTypesBitmask();
 
-        mNetworkTypeController.sendMessage(EVENT_PREFERRED_NETWORK_MODE_CHANGED);
+        mNetworkTypeController.sendMessage(10 /* EVENT_PREFERRED_NETWORK_MODE_CHANGED */);
         processAllMessages();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
@@ -786,11 +746,10 @@
 
     @Test
     public void testPrimaryTimerExpire() 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();
+        sendCarrierConfigChanged();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -798,13 +757,13 @@
 
         // should trigger 10 second timer
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // timer expires
         moveTimeForward(10 * 1000);
@@ -813,23 +772,22 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @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();
+        sendCarrierConfigChanged();
 
         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*/);
+        mNetworkTypeController.sendMessage(12 /* EVENT_DEVICE_IDLE_MODE_CHANGED */);
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -837,22 +795,21 @@
 
         // should not trigger timer
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testPrimaryTimerReset() 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();
+        sendCarrierConfigChanged();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -860,17 +817,17 @@
 
         // trigger 10 second timer after disconnecting from NR
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // reconnect to NR in the middle of the timer
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         // timer expires
         moveTimeForward(10 * 1000);
@@ -880,16 +837,15 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @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();
+        sendCarrierConfigChanged();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -903,24 +859,23 @@
         // 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);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         // timer should be reset.
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testPrimaryTimerExpireMmwave() throws Exception {
-        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.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
@@ -928,13 +883,13 @@
 
         // should trigger 10 second timer
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // timer expires
         moveTimeForward(10 * 1000);
@@ -943,17 +898,16 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testPrimaryTimerResetMmwave() throws Exception {
-        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.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
@@ -961,17 +915,17 @@
 
         // trigger 10 second timer after disconnecting from NR
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // reconnect to NR in the middle of the timer
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         // timer expires
         moveTimeForward(10 * 1000);
@@ -981,18 +935,17 @@
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testSecondaryTimerExpire() 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");
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
                 "connected,any,30");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -1000,13 +953,13 @@
 
         // should trigger 10 second primary timer
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // primary timer expires
         moveTimeForward(10 * 1000);
@@ -1016,7 +969,7 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // secondary timer expires
         moveTimeForward(30 * 1000);
@@ -1025,18 +978,17 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testSecondaryTimerReset() 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");
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
                 "connected,any,30");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
@@ -1044,13 +996,13 @@
 
         // should trigger 10 second primary timer
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // primary timer expires
         moveTimeForward(10 * 1000);
@@ -1060,11 +1012,11 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // reconnect to NR in the middle of the timer
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         // secondary timer expires
         moveTimeForward(30 * 1000);
@@ -1074,19 +1026,18 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testSecondaryTimerExpireMmwave() throws Exception {
-        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.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,30");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
@@ -1094,13 +1045,13 @@
 
         // should trigger 10 second primary timer
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // primary timer expires
         moveTimeForward(10 * 1000);
@@ -1110,7 +1061,7 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // secondary timer expires
         moveTimeForward(30 * 1000);
@@ -1119,19 +1070,18 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testSecondaryTimerResetMmwave() throws Exception {
-        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.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,30");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
@@ -1139,13 +1089,13 @@
 
         // should trigger 10 second primary timer
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // primary timer expires
         moveTimeForward(10 * 1000);
@@ -1155,11 +1105,11 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // reconnect to NR in the middle of the timer
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
 
         // secondary timer expires
         moveTimeForward(30 * 1000);
@@ -1169,19 +1119,18 @@
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
     public void testNrTimerResetIn3g() throws Exception {
-        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.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
                 "connected_mmwave,any,30");
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
@@ -1189,13 +1138,13 @@
 
         // should trigger 10 second primary timer
         doReturn(ServiceState.FREQUENCY_RANGE_LOW).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertTrue(mNetworkTypeController.is5GHysteresisActive());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
 
         // rat is UMTS, should stop timer
         NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
@@ -1204,21 +1153,97 @@
                 .build();
         doReturn(nri).when(mServiceState).getNetworkRegistrationInfo(anyInt(), anyInt());
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_DATA_RAT_CHANGED);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
 
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
-    private void setPhysicalLinkStatus(Boolean state) {
+    @Test
+    public void testNrTimerResetWhenConnected() throws Exception {
+        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
+                "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
+        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
+                "connected_mmwave,any,30");
+        sendCarrierConfigChanged();
+
+        doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
+        mNetworkTypeController.sendMessage(4 /* EVENT_PHYSICAL_LINK_STATUS_CHANGED */,
+                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
+
+        assertEquals("not_restricted_rrc_con", getCurrentState().getName());
+        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
+                mNetworkTypeController.getOverrideNetworkType());
+
+        // should trigger 10 second primary timer
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
+
+        assertEquals("legacy", getCurrentState().getName());
+        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
+                mNetworkTypeController.getOverrideNetworkType());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
+
+        // rat is NR, should stop timer
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+                .build();
+        doReturn(nri).when(mServiceState).getNetworkRegistrationInfo(anyInt(), anyInt());
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
+
+        assertEquals("connected", getCurrentState().getName());
+        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
+                mNetworkTypeController.getOverrideNetworkType());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
+    }
+
+    @Test
+    public void testNrTimerResetWhenConnectedAdvanced() throws Exception {
+        testTransitionToCurrentStateNrConnectedMmwave();
+        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
+                "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
+        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING,
+                "connected_mmwave,any,30");
+        sendCarrierConfigChanged();
+
+        // should trigger 10 second primary timer
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange();
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
+
+        assertEquals("legacy", getCurrentState().getName());
+        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
+                mNetworkTypeController.getOverrideNetworkType());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
+
+        // not advanced, should not stop timer
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
+        processAllMessages();
+
+        assertEquals("connected", getCurrentState().getName());
+        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
+                mNetworkTypeController.getOverrideNetworkType());
+        assertTrue(mNetworkTypeController.areAnyTimersActive());
+    }
+
+    private void setPhysicalLinkStatus(boolean state) {
         List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
-        // If PhysicalChannelConfigList is empty, PhysicalLinkStatus is DcController
-        // .PHYSICAL_LINK_NOT_ACTIVE
-        // If PhysicalChannelConfigList is not empty, PhysicalLinkStatus is DcController
-        // .PHYSICAL_LINK_ACTIVE
+        // If PhysicalChannelConfigList is empty, PhysicalLinkStatus is
+        // DataCallResponse.LINK_STATUS_DORMANT
+        // If PhysicalChannelConfigList is not empty, PhysicalLinkStatus is
+        // DataCallResponse.LINK_STATUS_ACTIVE
 
         if (state) {
             PhysicalChannelConfig physicalChannelConfig = new PhysicalChannelConfig.Builder()
@@ -1233,14 +1258,13 @@
     @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();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
@@ -1248,47 +1272,13 @@
     @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();
-        List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
-        lastPhysicalChannelConfigList.add(new PhysicalChannelConfig.Builder()
-                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
-                .setCellBandwidthDownlinkKhz(20001)
-                .build());
-        doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
+        doReturn(new int[] {20001}).when(mServiceState).getCellBandwidths();
         mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected_mmwave", getCurrentState().getName());
-    }
-
-    @Test
-    public void testTransitionToCurrentStateNrConnectedWithHighBandwidthIncludingLte()
-            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();
-        List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
-        lastPhysicalChannelConfigList.add(new PhysicalChannelConfig.Builder()
-                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
-                .setCellBandwidthDownlinkKhz(20000)
-                .build());
-        lastPhysicalChannelConfigList.add(new PhysicalChannelConfig.Builder()
-                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                .setCellBandwidthDownlinkKhz(10000)
-                .build());
-        doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        mBundle.putBoolean(
-                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
-                true);
-        broadcastCarrierConfigs();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED */);
         processAllMessages();
         assertEquals("connected_mmwave", getCurrentState().getName());
     }
@@ -1296,14 +1286,13 @@
     @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();
+        sendCarrierConfigChanged();
 
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("connected", getCurrentState().getName());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
index 5771326..700a246 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
@@ -138,6 +138,27 @@
 
     @Test
     @SmallTest
+    public void testConfigureAndGetMaxActiveVoiceSubscriptions() throws Exception {
+        init(2);
+        assertEquals(1, mPcm.getStaticPhoneCapability().getMaxActiveVoiceSubscriptions());
+
+        PhoneCapability dualActiveVoiceSubCapability = new PhoneCapability.Builder(
+                PhoneCapability.DEFAULT_DSDS_CAPABILITY)
+                .setMaxActiveVoiceSubscriptions(2)
+                .build();
+
+        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
+        verify(mMockRadioConfig).getPhoneCapability(captor.capture());
+        Message msg = captor.getValue();
+        AsyncResult.forMessage(msg, dualActiveVoiceSubCapability, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertEquals(2, mPcm.getStaticPhoneCapability().getMaxActiveVoiceSubscriptions());
+    }
+
+    @Test
+    @SmallTest
     public void testSwitchMultiSimConfig_notDsdsCapable_shouldFail() throws Exception {
         init(1);
         assertEquals(PhoneCapability.DEFAULT_SSSS_CAPABILITY, mPcm.getStaticPhoneCapability());
@@ -199,9 +220,9 @@
 
         // Verify clearSubInfoRecord() and onSlotActiveStatusChange() are called for second phone,
         // and not for the first one
-        verify(mSubscriptionController).clearSubInfoRecord(1);
+        verify(mSubscriptionManagerService).markSubscriptionsInactive(1);
         verify(mMockCi1).onSlotActiveStatusChange(anyBoolean());
-        verify(mSubscriptionController, never()).clearSubInfoRecord(0);
+        verify(mSubscriptionManagerService, never()).markSubscriptionsInactive(0);
         verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
 
         // Verify onPhoneRemoved() gets called on MultiSimSettingController phone
@@ -229,28 +250,28 @@
             ex.)    object.set( 2 )   --> next call to object.get() will return 2
          */
 
-        // setup mocks for  VOICE mSubscriptionController. getter/setter
+        // setup mocks for  VOICE mSubscriptionManagerService. getter/setter
         doAnswer(invocation -> {
             Integer value = (Integer) invocation.getArguments()[0];
-            Mockito.when(mSubscriptionController.getDefaultVoiceSubId()).thenReturn(value);
+            Mockito.when(mSubscriptionManagerService.getDefaultVoiceSubId()).thenReturn(value);
             return null;
-        }).when(mSubscriptionController).setDefaultVoiceSubId(anyInt());
+        }).when(mSubscriptionManagerService).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());
+        mSubscriptionManagerService.setDefaultVoiceSubId(startingDefaultSubscriptionId);
+        assertEquals(startingDefaultSubscriptionId,
+                mSubscriptionManagerService.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.
+                mSubscriptionManagerService.getDefaultVoiceSubId());
+        // Now, when the user goes to place a CALL, they will be prompted on which sim to use.
     }
 
     /**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneFactoryTest.java
deleted file mode 100644
index d1aea03..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneFactoryTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 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.fail;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import org.junit.Test;
-
-public class PhoneFactoryTest {
-    @Test
-    @SmallTest
-    public void testBeforeMakePhone() {
-        try {
-            PhoneFactory.getDefaultPhone();
-            fail("Expecting IllegalStateException");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            PhoneFactory.getPhone(0);
-            fail("Expecting IllegalStateException");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            PhoneFactory.getPhones();
-            fail("Expecting IllegalStateException");
-        } catch (IllegalStateException e) {
-        }
-
-        try {
-            PhoneFactory.getNetworkFactory(0);
-            fail("Expecting IllegalStateException");
-        } catch (IllegalStateException e) {
-        }
-    }
-
-    //todo: add test for makeDefaultPhone(). will need some refactoring in PhoneFactory.
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index b7d2913..2f3bbf7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -562,6 +562,17 @@
         assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
     }
 
+    @Test
+    public void testFormatNumber_lowerCase() {
+        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "us"));
+        assertEquals("223-4567", PhoneNumberUtils.formatNumber("2234567", "us"));
+        assertEquals("011 86 10 8888 0000",
+                PhoneNumberUtils.formatNumber("011861088880000", "us"));
+        assertEquals("010 8888 0000", PhoneNumberUtils.formatNumber("01088880000", "cn"));
+        // formatNumber doesn't format alpha numbers, but keep them as they are.
+        assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "us"));
+    }
+
     /**
      * Tests ability to format phone numbers from Japan using the international format when the
      * current country is not Japan.
@@ -570,6 +581,9 @@
     @Test
     public void testFormatJapanInternational() {
         assertEquals("+81 90-6657-1180", PhoneNumberUtils.formatNumber("+819066571180", "US"));
+
+        // Again with lower case country code
+        assertEquals("+81 90-6657-1180", PhoneNumberUtils.formatNumber("+819066571180", "us"));
     }
 
     /**
@@ -582,8 +596,15 @@
         assertEquals("090-6657-0660", PhoneNumberUtils.formatNumber("09066570660", "JP"));
         assertEquals("090-6657-1180", PhoneNumberUtils.formatNumber("+819066571180", "JP"));
 
+        // Again with lower case country code
+        assertEquals("090-6657-0660", PhoneNumberUtils.formatNumber("09066570660", "jp"));
+        assertEquals("090-6657-1180", PhoneNumberUtils.formatNumber("+819066571180", "jp"));
+
+
         // US number should still be internationally formatted
         assertEquals("+1 650-555-1212", PhoneNumberUtils.formatNumber("+16505551212", "JP"));
+        // Again with lower case country code
+        assertEquals("+1 650-555-1212", PhoneNumberUtils.formatNumber("+16505551212", "jp"));
     }
 
     @SmallTest
@@ -600,6 +621,20 @@
         assertEquals("**650 2910000", PhoneNumberUtils.formatNumber("**650 2910000", "US"));
     }
 
+    // Same as testFormatNumber_LeadingStarAndHash but using lower case country code.
+    @Test
+    public void testFormatNumber_LeadingStarAndHash_countryCodeLowerCase() {
+        // Numbers with a leading '*' or '#' should be left unchanged.
+        assertEquals("*650 2910000", PhoneNumberUtils.formatNumber("*650 2910000", "us"));
+        assertEquals("#650 2910000", PhoneNumberUtils.formatNumber("#650 2910000", "us"));
+        assertEquals("*#650 2910000", PhoneNumberUtils.formatNumber("*#650 2910000", "us"));
+        assertEquals("#*650 2910000", PhoneNumberUtils.formatNumber("#*650 2910000", "us"));
+        assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "us"));
+        assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "us"));
+        assertEquals("##650 2910000", PhoneNumberUtils.formatNumber("##650 2910000", "us"));
+        assertEquals("**650 2910000", PhoneNumberUtils.formatNumber("**650 2910000", "us"));
+    }
+
     @SmallTest
     @Test
     public void testNormalizeNumber() {
@@ -641,59 +676,63 @@
                 PhoneNumberUtils.formatNumber("011861088880000", "", "GB"));
     }
 
+    // Same as testFormatDailabeNumber but using lower case country code.
+    @Test
+    public void testFormatDailabeNumber_countryCodeLowerCase() {
+        // Using the phoneNumberE164's country code
+        assertEquals("(650) 291-0000",
+                PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "cn"));
+        // Using the default country code for a phone number containing the IDD
+        assertEquals("011 86 10 8888 0000",
+                PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "us"));
+        assertEquals("00 86 10 8888 0000",
+                PhoneNumberUtils.formatNumber("00861088880000", "+861088880000", "gb"));
+        assertEquals("+86 10 8888 0000",
+                PhoneNumberUtils.formatNumber("+861088880000", "+861088880000", "gb"));
+        // Wrong default country, so no formatting is done
+        assertEquals("011861088880000",
+                PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "gb"));
+        // The phoneNumberE164 is null
+        assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "us"));
+        // The given number has a country code.
+        assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "cn"));
+        // The given number was formatted.
+        assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "us"));
+        // A valid Polish number should be formatted.
+        assertEquals("506 128 687", PhoneNumberUtils.formatNumber("506128687", null, "pl"));
+        // An invalid Polish number should be left as it is. Note Poland doesn't use '0' as a
+        // national prefix; therefore, the leading '0' makes the number invalid.
+        assertEquals("0506128687", PhoneNumberUtils.formatNumber("0506128687", null, "pl"));
+        // Wrong default country, so no formatting is done
+        assertEquals("011861088880000",
+                PhoneNumberUtils.formatNumber("011861088880000", "", "gb"));
+    }
+
     @FlakyTest
     @Test
     @Ignore
     public void testIsEmergencyNumber() {
-        // There are two parallel sets of tests here: one for the
-        // regular isEmergencyNumber() method, and the other for
-        // isPotentialEmergencyNumber().
-        //
         // (The difference is that isEmergencyNumber() will return true
         // only if the specified number exactly matches an actual
-        // emergency number, but isPotentialEmergencyNumber() will
-        // return true if the specified number simply starts with the
-        // same digits as any actual emergency number.)
+        // emergency number
 
         // Tests for isEmergencyNumber():
-        assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
-        assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
+        assertTrue(PhoneNumberUtils.isEmergencyNumber("911"));
+        assertTrue(PhoneNumberUtils.isEmergencyNumber("112"));
         // The next two numbers are not valid phone numbers in the US,
         // so do not count as emergency numbers (but they *are* "potential"
         // emergency numbers; see below.)
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345"));
         // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
         // in Singapore, as 911 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234"));
         // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
         // in Brazil, as 112 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567"));
         // A valid local phone number from Brazil shouldn't be classified as an emergency number in
         // Brazil.
-        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
-
-        // Tests for isPotentialEmergencyNumber():
-        // These first two are obviously emergency numbers:
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US"));
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US"));
-        // The next two numbers are not valid phone numbers in the US, but can be used to trick the
-        // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
-        // addressing that, they are also classified as "potential" emergency numbers in the US.
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
-        assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
-
-        // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
-        // in Singapore, as 911 is not an emergency number there.
-        // This test fails on devices that have ecclist property preloaded with 911.
-        // assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
-
-        // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
-        // in Brazil, as 112 is not an emergency number there.
-        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
-        // A valid local phone number from Brazil shouldn't be classified as an emergency number in
-        // Brazil.
-        assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR"));
+        assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345"));
     }
 
     @SmallTest
@@ -768,6 +807,22 @@
         assertFalse(PhoneNumberUtils.isInternationalNumber("011-613-966-94916", "AU"));
     }
 
+    // Same as testIsInternational but using lower case country code.
+    @Test
+    public void testIsInternational_countryCodeLowerCase() {
+        assertFalse(PhoneNumberUtils.isInternationalNumber("", "us"));
+        assertFalse(PhoneNumberUtils.isInternationalNumber(null, "us"));
+        assertFalse(PhoneNumberUtils.isInternationalNumber("+16505551212", "us"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("+16505551212", "uk"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("+16505551212", "jp"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("+86 10 8888 0000", "us"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("001-541-754-3010", "de"));
+        assertFalse(PhoneNumberUtils.isInternationalNumber("001-541-754-3010", "us"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("01161396694916", "us"));
+        assertTrue(PhoneNumberUtils.isInternationalNumber("011-613-966-94916", "us"));
+        assertFalse(PhoneNumberUtils.isInternationalNumber("011-613-966-94916", "au"));
+    }
+
     @SmallTest
     @Test
     public void testIsUriNumber() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
index 606bcec..00634a0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
@@ -16,13 +16,17 @@
 package com.android.internal.telephony;
 
 import static android.Manifest.permission.READ_PHONE_STATE;
+import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+import static android.telephony.TelephonyManager.APPTYPE_ISIM;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -31,17 +35,32 @@
 import android.app.PropertyInvalidatedCache;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
+import android.os.RemoteException;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.telephony.uicc.IsimUiccRecords;
+import com.android.internal.telephony.uicc.SIMRecords;
+import com.android.internal.telephony.uicc.UiccCardApplication;
+import com.android.internal.telephony.uicc.UiccPort;
+import com.android.internal.telephony.uicc.UiccProfile;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.List;
 
 public class PhoneSubInfoControllerTest extends TelephonyTest {
     private static final String FEATURE_ID = "myfeatureId";
+    private static final String PSI_SMSC_TEL1 = "tel:+91123456789";
+    private static final String PSI_SMSC_SIP1 = "sip:+1234567890@abc.pc.operetor1.com;user=phone";
+    private static final String PSI_SMSC_TEL2 = "tel:+91987654321";
+    private static final String PSI_SMSC_SIP2 = "sip:+19876543210@dcf.pc.operetor2.com;user=phone";
 
     private PhoneSubInfoController mPhoneSubInfoControllerUT;
     private AppOpsManager mAppOsMgr;
@@ -57,18 +76,15 @@
         PropertyInvalidatedCache.disableForTestMode();
         /* mPhone -> PhoneId: 0 -> SubId:0
            mSecondPhone -> PhoneId:1 -> SubId: 1*/
-        doReturn(0).when(mSubscriptionController).getPhoneId(eq(0));
-        doReturn(1).when(mSubscriptionController).getPhoneId(eq(1));
+        doReturn(0).when(mSubscriptionManagerService).getPhoneId(eq(0));
+        doReturn(1).when(mSubscriptionManagerService).getPhoneId(eq(1));
         doReturn(2).when(mTelephonyManager).getPhoneCount();
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        doReturn(true).when(mSubscriptionController).isActiveSubId(0, TAG, FEATURE_ID);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(1, TAG, FEATURE_ID);
+        doReturn(true).when(mSubscriptionManagerService).isActiveSubId(0, TAG, FEATURE_ID);
+        doReturn(true).when(mSubscriptionManagerService).isActiveSubId(1, TAG, FEATURE_ID);
         doReturn(new int[]{0, 1}).when(mSubscriptionManager)
                 .getCompleteActiveSubscriptionIdList();
 
-        mServiceManagerMockedServices.put("isub", mSubscriptionController);
-        doReturn(mSubscriptionController).when(mSubscriptionController)
-                .queryLocalInterface(anyString());
         doReturn(mContext).when(mSecondPhone).getContext();
 
         mAppOsMgr = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -922,4 +938,357 @@
         assertEquals("VM_SIM_1", mPhoneSubInfoControllerUT
                 .getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
-}
+
+    private void setUpInitials() {
+        UiccPort uiccPort1 = Mockito.mock(UiccPort.class);
+        UiccProfile uiccProfile1 = Mockito.mock(UiccProfile.class);
+        UiccCardApplication uiccCardApplication1 = Mockito.mock(UiccCardApplication.class);
+        SIMRecords simRecords1 = Mockito.mock(SIMRecords.class);
+        IsimUiccRecords isimUiccRecords1 = Mockito.mock(IsimUiccRecords.class);
+
+        doReturn(uiccPort1).when(mPhone).getUiccPort();
+        doReturn(uiccProfile1).when(uiccPort1).getUiccProfile();
+        doReturn(uiccCardApplication1).when(uiccProfile1).getApplicationByType(anyInt());
+        doReturn(simRecords1).when(uiccCardApplication1).getIccRecords();
+        doReturn(isimUiccRecords1).when(uiccCardApplication1).getIccRecords();
+        doReturn(PSI_SMSC_TEL1).when(simRecords1).getSmscIdentity();
+        doReturn(PSI_SMSC_TEL1).when(isimUiccRecords1).getSmscIdentity();
+
+        doReturn(mUiccPort).when(mSecondPhone).getUiccPort();
+        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+        doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords();
+        doReturn(PSI_SMSC_TEL2).when(mSimRecords).getSmscIdentity();
+        doReturn(PSI_SMSC_TEL2).when(mIsimUiccRecords).getSmscIdentity();
+    }
+
+    @Test
+    public void testGetSmscIdentityForTelUri() {
+        try {
+            setUpInitials();
+            assertEquals(PSI_SMSC_TEL1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_TEL1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_USIM).toString());
+            assertEquals(PSI_SMSC_TEL2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_TEL2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_USIM).toString());
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testGetSmscIdentityForSipUri() {
+        try {
+            UiccPort uiccPort1 = Mockito.mock(UiccPort.class);
+            UiccProfile uiccProfile1 = Mockito.mock(UiccProfile.class);
+            UiccCardApplication uiccCardApplication1 = Mockito.mock(UiccCardApplication.class);
+            SIMRecords simRecords1 = Mockito.mock(SIMRecords.class);
+            IsimUiccRecords isimUiccRecords1 = Mockito.mock(IsimUiccRecords.class);
+
+            doReturn(uiccPort1).when(mPhone).getUiccPort();
+            doReturn(uiccProfile1).when(uiccPort1).getUiccProfile();
+            doReturn(uiccCardApplication1).when(uiccProfile1).getApplicationByType(anyInt());
+            doReturn(simRecords1).when(uiccCardApplication1).getIccRecords();
+            doReturn(isimUiccRecords1).when(uiccCardApplication1).getIccRecords();
+            doReturn(PSI_SMSC_SIP1).when(simRecords1).getSmscIdentity();
+            doReturn(PSI_SMSC_SIP1).when(isimUiccRecords1).getSmscIdentity();
+
+            doReturn(mUiccPort).when(mSecondPhone).getUiccPort();
+            doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+            doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+            doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+            doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords();
+            doReturn(PSI_SMSC_SIP2).when(mSimRecords).getSmscIdentity();
+            doReturn(PSI_SMSC_SIP2).when(mIsimUiccRecords).getSmscIdentity();
+
+            assertEquals(PSI_SMSC_SIP1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_SIP1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_USIM).toString());
+            assertEquals(PSI_SMSC_SIP2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_SIP2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_USIM).toString());
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testGetSmscIdentityWithOutPermissions() {
+        setUpInitials();
+
+        //case 1: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
+        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+        try {
+            mPhoneSubInfoControllerUT.getSmscIdentity(0, APPTYPE_ISIM);
+            Assert.fail("expected Security Exception Thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("getSmscIdentity"));
+        }
+
+        try {
+            mPhoneSubInfoControllerUT.getSmscIdentity(1, APPTYPE_ISIM);
+            Assert.fail("expected Security Exception Thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("getSmscIdentity"));
+        }
+
+        try {
+            mPhoneSubInfoControllerUT.getSmscIdentity(0, APPTYPE_USIM);
+            Assert.fail("expected Security Exception Thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("getSmscIdentity"));
+        }
+
+        try {
+            mPhoneSubInfoControllerUT.getSmscIdentity(1, APPTYPE_USIM);
+            Assert.fail("expected Security Exception Thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("getSmscIdentity"));
+        }
+
+        //case 2: no READ_PRIVILEGED_PHONE_STATE
+        mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
+        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+
+        try {
+            assertEquals(PSI_SMSC_TEL1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_TEL1, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(0, APPTYPE_USIM).toString());
+            assertEquals(PSI_SMSC_TEL2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_ISIM).toString());
+            assertEquals(PSI_SMSC_TEL2, mPhoneSubInfoControllerUT
+                    .getSmscIdentity(1, APPTYPE_USIM).toString());
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testGetSimServiceTable() throws RemoteException {
+        String refSst = "1234567";
+        doReturn(mUiccPort).when(mPhone).getUiccPort();
+        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+        doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+        String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+        assertEquals(refSst, resultSst);
+    }
+
+    @Test
+    public void testGetSimServiceTableEmpty() throws RemoteException {
+        String refSst = null;
+        doReturn(mUiccPort).when(mPhone).getUiccPort();
+        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+        doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+        String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+        assertEquals(refSst, resultSst);
+    }
+
+    @Test
+    public void testGetSstWhenNoUiccPort() throws RemoteException {
+            String refSst = "1234567";
+            doReturn(null).when(mPhone).getUiccPort();
+            doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+            doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+            doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+            doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+            String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+            assertEquals(null, resultSst);
+    }
+
+    @Test
+    public void testGetSstWhenNoUiccProfile() throws RemoteException {
+        String refSst = "1234567";
+        doReturn(mUiccPort).when(mPhone).getUiccPort();
+        doReturn(null).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+        doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+        String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+        assertEquals(null, resultSst);
+    }
+
+    @Test
+    public void testGetSstWhenNoUiccApplication() throws RemoteException {
+        String refSst = "1234567";
+        doReturn(mUiccPort).when(mPhone).getUiccPort();
+        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(null).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+        doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+        String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+        assertEquals(null, resultSst);
+    }
+
+    @Test
+    public void testGetSimServiceTableWithOutPermissions() throws RemoteException {
+        String refSst = "1234567";
+        doReturn(mUiccPort).when(mPhone).getUiccPort();
+        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccCardApplicationIms).when(mUiccProfile).getApplicationByType(anyInt());
+        doReturn(mSimRecords).when(mUiccCardApplicationIms).getIccRecords();
+
+        doReturn(refSst).when(mSimRecords).getSimServiceTable();
+
+        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+        try {
+            mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt());
+            Assert.fail("expected Security Exception Thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("getSimServiceTable"));
+        }
+
+        mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
+        assertEquals(refSst, mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()));
+    }
+
+    @Test
+    public void getPrivateUserIdentity() {
+        String refImpi = "1234567890@example.com";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpi).when(mIsimUiccRecords).getIsimImpi();
+
+        doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOpNoThrow(
+                eq(AppOpsManager.OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER), anyInt(), eq(TAG),
+                eq(FEATURE_ID), nullable(String.class));
+
+        String impi = mPhoneSubInfoControllerUT.getImsPrivateUserIdentity(0, TAG, FEATURE_ID);
+        assertEquals(refImpi, impi);
+    }
+
+    @Test
+    public void getPrivateUserIdentity_NoPermission() {
+        String refImpi = "1234567890@example.com";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpi).when(mIsimUiccRecords).getIsimImpi();
+
+        try {
+            mPhoneSubInfoControllerUT.getImsPrivateUserIdentity(0, TAG, FEATURE_ID);
+            fail();
+        } catch (Exception ex) {
+            assertTrue(ex instanceof SecurityException);
+            assertTrue(ex.getMessage().contains("No permissions to the caller"));
+        }
+    }
+
+    @Test
+    public void getPrivateUserIdentity_InValidSubIdCheck() {
+        String refImpi = "1234567890@example.com";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpi).when(mIsimUiccRecords).getIsimImpi();
+
+        try {
+            mPhoneSubInfoControllerUT.getImsPrivateUserIdentity(-1, TAG, FEATURE_ID);
+            fail();
+        } catch (Exception ex) {
+            assertTrue(ex instanceof IllegalArgumentException);
+            assertTrue(ex.getMessage().contains("Invalid SubscriptionID"));
+        }
+    }
+
+    @Test
+    public void getImsPublicUserIdentities() {
+        String[] refImpuArray = new String[3];
+        refImpuArray[0] = "012345678";
+        refImpuArray[1] = "sip:test@verify.com";
+        refImpuArray[2] = "tel:+91987754324";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpuArray).when(mIsimUiccRecords).getIsimImpu();
+
+        List<Uri> impuList = mPhoneSubInfoControllerUT.getImsPublicUserIdentities(0, TAG,
+                FEATURE_ID);
+
+        assertNotNull(impuList);
+        assertEquals(refImpuArray.length, impuList.size());
+        assertEquals(impuList.get(0).toString(), refImpuArray[0]);
+        assertEquals(impuList.get(1).toString(), refImpuArray[1]);
+        assertEquals(impuList.get(2).toString(), refImpuArray[2]);
+    }
+
+    @Test
+    public void getImsPublicUserIdentities_InvalidImpu() {
+        String[] refImpuArray = new String[3];
+        refImpuArray[0] = null;
+        refImpuArray[2] = "";
+        refImpuArray[2] = "tel:+91987754324";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpuArray).when(mIsimUiccRecords).getIsimImpu();
+        List<Uri> impuList = mPhoneSubInfoControllerUT.getImsPublicUserIdentities(0, TAG,
+                FEATURE_ID);
+        assertNotNull(impuList);
+        // Null or Empty string cannot be converted to URI
+        assertEquals(refImpuArray.length - 2, impuList.size());
+    }
+
+    @Test
+    public void getImsPublicUserIdentities_IsimNotLoadedError() {
+        doReturn(null).when(mPhone).getIsimRecords();
+
+        try {
+            mPhoneSubInfoControllerUT.getImsPublicUserIdentities(0, TAG, FEATURE_ID);
+            fail();
+        } catch (Exception ex) {
+            assertTrue(ex instanceof IllegalStateException);
+            assertTrue(ex.getMessage().contains("ISIM is not loaded"));
+        }
+    }
+
+    @Test
+    public void getImsPublicUserIdentities_InValidSubIdCheck() {
+        try {
+            mPhoneSubInfoControllerUT.getImsPublicUserIdentities(-1, TAG, FEATURE_ID);
+            fail();
+        } catch (Exception ex) {
+            assertTrue(ex instanceof IllegalArgumentException);
+            assertTrue(ex.getMessage().contains("Invalid SubscriptionID"));
+        }
+    }
+
+    @Test
+    public void getImsPublicUserIdentities_NoReadPrivilegedPermission() {
+        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+        String[] refImpuArray = new String[3];
+        refImpuArray[0] = "012345678";
+        refImpuArray[1] = "sip:test@verify.com";
+        refImpuArray[2] = "tel:+91987754324";
+        doReturn(mIsimUiccRecords).when(mPhone).getIsimRecords();
+        doReturn(refImpuArray).when(mIsimUiccRecords).getIsimImpu();
+
+        List<Uri> impuList = mPhoneSubInfoControllerUT.getImsPublicUserIdentities(0, TAG,
+                FEATURE_ID);
+
+        assertNotNull(impuList);
+        assertEquals(refImpuArray.length, impuList.size());
+        assertEquals(impuList.get(0).toString(), refImpuArray[0]);
+        assertEquals(impuList.get(1).toString(), refImpuArray[1]);
+        assertEquals(impuList.get(2).toString(), refImpuArray[2]);
+        mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
+    }
+}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
index 21514ef..65ab664 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
@@ -19,14 +19,16 @@
 import static android.telephony.RadioAccessFamily.RAF_GSM;
 import static android.telephony.RadioAccessFamily.RAF_LTE;
 
+import static com.android.internal.telephony.ProxyController.EVENT_FINISH_RC_RESPONSE;
 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 com.android.internal.telephony.ProxyController.EVENT_TIMEOUT;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 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;
@@ -47,14 +49,11 @@
 @TestableLooper.RunWithLooper
 public class ProxyControllerTest extends TelephonyTest {
     // Mocked classes
-    Phone mPhone2;
-
     ProxyController mProxyController;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhone2 = mock(Phone.class);
         replaceInstance(ProxyController.class, "sProxyController", null, null);
         mProxyController = ProxyController.getInstance(mContext);
     }
@@ -101,12 +100,139 @@
         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)))
+        Message.obtain(
+                        mProxyController.mHandler,
+                        EVENT_START_RC_RESPONSE,
+                        new AsyncResult(
+                                null,
+                                null,
+                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
                 .sendToTarget();
         processAllMessages();
 
         assertFalse(mProxyController.isWakeLockHeld());
     }
+
+    @Test
+    @SmallTest
+    public void testWithNonPermanentExceptionOnRCResponse_WithExceptionOnFinishResponse()
+            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.RADIO_NOT_AVAILABLE)))
+                .sendToTarget();
+        processAllMessages();
+        assertTrue(mProxyController.isWakeLockHeld());
+        onFinishResponseWithException();
+    }
+
+    @Test
+    @SmallTest
+    public void testWithNonPermanentExceptionOnRCResponse_WithoutExceptionOnFinishResponse()
+            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, null))
+                .sendToTarget();
+        processAllMessages();
+        assertTrue(mProxyController.isWakeLockHeld());
+        onFinishResponseWithoutException();
+    }
+
+    @Test
+    @SmallTest
+    public void testOnRCResponseTimeout_WithExceptionOnFinishResponse() 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_TIMEOUT,
+                        new AsyncResult(
+                                null,
+                                null,
+                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
+                .sendToTarget();
+        processAllMessages();
+        onFinishResponseWithException();
+    }
+
+    private void onFinishResponseWithException() throws Exception {
+        replaceInstance(
+                ProxyController.class, "mRadioAccessFamilyStatusCounter", mProxyController, 1);
+        replaceInstance(ProxyController.class, "mTransactionFailed", mProxyController, true);
+        Message.obtain(
+                        mProxyController.mHandler,
+                        EVENT_FINISH_RC_RESPONSE,
+                        new AsyncResult(
+                                null,
+                                null,
+                                new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
+                .sendToTarget();
+        processAllMessages();
+        assertTrue(mProxyController.isWakeLockHeld());
+    }
+
+    private void onFinishResponseWithoutException() throws Exception {
+        replaceInstance(
+                ProxyController.class, "mRadioAccessFamilyStatusCounter", mProxyController, 1);
+        replaceInstance(ProxyController.class, "mTransactionFailed", mProxyController, false);
+        replaceInstance(
+                ProxyController.class, "mRadioCapabilitySessionId", mProxyController, 123456);
+        Message.obtain(
+                        mProxyController.mHandler,
+                        EVENT_FINISH_RC_RESPONSE,
+                        new AsyncResult(
+                                null, new RadioCapability(0, 123456, 0, 0, "test_modem", 0), null))
+                .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..2396d1d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -16,6 +16,12 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
+import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
+
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ALLOW_DATA;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE;
@@ -27,6 +33,7 @@
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DATA_REGISTRATION_STATE;
 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_DEVICE_IMEI;
 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;
@@ -90,6 +97,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 org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -120,12 +128,14 @@
 import android.net.ConnectivityManager;
 import android.net.InetAddresses;
 import android.net.LinkAddress;
+import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.IThermalService;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.WorkSource;
 import android.service.carrier.CarrierIdentifier;
 import android.telephony.AccessNetworkConstants;
@@ -172,6 +182,7 @@
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -183,8 +194,10 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -205,14 +218,16 @@
     private RadioDataProxy mDataProxy;
     private RadioNetworkProxy mNetworkProxy;
     private RadioSimProxy mSimProxy;
+    private RadioModemProxy mRadioModemProxy;
 
-    private HalVersion mRadioVersionV10 = new HalVersion(1, 0);
-    private HalVersion mRadioVersionV11 = new HalVersion(1, 1);
-    private HalVersion mRadioVersionV12 = new HalVersion(1, 2);
-    private HalVersion mRadioVersionV13 = new HalVersion(1, 3);
-    private HalVersion mRadioVersionV14 = new HalVersion(1, 4);
-    private HalVersion mRadioVersionV15 = new HalVersion(1, 5);
-    private HalVersion mRadioVersionV16 = new HalVersion(1, 6);
+    private Map<Integer, HalVersion> mHalVersionV10 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV11 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV12 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV13 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV14 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV15 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV16 = new HashMap<>();
+    private Map<Integer, HalVersion> mHalVersionV21 = new HashMap<>();
 
     private RIL mRILInstance;
     private RIL mRILUnderTest;
@@ -300,6 +315,7 @@
         mDataProxy = mock(RadioDataProxy.class);
         mNetworkProxy = mock(RadioNetworkProxy.class);
         mSimProxy = mock(RadioSimProxy.class);
+        mRadioModemProxy = mock(RadioModemProxy.class);
         try {
             TelephonyDevController.create();
         } catch (RuntimeException e) {
@@ -316,10 +332,11 @@
         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);
+        proxies.put(HAL_SERVICE_RADIO, null);
+        proxies.put(HAL_SERVICE_DATA, mDataProxy);
+        proxies.put(HAL_SERVICE_NETWORK, mNetworkProxy);
+        proxies.put(HAL_SERVICE_SIM, mSimProxy);
+        proxies.put(HAL_SERVICE_MODEM, mRadioModemProxy);
         mRILInstance = new RIL(context,
                 RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE),
                 Phone.PREFERRED_CDMA_SUBSCRIPTION, 0, proxies);
@@ -331,11 +348,24 @@
                 eq(RadioNetworkProxy.class), any());
         doReturn(mSimProxy).when(mRILUnderTest).getRadioServiceProxy(eq(RadioSimProxy.class),
                 any());
+        doReturn(mRadioModemProxy).when(mRILUnderTest).getRadioServiceProxy(
+                eq(RadioModemProxy.class), any());
         doReturn(false).when(mDataProxy).isEmpty();
         doReturn(false).when(mNetworkProxy).isEmpty();
         doReturn(false).when(mSimProxy).isEmpty();
+        doReturn(false).when(mRadioModemProxy).isEmpty();
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV10);
+            for (int service = RIL.MIN_SERVICE_IDX; service <= RIL.MAX_SERVICE_IDX; service++) {
+                mHalVersionV10.put(service, new HalVersion(1, 0));
+                mHalVersionV11.put(service, new HalVersion(1, 1));
+                mHalVersionV12.put(service, new HalVersion(1, 2));
+                mHalVersionV13.put(service, new HalVersion(1, 3));
+                mHalVersionV14.put(service, new HalVersion(1, 4));
+                mHalVersionV15.put(service, new HalVersion(1, 5));
+                mHalVersionV16.put(service, new HalVersion(1, 6));
+                mHalVersionV21.put(service, new HalVersion(2, 1));
+            }
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV10);
         } catch (Exception e) {
         }
     }
@@ -493,7 +523,7 @@
 
         // Make radio version 1.5 to support the operation.
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
 
@@ -531,7 +561,7 @@
 
         // Make radio version 1.5 to support the operation.
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
 
@@ -711,7 +741,7 @@
     public void testStartNetworkScanWithUnsupportedResponse() throws Exception {
         // Use Radio HAL v1.5
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
         NetworkScanRequest nsr = getNetworkScanRequestForTesting();
@@ -738,7 +768,7 @@
     public void testGetVoiceRegistrationStateWithUnsupportedResponse() throws Exception {
         // Use Radio HAL v1.5
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
         mRILUnderTest.getVoiceRegistrationState(obtainMessage());
@@ -773,7 +803,7 @@
     public void testGetDataRegistrationStateWithUnsupportedResponse() throws Exception {
         // Use Radio HAL v1.5
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
 
@@ -818,7 +848,7 @@
 
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
 
@@ -861,7 +891,7 @@
     public void testSendSMS_1_6() throws Exception {
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
         String smscPdu = "smscPdu";
@@ -893,7 +923,7 @@
     public void testSendSMSExpectMore_1_6() throws Exception {
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
         String smscPdu = "smscPdu";
@@ -912,7 +942,7 @@
     public void testSendCdmaSMS_1_6() throws Exception {
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
         byte[] pdu = "000010020000000000000000000000000000000000".getBytes();
@@ -928,7 +958,7 @@
     public void testSendCdmaSMSExpectMore_1_6() throws Exception {
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
         byte[] pdu = "000010020000000000000000000000000000000000".getBytes();
@@ -1251,7 +1281,7 @@
     @Test
     public void testIccCloseLogicalChannel() throws Exception {
         int channel = 1;
-        mRILUnderTest.iccCloseLogicalChannel(channel, obtainMessage());
+        mRILUnderTest.iccCloseLogicalChannel(channel, false, obtainMessage());
         verify(mRadioProxy).iccCloseLogicalChannel(mSerialNumberCaptor.capture(), eq(channel));
         verifyRILResponse(
                 mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_SIM_CLOSE_CHANNEL);
@@ -1475,7 +1505,7 @@
 
         // Make radio version 1.5 to support the operation.
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
         mRILUnderTest.getBarringInfo(obtainMessage());
@@ -2838,7 +2868,7 @@
 
         // Make radio version 1.5 to support the operation.
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
         mRILUnderTest.enableUiccApplications(false, obtainMessage());
@@ -2855,7 +2885,7 @@
 
         // Make radio version 1.5 to support the operation.
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV15);
         } catch (Exception e) {
         }
         mRILUnderTest.areUiccApplicationsEnabled(obtainMessage());
@@ -2902,7 +2932,7 @@
     public void testGetSlicingConfig() throws Exception {
         // Use Radio HAL v1.6
         try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
         } catch (Exception e) {
         }
         mRILUnderTest.getSlicingConfig(obtainMessage());
@@ -2910,4 +2940,31 @@
         verifyRILResponse_1_6(
                 mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_GET_SLICING_CONFIG);
     }
+
+    @Test
+    public void getImei() throws RemoteException {
+        try {
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV21);
+        } catch (Exception e) {
+            fail();
+        }
+        mRILUnderTest.getImei(obtainMessage());
+        verify(mRadioModemProxy, atLeast(1)).getImei(mSerialNumberCaptor.capture());
+        verifyRILResponse(mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_DEVICE_IMEI);
+    }
+
+    @Test
+    public void getImeiNotSupported() {
+        try {
+            replaceInstance(RIL.class, "mHalVersion", mRILUnderTest, mHalVersionV16);
+        } catch (Exception e) {
+            fail();
+        }
+        Message message = obtainMessage();
+        mRILUnderTest.getImei(message);
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertEquals(null, ar.result);
+        Assert.assertNotNull(ar.exception.getMessage());
+        Assert.assertEquals("REQUEST_NOT_SUPPORTED", ar.exception.getMessage());
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java b/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
index 6cbb1da..45acc40 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
@@ -18,6 +18,11 @@
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
 import android.os.PersistableBundle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
@@ -31,6 +36,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.concurrent.Executor;
 
 /** Tests for RatRatcheter. */
 public class RatRatcheterTest extends TelephonyTest {
@@ -41,6 +47,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
+        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
         mServiceState = new ServiceState();
     }
 
@@ -135,6 +142,7 @@
         ServiceState newSS = new ServiceState();
 
         mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
         mBundle.putStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES,
                 new String[]{"14,19"});
 
@@ -153,6 +161,7 @@
         ServiceState newSS = new ServiceState();
 
         mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
         mBundle.putStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, new String[]{});
 
         setNetworkRegistrationInfo(oldSS, TelephonyManager.NETWORK_TYPE_LTE_CA);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 3833f7d..379117c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
@@ -92,8 +93,10 @@
 
 import com.android.internal.R;
 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.metrics.ServiceStateStats;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccRecords;
@@ -105,12 +108,14 @@
 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.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 public class ServiceStateTrackerTest extends TelephonyTest {
     // Mocked classes
@@ -119,9 +124,12 @@
     private NetworkService mIwlanNetworkService;
     private INetworkService.Stub mIwlanNetworkServiceStub;
     private SubscriptionInfo mSubInfo;
+
+    private SubscriptionInfoInternal mSubInfoInternal;
     private ServiceStateStats mServiceStateStats;
 
     private CellularNetworkService mCellularNetworkService;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     // SST now delegates all signal strength operations to SSC
     // Add Mock SSC as the dependency to avoid NPE
@@ -179,7 +187,18 @@
             mSsc = new SignalStrengthController(mPhone);
             doReturn(mSsc).when(mPhone).getSignalStrengthController();
 
+            // Capture listener registered for ServiceStateTracker to emulate the carrier config
+            // change notification used later. In this test, it's the third one. The first one
+            // comes from RatRatcheter and the second one comes from SignalStrengthController.
+            ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener>
+                    listenerArgumentCaptor =
+                            ArgumentCaptor.forClass(
+                                    CarrierConfigManager.CarrierConfigChangeListener.class);
             sst = new ServiceStateTracker(mPhone, mSimulatedCommands);
+            verify(mCarrierConfigManager, atLeast(3)).registerCarrierConfigChangeListener(any(),
+                    listenerArgumentCaptor.capture());
+            mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(2);
+
             sst.setServiceStateStats(mServiceStateStats);
             doReturn(sst).when(mPhone).getServiceStateTracker();
             setReady(true);
@@ -226,8 +245,14 @@
         mIwlanNetworkService = Mockito.mock(NetworkService.class);
         mIwlanNetworkServiceStub = Mockito.mock(INetworkService.Stub.class);
         mSubInfo = Mockito.mock(SubscriptionInfo.class);
+        mSubInfoInternal = new SubscriptionInfoInternal.Builder().setId(1).build();
         mServiceStateStats = Mockito.mock(ServiceStateStats.class);
 
+        mContextFixture.putResource(R.string.kg_text_message_separator, " \u2014 ");
+
+        doReturn(mSubInfoInternal).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(anyInt());
+        doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
         mContextFixture.putResource(R.string.config_wwan_network_service_package,
                 "com.android.phone");
         mContextFixture.putResource(R.string.config_wlan_network_service_package,
@@ -241,6 +266,8 @@
 
         replaceInstance(ProxyController.class, "sProxyController", null, mProxyController);
         mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
         mBundle.putStringArray(
                 CarrierConfigManager.KEY_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});
 
@@ -251,6 +278,15 @@
                 // UMTS < GPRS < EDGE
                 new String[]{"3,1,2"});
 
+        mBundle.putBoolean(CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL,
+                false);
+
+        mBundle.putBoolean(CarrierConfigManager.KEY_RATCHET_NR_ADVANCED_BANDWIDTH_IF_RRC_IDLE_BOOL,
+                true);
+
+        doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+                TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
         mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
@@ -269,6 +305,11 @@
         waitUntilReady();
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
+        // Voice radio tech change will always trigger an update of
+        // phone object irrespective of this config
+        mContextFixture.putBooleanResource(
+                com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change, false);
+
         // Override SPN related resource
         mContextFixture.putResource(
                 com.android.internal.R.string.lockscreen_carrier_default,
@@ -333,10 +374,11 @@
                     15, /* SIGNAL_STRENGTH_GOOD */
                     30  /* SIGNAL_STRENGTH_GREAT */
                 });
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
+                true);
 
-        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
-        mContext.sendBroadcast(intent);
+        sendCarrierConfigUpdate(PHONE_ID);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
         logd("ServiceStateTrackerTest -Setup!");
@@ -464,30 +506,37 @@
     @Test
     @MediumTest
     public void testSetRadioPowerForReason() {
+        testSetRadioPowerForReason(TelephonyManager.RADIO_POWER_REASON_THERMAL);
+        testSetRadioPowerForReason(TelephonyManager.RADIO_POWER_REASON_NEARBY_DEVICE);
+        testSetRadioPowerForReason(TelephonyManager.RADIO_POWER_REASON_CARRIER);
+    }
+
+    private void testSetRadioPowerForReason(int reason) {
         // Radio does not turn on if off for other reason and not emergency call.
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
         assertTrue(sst.getRadioPowerOffReasons().isEmpty());
-        sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
-        assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+        sst.setRadioPowerForReason(false, false, false, false, reason);
+        assertTrue(sst.getRadioPowerOffReasons().contains(reason));
         assertTrue(sst.getRadioPowerOffReasons().size() == 1);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
-        sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_USER);
-        assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+        sst.setRadioPowerForReason(true, false, false, false,
+                TelephonyManager.RADIO_POWER_REASON_USER);
+        assertTrue(sst.getRadioPowerOffReasons().contains(reason));
         assertTrue(sst.getRadioPowerOffReasons().size() == 1);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
 
         // Radio power state reason is removed and radio turns on if turned on for same reason it
         // had been turned off for.
-        sst.setRadioPowerForReason(true, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
+        sst.setRadioPowerForReason(true, false, false, false, reason);
         assertTrue(sst.getRadioPowerOffReasons().isEmpty());
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
 
         // Turn radio off, then successfully turn radio on for emergency call.
-        sst.setRadioPowerForReason(false, false, false, false, Phone.RADIO_POWER_REASON_THERMAL);
-        assertTrue(sst.getRadioPowerOffReasons().contains(Phone.RADIO_POWER_REASON_THERMAL));
+        sst.setRadioPowerForReason(false, false, false, false, reason);
+        assertTrue(sst.getRadioPowerOffReasons().contains(reason));
         assertTrue(sst.getRadioPowerOffReasons().size() == 1);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
@@ -499,33 +548,83 @@
 
     @Test
     @MediumTest
-    public void testSetRadioPowerFromCarrier() {
+    public void testSetRadioPowerForMultipleReasons() {
+        assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
+        assertTrue(sst.getRadioPowerOffReasons().isEmpty());
+
+        // Turn off radio
+        turnRadioOffForReason(TelephonyManager.RADIO_POWER_REASON_USER, 1);
+        turnRadioOffForReason(TelephonyManager.RADIO_POWER_REASON_THERMAL, 2);
+        turnRadioOffForReason(TelephonyManager.RADIO_POWER_REASON_CARRIER, 3);
+        turnRadioOffForReason(TelephonyManager.RADIO_POWER_REASON_NEARBY_DEVICE, 4);
+
+        // Turn on radio
+        turnRadioOnForReason(TelephonyManager.RADIO_POWER_REASON_NEARBY_DEVICE, 3,
+                TelephonyManager.RADIO_POWER_OFF);
+        turnRadioOnForReason(TelephonyManager.RADIO_POWER_REASON_THERMAL, 2,
+                TelephonyManager.RADIO_POWER_OFF);
+        turnRadioOnForReason(TelephonyManager.RADIO_POWER_REASON_CARRIER, 1,
+                TelephonyManager.RADIO_POWER_OFF);
+        turnRadioOnForReason(TelephonyManager.RADIO_POWER_REASON_USER, 0,
+                TelephonyManager.RADIO_POWER_ON);
+    }
+
+    private void turnRadioOffForReason(int reason, int powerOffReasonSize) {
+        sst.setRadioPowerForReason(false, false, false, false, reason);
+        assertTrue(sst.getRadioPowerOffReasons().contains(reason));
+        assertTrue(sst.getRadioPowerOffReasons().size() == powerOffReasonSize);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
+    }
+
+    private void turnRadioOnForReason(int reason, int powerOffReasonSize,
+            int expectedRadioPowerState) {
+        sst.setRadioPowerForReason(true, false, false, false, reason);
+        assertFalse(sst.getRadioPowerOffReasons().contains(reason));
+        assertTrue(sst.getRadioPowerOffReasons().size() == powerOffReasonSize);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertTrue(mSimulatedCommands.getRadioState() == expectedRadioPowerState);
+    }
+
+    @Test
+    @MediumTest
+    public void testSetRadioPowerForReasonCarrier() {
         // Carrier disable radio power
-        sst.setRadioPowerFromCarrier(false);
+        sst.setRadioPowerForReason(false, false, false, false,
+                TelephonyManager.RADIO_POWER_REASON_CARRIER);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertFalse(mSimulatedCommands.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON);
-        assertTrue(sst.getDesiredPowerState());
+        assertFalse(sst.getDesiredPowerState());
         assertFalse(sst.getPowerStateFromCarrier());
+        assertTrue(sst.getRadioPowerOffReasons().contains(
+                TelephonyManager.RADIO_POWER_REASON_CARRIER));
+        assertTrue(sst.getRadioPowerOffReasons().size() == 1);
 
         // User toggle radio power will not overrides carrier settings
         sst.setRadioPower(true);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertFalse(mSimulatedCommands.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON);
-        assertTrue(sst.getDesiredPowerState());
+        assertFalse(sst.getDesiredPowerState());
         assertFalse(sst.getPowerStateFromCarrier());
+        assertTrue(sst.getRadioPowerOffReasons().contains(
+                TelephonyManager.RADIO_POWER_REASON_CARRIER));
+        assertTrue(sst.getRadioPowerOffReasons().size() == 1);
 
         // Carrier re-enable radio power
-        sst.setRadioPowerFromCarrier(true);
+        sst.setRadioPowerForReason(true, false, false, false,
+                TelephonyManager.RADIO_POWER_REASON_CARRIER);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
         assertTrue(sst.getDesiredPowerState());
         assertTrue(sst.getPowerStateFromCarrier());
+        assertTrue(sst.getRadioPowerOffReasons().isEmpty());
 
         // User toggle radio power off (airplane mode) and set carrier on
         sst.setRadioPower(false);
-        sst.setRadioPowerFromCarrier(true);
+        sst.setRadioPowerForReason(true, false, false, false,
+                TelephonyManager.RADIO_POWER_REASON_CARRIER);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertFalse(mSimulatedCommands.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON);
@@ -748,15 +847,10 @@
         verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
     }
 
-    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);
+    private void sendCarrierConfigUpdate(int phoneId) {
+        mCarrierConfigChangeListener.onCarrierConfigChanged(phoneId,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
     }
 
@@ -832,13 +926,15 @@
     @Test
     @MediumTest
     public void testUpdatePhoneType() {
+        String brandOverride = "spn from brand override";
+        doReturn(brandOverride).when(mUiccProfile).getOperatorBrandOverride();
         doReturn(false).when(mPhone).isPhoneTypeGsm();
         doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
         doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM).
                 getCdmaSubscriptionSource();
 
-        logd("Calling updatePhoneType");
         // switch to CDMA
+        logd("Calling updatePhoneType");
         sst.updatePhoneType();
 
         ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -883,7 +979,6 @@
         mSimulatedCommands.setVoiceRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
         mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
         mSimulatedCommands.notifyNetworkStateChanged();
-
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
         // verify if registered handler has message posted to it
@@ -1065,7 +1160,6 @@
         mSimulatedCommands.notifyNetworkStateChanged();
 
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
         // verify if registered handler has message posted to it
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
@@ -1189,7 +1283,7 @@
 
     @Test
     @MediumTest
-    public void testRegisterForVoiceRegStateOrRatChange() {
+    public void testRegisterForVoiceRegStateOrRatChange() throws Exception {
         NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
@@ -1197,14 +1291,17 @@
                 .build();
         sst.mSS.addNetworkRegistrationInfo(nri);
 
+        sst.mSS.setState(ServiceState.STATE_IN_SERVICE);
         sst.registerForVoiceRegStateOrRatChanged(mTestHandler, EVENT_VOICE_RAT_CHANGED, null);
 
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
         // Verify if message was posted to handler and value of result
         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
+        verify(mTestHandler)
+                .sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
         assertEquals(EVENT_VOICE_RAT_CHANGED, messageArgumentCaptor.getValue().what);
+
         assertEquals(new Pair<Integer, Integer>(ServiceState.STATE_IN_SERVICE,
                         ServiceState.RIL_RADIO_TECHNOLOGY_LTE),
                 ((AsyncResult)messageArgumentCaptor.getValue().obj).result);
@@ -1299,6 +1396,7 @@
         mSimulatedCommands.setDataRegState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
         mSimulatedCommands.notifyNetworkStateChanged();
 
+        waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(), 500, 200);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
         // verify if registered handler has message posted to it
@@ -1450,14 +1548,11 @@
 
     @Test
     @SmallTest
-    public void testSetPsNotifications() {
+    public void testSetPsNotifications() throws Exception {
         int subId = 1;
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
 
-        doReturn(mSubInfo).when(mSubscriptionController).getActiveSubscriptionInfo(
-                anyInt(), anyString(), nullable(String.class));
-
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         mContextFixture.putBooleanResource(
@@ -1468,6 +1563,9 @@
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
         mContextFixture.putResource(com.android.internal.R.string.RestrictedOnDataTitle, "test1");
+        // Make sure getState() condition returns in service, without this at logs at times found to
+        // be out of service
+        sst.mSS.setState(ServiceState.STATE_IN_SERVICE);
         sst.setNotification(ServiceStateTracker.PS_ENABLED);
         ArgumentCaptor<Notification> notificationArgumentCaptor =
                 ArgumentCaptor.forClass(Notification.class);
@@ -1483,12 +1581,10 @@
 
     @Test
     @SmallTest
-    public void testSetCsNotifications() {
+    public void testSetCsNotifications() throws Exception {
         int subId = 1;
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
-        doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1501,6 +1597,9 @@
 
         mContextFixture.putResource(com.android.internal.R.string.RestrictedOnAllVoiceTitle,
                 "test2");
+        // Make sure getState() condition returns in service, without this at logs at times found to
+        // be out of service
+        sst.mSS.setState(ServiceState.STATE_IN_SERVICE);
         sst.setNotification(ServiceStateTracker.CS_ENABLED);
         ArgumentCaptor<Notification> notificationArgumentCaptor =
                 ArgumentCaptor.forClass(Notification.class);
@@ -1516,12 +1615,10 @@
 
     @Test
     @SmallTest
-    public void testSetCsNormalNotifications() {
+    public void testSetCsNormalNotifications() throws Exception {
         int subId = 1;
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
-        doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1533,6 +1630,9 @@
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
         mContextFixture.putResource(com.android.internal.R.string.RestrictedOnNormalTitle, "test3");
+        // Make sure getState() condition returns in service, without this at logs at times found to
+        // be out of service
+        sst.mSS.setState(ServiceState.STATE_IN_SERVICE);
         sst.setNotification(ServiceStateTracker.CS_NORMAL_ENABLED);
         ArgumentCaptor<Notification> notificationArgumentCaptor =
                 ArgumentCaptor.forClass(Notification.class);
@@ -1548,12 +1648,10 @@
 
     @Test
     @SmallTest
-    public void testSetCsEmergencyNotifications() {
+    public void testSetCsEmergencyNotifications() throws Exception {
         int subId = 1;
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
-        doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1566,6 +1664,9 @@
 
         mContextFixture.putResource(com.android.internal.R.string.RestrictedOnEmergencyTitle,
                 "test4");
+        // Make sure mIsEmergencyOnly should be true, when setNotification notification type is
+        // CS_EMERGENCY_ENABLED notification
+        sst.mSS.setEmergencyOnly(true);
         sst.setNotification(ServiceStateTracker.CS_EMERGENCY_ENABLED);
         ArgumentCaptor<Notification> notificationArgumentCaptor =
                 ArgumentCaptor.forClass(Notification.class);
@@ -1588,6 +1689,9 @@
         int otherSubId = 2;
         sst.mSubId = otherSubId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
+        doReturn(new SubscriptionInfoInternal.Builder().setId(2).setOpportunistic(1)
+                .setGroupUuid("fb767ff3-a395-4a53-bb17-3f853ae0eb87").build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -2180,16 +2284,16 @@
     }
 
     @Test
-    public void testPhyChanBandwidthRatchetedOnPhyChanBandwidth() throws Exception {
+    public void testPhyChanBandwidthRatchetedOnPhyChanBandwidth() {
         // LTE Cell with bandwidth = 10000
         CellIdentityLte cellIdentity10 =
                 new CellIdentityLte(1, 1, 1, 1, new int[] {1, 2}, 10000, "1", "1", "test",
                         "tst", Collections.emptyList(), null);
 
         sendRegStateUpdateForLteCellId(cellIdentity10);
-        assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
+        assertArrayEquals(new int[]{10000}, sst.mSS.getCellBandwidths());
         sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
-        assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
+        assertArrayEquals(new int[]{10000, 5000}, sst.mSS.getCellBandwidths());
     }
 
     @Test
@@ -2201,7 +2305,43 @@
     }
 
     @Test
-    public void testPhyChanBandwidthResetsOnOos() throws Exception {
+    public void testNotifyServiceStateChangedOnPhysicalConfigUpdates() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
+                true);
+
+        // LTE Cell with bandwidth = 10000
+        CellIdentityLte cellIdentity11 =
+                new CellIdentityLte(1, 1, 1, 1, new int[] {1, 2}, 10000, "1", "1", "test",
+                        "tst", Collections.emptyList(), null);
+
+        sendRegStateUpdateForLteCellId(cellIdentity11);
+
+        // Notify Service State changed for BandWidth Change
+        sendPhyChanConfigChange(new int[] {10000, 40000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
+        verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
+
+        // Notify Service State changed for NR Connection Status: LTE -> NR
+        // with context id update
+        when(mPhone.getDataNetworkController().isInternetNetwork(eq(3))).thenReturn(true);
+        sendPhyChanConfigChange(new int[] {10000, 40000}, TelephonyManager.NETWORK_TYPE_NR, 1,
+                new int[][]{{0, 1}, {2, 3}});
+        verify(mPhone, times(2)).notifyServiceStateChanged(any(ServiceState.class));
+
+        // Service State changed is not notified since no change
+        when(mPhone.getDataNetworkController().isInternetNetwork(eq(3))).thenReturn(true);
+        sendPhyChanConfigChange(new int[] {10000, 40000}, TelephonyManager.NETWORK_TYPE_NR, 1,
+                new int[][]{{0, 1}, {2, 3}});
+        verify(mPhone, times(2)).notifyServiceStateChanged(any(ServiceState.class));
+
+        // Notify Service State changed for NR Connection Status: NR -> LTE
+        when(mPhone.getDataNetworkController().isInternetNetwork(eq(3))).thenReturn(true);
+        sendPhyChanConfigChange(new int[] {10000, 40000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
+        verify(mPhone, times(3)).notifyServiceStateChanged(any(ServiceState.class));
+    }
+
+    @Test
+    public void testPhyChanBandwidthResetsOnOos() {
         testPhyChanBandwidthRatchetedOnPhyChanBandwidth();
         LteVopsSupportInfo lteVopsSupportInfo =
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
@@ -2229,13 +2369,21 @@
 
     @Test
     public void testPhyChanBandwidthForNr() {
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
+                false);
         // NR Cell with bandwidth = 10000
         CellIdentityNr nrCi = new CellIdentityNr(
-                0, 0, 0, new int[] {}, "", "", 5, "", "", Collections.emptyList());
+                0, 0, 0, new int[]{10000}, "", "", 5, "", "", Collections.emptyList());
 
-        sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_NR, 0);
         sendRegStateUpdateForNrCellId(nrCi);
-        assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
+        // should ratchet for NR
+        sendPhyChanConfigChange(new int[] {10000, 5000}, TelephonyManager.NETWORK_TYPE_NR, 0);
+        assertArrayEquals(new int[]{10000, 5000}, sst.mSS.getCellBandwidths());
+
+        // should not ratchet for LTE
+        sendPhyChanConfigChange(new int[] {100}, TelephonyManager.NETWORK_TYPE_LTE, 0);
+        assertArrayEquals(new int[]{}, sst.mSS.getCellBandwidths());
     }
 
     /**
@@ -2332,6 +2480,9 @@
     public void testLocaleTrackerUpdateWithIWLANInService() {
         // Start state: Cell data only LTE + IWLAN
         final String[] OpNamesResult = new String[] { "carrier long", "carrier", "310310" };
+        // Clear invocations for mLocaleTracker as precondition before test case execution & as part
+        // test setup
+        Mockito.clearInvocations(mLocaleTracker);
         changeRegStateWithIwlanOperatorNumeric(NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                 TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, OpNamesResult, true);
@@ -2414,7 +2565,7 @@
 
     @Test
     @SmallTest
-    public void testGetMdn() throws Exception {
+    public void testGetMdn() {
         doReturn(false).when(mPhone).isPhoneTypeGsm();
         doReturn(false).when(mPhone).isPhoneTypeCdma();
         doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
@@ -2715,13 +2866,20 @@
     @Test
     public void testUpdateSpnDisplay_spnNotEmptyAndCrossSimCallingEnabled_showSpnOnly() {
         // GSM phone
-
         doReturn(true).when(mPhone).isPhoneTypeGsm();
+        final CellIdentityLte cellIdentityLte =
+                new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
+                        "tst", Collections.emptyList(), null);
 
         // In Service
         ServiceState ss = new ServiceState();
         ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
         ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
+        //To By Pass RatRacheter
+        ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                cellIdentityLte, true));
         sst.mSS = ss;
 
         // cross-sim-calling is enable
@@ -2750,11 +2908,19 @@
     public void testUpdateSpnDisplay_spnNotEmptyAndWifiCallingEnabled_showSpnOnly() {
         // GSM phone
         doReturn(true).when(mPhone).isPhoneTypeGsm();
+        final CellIdentityLte cellIdentityLte =
+                new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
+                        "tst", Collections.emptyList(), null);
 
         // In Service
         ServiceState ss = new ServiceState();
         ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
         ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
+        //To By Pass RatRacheter
+        ss.addNetworkRegistrationInfo(makeNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                cellIdentityLte, true));
         sst.mSS = ss;
 
         // wifi-calling is enabled
@@ -2779,7 +2945,7 @@
     public void testUpdateSpnDisplay_spnEmptyAndWifiCallingEnabled_showPlmnOnly() {
         // set empty service provider name
         mBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, "");
-        sendCarrierConfigUpdate();
+        sendCarrierConfigUpdate(PHONE_ID);
 
         // GSM phone
         doReturn(true).when(mPhone).isPhoneTypeGsm();
@@ -2859,7 +3025,7 @@
     public void testUpdateSpnDisplayLegacy_WlanServiceNoWifiCalling_displayOOS() {
         mBundle.putBoolean(
                 CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, false);
-        sendCarrierConfigUpdate();
+        sendCarrierConfigUpdate(PHONE_ID);
 
         // GSM phone
         doReturn(true).when(mPhone).isPhoneTypeGsm();
@@ -2991,6 +3157,7 @@
     @Test
     public void testGetCombinedRegState() {
         doReturn(mImsPhone).when(mPhone).getImsPhone();
+        doReturn(true).when(mPhone).isPhoneTypeGsm();
 
         // If voice/data out of service, return out of service.
         doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
@@ -3030,4 +3197,35 @@
         doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getState();
         assertEquals(ServiceState.STATE_EMERGENCY_ONLY, sst.getCombinedRegState(mServiceState));
     }
+
+
+    @Test
+    public void testOnChangingPreferredOnIwlan() throws Exception {
+        Field callbackField =
+                ServiceStateTracker.class.getDeclaredField("mAccessNetworksManagerCallback");
+        callbackField.setAccessible(true);
+        AccessNetworksManager.AccessNetworksManagerCallback accessNetworksManagerCallback =
+                (AccessNetworksManager.AccessNetworksManagerCallback) callbackField.get(sst);
+
+        when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(false);
+
+        // Start state: Cell data only LTE + IWLAN
+        CellIdentityLte cellIdentity =
+                new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
+                        "tst", Collections.emptyList(), null);
+        changeRegStateWithIwlan(
+                // WWAN
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, cellIdentity,
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyManager.NETWORK_TYPE_LTE,
+                // WLAN
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                TelephonyManager.NETWORK_TYPE_IWLAN);
+        assertFalse(sst.mSS.isIwlanPreferred());
+
+        when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(true);
+        accessNetworksManagerCallback.onPreferredTransportChanged(0);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+        assertTrue(sst.mSS.isIwlanPreferred());
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
index 50a1b96..b2f118d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
@@ -18,20 +18,23 @@
 
 import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP;
 import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI;
+import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP;
 import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.reset;
 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;
@@ -47,6 +50,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SignalStrengthUpdateRequest;
 import android.telephony.SignalThresholdInfo;
+import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -91,16 +95,13 @@
 
     private SignalStrengthController mSsc;
     private PersistableBundle mBundle;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     @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());
 
         // Config a fixed supported RAN/MeasurementTypes to make the test more stable
         mBundle = mContextFixture.getCarrierConfigBundle();
@@ -112,6 +113,7 @@
                         -97, /* SIGNAL_STRENGTH_GOOD */
                         -89,  /* SIGNAL_STRENGTH_GREAT */
                 });
+        mBundle.putInt(CarrierConfigManager.KEY_GERAN_RSSI_HYSTERESIS_DB_INT, 6);
         // Support EUTRAN with RSRP
         mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT,
                 1 /* USE_RSRP */);
@@ -122,6 +124,7 @@
                         -95, /* SIGNAL_STRENGTH_GOOD */
                         -85,  /* SIGNAL_STRENGTH_GREAT */
                 });
+        mBundle.putInt(CarrierConfigManager.KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT, 3);
         // Support NR with SSRSRP
         mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
                 1 /* USE_SSRSRP */);
@@ -132,6 +135,7 @@
                         -80, /* SIGNAL_STRENGTH_GOOD */
                         -64,  /* SIGNAL_STRENGTH_GREAT */
                 });
+        mBundle.putInt(CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT, 1);
         // By default, NR with SSRSRQ and SSSINR is not supported
         mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
                 new int[] {
@@ -147,6 +151,18 @@
                         15, /* SIGNAL_STRENGTH_GOOD */
                         30  /* SIGNAL_STRENGTH_GREAT */
                 });
+
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+        mSsc = new SignalStrengthController(mPhone);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
+
+        replaceInstance(Handler.class, "mLooper", mHandler, mSsc.getLooper());
+        replaceInstance(Phone.class, "mLooper", mPhone, mSsc.getLooper());
+
         processAllMessages();
         reset(mSimulatedCommandsVerifier);
     }
@@ -505,6 +521,212 @@
     }
 
     @Test
+    public void testSetMinimumHysteresisDb_FromThresholdDelta() {
+        final int[] consolidatedThresholdList = new int[] {-120, -116, -113, -112};
+
+        SignalThresholdInfo info =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setThresholds(new int[] {-113}, true)
+                        .setHysteresisDb(2)
+                        .build();
+        SignalStrengthUpdateRequest request =
+                createTestSignalStrengthUpdateRequest(
+                        info,
+                        false /* shouldReportWhileIdle*/,
+                        false /* shouldReportSystemWhileIdle */);
+        mSsc.setSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+
+        int minHysteresis =
+                mSsc.getMinimumHysteresisDb(true,
+                        AccessNetworkConstants.AccessNetworkType.GERAN,
+                        SIGNAL_MEASUREMENT_TYPE_RSSI,
+                        consolidatedThresholdList);
+        assertEquals(1, minHysteresis);
+        mSsc.clearSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+    }
+
+    @Test
+    public void testSetMinimumHysteresisDb_FromSignalThresholdRequest() {
+        final int[] consolidatedThresholdList = new int[] {-120, -116, -112, -108};
+
+        SignalThresholdInfo info =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SIGNAL_MEASUREMENT_TYPE_RSRP)
+                        .setThresholds(new int[] {-113}, true)
+                        .setHysteresisDb(3)
+                        .build();
+        SignalStrengthUpdateRequest request =
+                createTestSignalStrengthUpdateRequest(
+                        info,
+                        false /* shouldReportWhileIdle*/,
+                        false /* shouldReportSystemWhileIdle */);
+        mSsc.setSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+
+        int minHysteresis =
+                mSsc.getMinimumHysteresisDb(true,
+                        AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                        SIGNAL_MEASUREMENT_TYPE_RSRP,
+                        consolidatedThresholdList);
+        assertEquals(3, minHysteresis);
+
+        mSsc.clearSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+    }
+
+    @Test
+    public void testSetMinimumHysteresisDb_FromCarrierConfig() {
+        final int[] consolidatedThresholdList = new int[] {-120, -115, -108, -103};
+
+        SignalThresholdInfo info =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(SIGNAL_MEASUREMENT_TYPE_SSRSRP)
+                        .setThresholds(new int[] {-113}, true)
+                        .setHysteresisDb(6)
+                        .build();
+        SignalStrengthUpdateRequest request =
+                createTestSignalStrengthUpdateRequest(
+                        info,
+                        false /* shouldReportWhileIdle*/,
+                        false /* shouldReportSystemWhileIdle */);
+        mSsc.setSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+
+        int minHysteresis =
+                mSsc.getMinimumHysteresisDb(true,
+                        AccessNetworkConstants.AccessNetworkType.NGRAN,
+                        SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                        consolidatedThresholdList);
+        assertEquals(1, minHysteresis);
+        mSsc.clearSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+    }
+
+    @Test
+    public void testSetHysteresisDb_WithCarrierConfigValue() {
+        when(mPhone.isDeviceIdle()).thenReturn(true);
+        when(mPhone.getSubId()).thenReturn(ACTIVE_SUB_ID);
+
+        mBundle.putInt(CarrierConfigManager.KEY_GERAN_RSSI_HYSTERESIS_DB_INT, 5);
+        mBundle.putInt(CarrierConfigManager.KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT, 3);
+        mBundle.putInt(CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT, 2);
+        sendCarrierConfigUpdate();
+
+        ArgumentCaptor<List<SignalThresholdInfo>> signalThresholdInfoCaptor =
+                ArgumentCaptor.forClass(List.class);
+        verify(mSimulatedCommandsVerifier, atLeastOnce())
+                .setSignalStrengthReportingCriteria(signalThresholdInfoCaptor.capture(), isNull());
+        List<SignalThresholdInfo> capturedInfos = signalThresholdInfoCaptor.getAllValues().get(0);
+        assertThat(capturedInfos).isNotEmpty();
+
+        for (SignalThresholdInfo signalThresholdInfo : capturedInfos) {
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_RSRP) {
+                assertEquals(3, signalThresholdInfo.getHysteresisDb());
+            }
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_RSSI) {
+                assertEquals(5, signalThresholdInfo.getHysteresisDb());
+            }
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_SSRSRP) {
+                assertEquals(2, signalThresholdInfo.getHysteresisDb());
+            }
+        }
+        reset(mSimulatedCommandsVerifier);
+    }
+
+    @Test
+    public void testSetHysteresisDb_BetweenCarrierConfigSignalThresholdInfoThresholdDelta() {
+        SignalThresholdInfo info =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(SIGNAL_MEASUREMENT_TYPE_SSRSRP)
+                        .setThresholds(new int[] {-116}, true)
+                        .setHysteresisDb(3)
+                        .build();
+        SignalStrengthUpdateRequest request =
+                createTestSignalStrengthUpdateRequest(
+                        info,
+                        false /* shouldReportWhileIdle*/,
+                        false /* shouldReportSystemWhileIdle */);
+        mSsc.setSignalStrengthUpdateRequest(
+                ACTIVE_SUB_ID, CALLING_UID, request, Message.obtain(mHandler));
+        processAllMessages();
+
+        reset(mSimulatedCommandsVerifier);
+        when(mPhone.isDeviceIdle()).thenReturn(false);
+        when(mPhone.getSubId()).thenReturn(ACTIVE_SUB_ID);
+        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
+                new int[] {
+                        -113, /* SIGNAL_STRENGTH_POOR */
+                        -107, /* SIGNAL_STRENGTH_MODERATE */
+                        -100, /* SIGNAL_STRENGTH_GOOD */
+                        -95,  /* SIGNAL_STRENGTH_GREAT */
+                });
+
+        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+                1 /* USE_SSRSRP */);
+        mBundle.putInt(CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT, 4);
+        sendCarrierConfigUpdate();
+
+        ArgumentCaptor<List<SignalThresholdInfo>> signalThresholdInfoCaptor =
+                ArgumentCaptor.forClass(List.class);
+        verify(mSimulatedCommandsVerifier, atLeastOnce())
+                .setSignalStrengthReportingCriteria(signalThresholdInfoCaptor.capture(), isNull());
+        List<SignalThresholdInfo> capturedInfos = signalThresholdInfoCaptor.getAllValues().get(0);
+        assertThat(capturedInfos).isNotEmpty();
+
+        for (SignalThresholdInfo signalThresholdInfo : capturedInfos) {
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_SSRSRP) {
+                assertEquals(4,
+                        mBundle.getInt(CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT));
+                assertEquals(3, signalThresholdInfo.getHysteresisDb());
+            }
+        }
+    }
+
+    @Test
+    public void testSetHysteresisDb_WithInvalidCarrierConfigValue() {
+        when(mPhone.isDeviceIdle()).thenReturn(true);
+        when(mPhone.getSubId()).thenReturn(ACTIVE_SUB_ID);
+
+        mBundle.putInt(CarrierConfigManager.KEY_GERAN_RSSI_HYSTERESIS_DB_INT, -4);
+        mBundle.putInt(CarrierConfigManager.KEY_EUTRAN_RSRP_HYSTERESIS_DB_INT, -5);
+        mBundle.putInt(CarrierConfigManager.KEY_NGRAN_SSRSRP_HYSTERESIS_DB_INT, -2);
+        sendCarrierConfigUpdate();
+
+        ArgumentCaptor<List<SignalThresholdInfo>> signalThresholdInfoCaptor =
+                ArgumentCaptor.forClass(List.class);
+        verify(mSimulatedCommandsVerifier, atLeastOnce())
+                .setSignalStrengthReportingCriteria(signalThresholdInfoCaptor.capture(), isNull());
+        List<SignalThresholdInfo> capturedInfos = signalThresholdInfoCaptor.getAllValues().get(0);
+        assertThat(capturedInfos).isNotEmpty();
+
+        for (SignalThresholdInfo signalThresholdInfo : capturedInfos) {
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_RSRP) {
+                assertEquals(2, signalThresholdInfo.getHysteresisDb());
+            }
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_RSSI) {
+                assertEquals(2, signalThresholdInfo.getHysteresisDb());
+            }
+            if (signalThresholdInfo.getSignalMeasurementType() == SIGNAL_MEASUREMENT_TYPE_SSRSRP) {
+                assertEquals(2, signalThresholdInfo.getHysteresisDb());
+            }
+        }
+        reset(mSimulatedCommandsVerifier);
+    }
+
+    @Test
     public void testLteSignalStrengthReportingCriteria_convertRssnrUnitFromTenDbToDB() {
         SignalStrength ss = new SignalStrength(
                 new CellSignalStrengthCdma(),
@@ -741,7 +963,7 @@
             }
         }
         // Only check on RADIO hal 1.5 and above to make it less flaky
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+        if (mPhone.getHalVersion(HAL_SERVICE_NETWORK).greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
             assertThat(expectedNonEmptyThreshold).isEqualTo(actualNonEmptyThreshold);
         }
     }
@@ -752,9 +974,8 @@
                 .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);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(PHONE_ID, ACTIVE_SUB_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
     }
 
@@ -789,4 +1010,4 @@
         }
         return builder.build();
     }
-}
+}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
index f15845c..96184c5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
@@ -98,7 +98,7 @@
                 new CellSignalStrengthWcdma(-94, 4, -102, -5),
                 new CellSignalStrengthTdscdma(-95, 2, -103),
                 new CellSignalStrengthLte(-85, -91, -6, -10, 1, 12, 1),
-                new CellSignalStrengthNr(-91, -6, 3, 1, NrCqiReport, -80, -7, 4));
+                new CellSignalStrengthNr(-91, -6, 3, 1, NrCqiReport, -80, -7, 4, 1));
         assertParcelingIsLossless(s);
 
         PersistableBundle bundle = new PersistableBundle();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalThresholdInfoTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalThresholdInfoTest.java
index b282c55..e22d7ab 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalThresholdInfoTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalThresholdInfoTest.java
@@ -42,69 +42,94 @@
 public class SignalThresholdInfoTest extends TestCase {
     private static final int HYSTERESIS_DB = 2;
     private static final int HYSTERESIS_MS = 30;
-    private static final int[] SSRSRP_THRESHOLDS = new int[]{-120, -100, -80, -60};
+    private static final int[] SSRSRP_THRESHOLDS = new int[] {-120, -100, -80, -60};
 
     // Map of SignalMeasurementType to invalid thresholds edge values.
     // Each invalid value will be constructed with a thresholds array to test separately.
-    private static final Map<Integer, List<Integer>> INVALID_THRESHOLDS_MAP = Map.of(
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
-            List.of(SignalThresholdInfo.SIGNAL_RSSI_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_RSSI_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
-            List.of(SignalThresholdInfo.SIGNAL_RSCP_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_RSCP_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
-            List.of(SignalThresholdInfo.SIGNAL_RSRP_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_RSRP_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
-            List.of(SignalThresholdInfo.SIGNAL_RSRQ_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_RSRQ_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
-            List.of(SignalThresholdInfo.SIGNAL_RSSNR_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_RSSNR_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
-            List.of(SignalThresholdInfo.SIGNAL_SSRSRP_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_SSRSRP_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
-            List.of(SignalThresholdInfo.SIGNAL_SSRSRQ_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_SSRSRQ_MAX_VALUE + 1),
-            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
-            List.of(SignalThresholdInfo.SIGNAL_SSSINR_MIN_VALUE - 1,
-                    SignalThresholdInfo.SIGNAL_SSSINR_MAX_VALUE + 1)
-    );
+    private static final Map<Integer, List<Integer>> INVALID_THRESHOLDS_MAP =
+            Map.of(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_RSSI_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_RSSI_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_RSCP_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_RSCP_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_RSRP_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_RSRP_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_RSRQ_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_RSRQ_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_RSSNR_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_RSSNR_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_SSRSRP_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_SSRSRP_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_SSRSRQ_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_SSRSRQ_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_SSSINR_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_SSSINR_MAX_VALUE + 1),
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO,
+                    List.of(
+                            SignalThresholdInfo.SIGNAL_ECNO_MIN_VALUE - 1,
+                            SignalThresholdInfo.SIGNAL_ECNO_MAX_VALUE + 1));
 
     // Map of RAN to allowed SignalMeasurementType set.
     // RAN/TYPE pair will be used to verify the validation of the combo
-    private static final Map<Integer, Set<Integer>> VALID_RAN_TO_MEASUREMENT_TYPE_MAP = Map.of(
-            AccessNetworkConstants.AccessNetworkType.GERAN,
-            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
-            AccessNetworkConstants.AccessNetworkType.CDMA2000,
-            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
-            AccessNetworkConstants.AccessNetworkType.UTRAN,
-            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP),
-            AccessNetworkConstants.AccessNetworkType.EUTRAN,
-            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
-                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
-                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR),
-            AccessNetworkConstants.AccessNetworkType.NGRAN,
-            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
-                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
-                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
-    );
+    private static final Map<Integer, Set<Integer>> VALID_RAN_TO_MEASUREMENT_TYPE_MAP =
+            Map.of(
+                    AccessNetworkConstants.AccessNetworkType.GERAN,
+                    Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
+                    AccessNetworkConstants.AccessNetworkType.CDMA2000,
+                    Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
+                    AccessNetworkConstants.AccessNetworkType.UTRAN,
+                    Set.of(
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO),
+                    AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                    Set.of(
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR),
+                    AccessNetworkConstants.AccessNetworkType.NGRAN,
+                    Set.of(
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR));
 
     // Deliberately picking up the max/min value in each range to test the edge cases
-    private final int[] mRssiThresholds = new int[]{-113, -103, -97, -51};
-    private final int[] mRscpThresholds = new int[]{-120, -105, -95, -25};
-    private final int[] mRsrpThresholds = new int[]{-140, -118, -108, -44};
-    private final int[] mRsrqThresholds = new int[]{-34, -17, -14, 3};
-    private final int[] mRssnrThresholds = new int[]{-20, 10, 20, 30};
-    private final int[] mSsrsrpThresholds = new int[]{-140, -118, -98, -44};
-    private final int[] mSsrsrqThresholds = new int[]{-43, -17, -14, 20};
-    private final int[] mSssinrThresholds = new int[]{-23, -16, -10, 40};
+    private final int[] mRssiThresholds = new int[] {-113, -103, -97, -51};
+    private final int[] mRscpThresholds = new int[] {-120, -105, -95, -25};
+    private final int[] mRsrpThresholds = new int[] {-140, -118, -108, -44};
+    private final int[] mRsrqThresholds = new int[] {-34, -17, -14, 3};
+    private final int[] mRssnrThresholds = new int[] {-20, 10, 20, 30};
+    private final int[] mSsrsrpThresholds = new int[] {-140, -118, -98, -44};
+    private final int[] mSsrsrqThresholds = new int[] {-43, -17, -14, 20};
+    private final int[] mSssinrThresholds = new int[] {-23, -16, -10, 40};
+    private final int[] mEcnoThresholds = new int[] {-24, -16, -8, 1};
 
-    private final int[][] mThresholds = {mRssiThresholds, mRscpThresholds, mRsrpThresholds,
-            mRsrqThresholds, mRssnrThresholds, mSsrsrpThresholds, mSsrsrqThresholds,
-            mSssinrThresholds};
+    private final int[][] mThresholds = {
+        mRssiThresholds,
+        mRscpThresholds,
+        mRsrpThresholds,
+        mRsrqThresholds,
+        mRssnrThresholds,
+        mSsrsrpThresholds,
+        mSsrsrqThresholds,
+        mSssinrThresholds,
+        mEcnoThresholds
+    };
 
     @Test
     @SmallTest
@@ -120,12 +145,14 @@
                         .setIsEnabled(false)
                         .build();
 
-        assertEquals(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+        assertEquals(
+                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
                 signalThresholdInfo.getSignalMeasurementType());
         assertEquals(HYSTERESIS_MS, signalThresholdInfo.getHysteresisMs());
         assertEquals(HYSTERESIS_DB, signalThresholdInfo.getHysteresisDb());
-        assertEquals(Arrays.toString(SSRSRP_THRESHOLDS), Arrays.toString(
-                signalThresholdInfo.getThresholds()));
+        assertEquals(
+                Arrays.toString(SSRSRP_THRESHOLDS),
+                Arrays.toString(signalThresholdInfo.getThresholds()));
         assertFalse(signalThresholdInfo.isEnabled());
     }
 
@@ -160,68 +187,127 @@
     @SmallTest
     public void testGetSignalThresholdInfo() {
         ArrayList<SignalThresholdInfo> stList = new ArrayList<>();
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-                .setHysteresisMs(0)
-                .setHysteresisDb(0)
-                .setThresholds(new int[]{}, true /*isSystem*/)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-                .setHysteresisMs(HYSTERESIS_MS).setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRssiThresholds)
-                .setIsEnabled(false)
-                .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setHysteresisMs(0)
+                        .setHysteresisDb(0)
+                        .setThresholds(new int[] {}, true /*isSystem*/)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssiThresholds)
+                        .setIsEnabled(false)
+                        .build());
 
-        assertThat(stList.get(0).getThresholds()).isEqualTo(new int[]{});
-        assertThat(stList.get(1).getSignalMeasurementType()).isEqualTo(
-                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI);
+        assertThat(stList.get(0).getThresholds()).isEqualTo(new int[] {});
+        assertThat(stList.get(1).getSignalMeasurementType())
+                .isEqualTo(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI);
         assertThat(stList.get(1).getThresholds()).isEqualTo(mRssiThresholds);
+        assertThat(stList.get(0).getHysteresisDb())
+                .isEqualTo(SignalThresholdInfo.HYSTERESIS_DB_MINIMUM);
+        assertThat(stList.get(1).getHysteresisDb())
+                .isEqualTo(HYSTERESIS_DB);
     }
 
     @Test
     @SmallTest
     public void testEqualsSignalThresholdInfo() {
-        final int[] dummyThresholds = new int[]{-100, -90, -70, -60};
-        final int[] dummyThreholdsDisordered = new int[]{-60, -90, -100, -70};
-        SignalThresholdInfo st1 = new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(1).setSignalMeasurementType(1)
-                .setHysteresisMs(HYSTERESIS_MS).setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRssiThresholds).setIsEnabled(false)
-                .build();
-        SignalThresholdInfo st2 = new SignalThresholdInfo.Builder().setRadioAccessNetworkType(2)
-                .setSignalMeasurementType(2).setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB).setThresholds(mRssiThresholds).setIsEnabled(false)
-                .build();
-        SignalThresholdInfo st3 = new SignalThresholdInfo.Builder().setRadioAccessNetworkType(1)
-                .setSignalMeasurementType(1).setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB).setThresholds(dummyThresholds).setIsEnabled(false)
-                .build();
-        SignalThresholdInfo st4 = new SignalThresholdInfo.Builder().setRadioAccessNetworkType(1)
-                .setSignalMeasurementType(1).setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB).setThresholds(mRssiThresholds).setIsEnabled(false)
-                .build();
-        SignalThresholdInfo st5 = new SignalThresholdInfo.Builder().setRadioAccessNetworkType(1)
-                .setSignalMeasurementType(1).setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB).setThresholds(dummyThreholdsDisordered)
-                .setIsEnabled(false).build();
+        final int[] dummyThresholds = new int[] {-100, -90, -70, -60};
+        final int[] dummyThresholdsDisordered = new int[] {-60, -90, -100, -70};
+        SignalThresholdInfo st1 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(1)
+                        .setSignalMeasurementType(1)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssiThresholds)
+                        .setIsEnabled(false)
+                        .build();
+        SignalThresholdInfo st2 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(2)
+                        .setSignalMeasurementType(2)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssiThresholds)
+                        .setIsEnabled(false)
+                        .build();
+        SignalThresholdInfo st3 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(1)
+                        .setSignalMeasurementType(1)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(dummyThresholds)
+                        .setIsEnabled(false)
+                        .build();
+        SignalThresholdInfo st4 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(1)
+                        .setSignalMeasurementType(1)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssiThresholds)
+                        .setIsEnabled(false)
+                        .build();
+        SignalThresholdInfo st5 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(1)
+                        .setSignalMeasurementType(1)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(dummyThresholdsDisordered)
+                        .setIsEnabled(false)
+                        .build();
 
-        //Return true if all SignalThresholdInfo values match.
+        // Return true if all SignalThresholdInfo values match.
         assertTrue(st1.equals(st1));
         assertFalse(st1.equals(st2));
         assertFalse(st1.equals(st3));
         assertTrue(st1.equals(st4));
-        //Threshold values ordering doesn't matter
+        // Threshold values ordering doesn't matter
         assertTrue(st3.equals(st5));
-        //Return false if the object of argument is other than SignalThresholdInfo.
+        // Return false if the object of argument is other than SignalThresholdInfo.
         assertFalse(st1.equals(new String("test")));
     }
 
     @Test
     @SmallTest
+    public void testHysteresisDbSettings_WithValidRange() {
+        SignalThresholdInfo st1 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setThresholds(new int[] {}, true)
+                        .build();
+        SignalThresholdInfo st2 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setThresholds(new int[] {}, true)
+                        .setHysteresisDb(3)
+                        .build();
+        SignalThresholdInfo st3 =
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setThresholds(new int[] {}, true)
+                        .setHysteresisDb(1)
+                        .build();
+        assertThat(st1.getHysteresisDb()).isEqualTo(HYSTERESIS_DB);
+        assertThat(st2.getHysteresisDb()).isEqualTo(3);
+        assertThat(st3.getHysteresisDb()).isEqualTo(1);
+    }
+
+    @Test
+    @SmallTest
     public void testBuilderWithValidParameters() {
         ArrayList<SignalThresholdInfo> stList = buildSignalThresholdInfoWithPublicFields();
 
@@ -229,7 +315,7 @@
             SignalThresholdInfo st = stList.get(i);
             assertThat(st.getThresholds()).isEqualTo(mThresholds[i]);
             assertThat(st.getHysteresisMs()).isEqualTo(SignalThresholdInfo.HYSTERESIS_MS_DISABLED);
-            assertThat(st.getHysteresisDb()).isEqualTo(SignalThresholdInfo.HYSTERESIS_DB_DISABLED);
+            assertThat(st.getHysteresisDb()).isEqualTo(HYSTERESIS_DB);
             assertFalse(st.isEnabled());
         }
     }
@@ -238,33 +324,46 @@
     @SmallTest
     public void testBuilderWithInvalidParameter() {
         // Invalid signal measurement type
-        int[] invalidSignalMeasurementTypes = new int[]{-1, 0, 9};
+        int[] invalidSignalMeasurementTypes = new int[] {-1, 0, 9};
         for (int signalMeasurementType : invalidSignalMeasurementTypes) {
             buildWithInvalidParameterThrowException(
-                    AccessNetworkConstants.AccessNetworkType.GERAN, signalMeasurementType,
-                    new int[]{-1});
+                    AccessNetworkConstants.AccessNetworkType.GERAN,
+                    signalMeasurementType,
+                    new int[] {-1}, 2);
         }
 
         // Null thresholds array
-        buildWithInvalidParameterThrowException(AccessNetworkConstants.AccessNetworkType.GERAN,
-                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, null);
+        buildWithInvalidParameterThrowException(
+                AccessNetworkConstants.AccessNetworkType.GERAN,
+                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                null, 0);
 
         // Empty thresholds
-        buildWithInvalidParameterThrowException(AccessNetworkConstants.AccessNetworkType.GERAN,
-                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, new int[]{});
-
+        buildWithInvalidParameterThrowException(
+                AccessNetworkConstants.AccessNetworkType.GERAN,
+                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                new int[] {}, 5);
 
         // Too long thresholds array
-        buildWithInvalidParameterThrowException(AccessNetworkConstants.AccessNetworkType.GERAN,
+        buildWithInvalidParameterThrowException(
+                AccessNetworkConstants.AccessNetworkType.GERAN,
                 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
-                new int[]{-100, -90, -70, -60, -58});
+                new int[] {-100, -90, -70, -60, -58}, 3);
+
+        // Test Hysteresis Db invalid Range
+        buildWithInvalidParameterThrowException(
+                AccessNetworkConstants.AccessNetworkType.GERAN,
+                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                new int[] {-100, -90, -70, -60}, -1);
 
         // Thresholds value out of range
         for (int signalMeasurementType : INVALID_THRESHOLDS_MAP.keySet()) {
             List<Integer> invalidThresholds = INVALID_THRESHOLDS_MAP.get(signalMeasurementType);
             for (int threshold : invalidThresholds) {
-                buildWithInvalidParameterThrowException(getValidRan(signalMeasurementType),
-                        signalMeasurementType, new int[]{threshold});
+                buildWithInvalidParameterThrowException(
+                        getValidRan(signalMeasurementType),
+                        signalMeasurementType,
+                        new int[] {threshold}, 1);
             }
         }
 
@@ -272,21 +371,23 @@
         for (int ran : VALID_RAN_TO_MEASUREMENT_TYPE_MAP.keySet()) {
             Set validTypes = VALID_RAN_TO_MEASUREMENT_TYPE_MAP.get(ran);
             for (int type = SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI;
-                    type <= SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR; type++) {
+                    type <= SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO;
+                    type++) {
                 if (!validTypes.contains(type)) {
-                    buildWithInvalidParameterThrowException(ran, type, new int[]{-1});
+                    buildWithInvalidParameterThrowException(ran, type, new int[] {-1}, 2);
                 }
             }
         }
     }
 
-    private void buildWithInvalidParameterThrowException(int ran, int signalMeasurementType,
-            int[] thresholds) {
+    private void buildWithInvalidParameterThrowException(
+            int ran, int signalMeasurementType, int[] thresholds, int hysteresisDb) {
         try {
             new SignalThresholdInfo.Builder()
                     .setRadioAccessNetworkType(ran)
                     .setSignalMeasurementType(signalMeasurementType)
                     .setThresholds(thresholds)
+                    .setHysteresisDb(hysteresisDb)
                     .build();
             fail("exception expected");
         } catch (IllegalArgumentException | NullPointerException expected) {
@@ -296,68 +397,90 @@
     private ArrayList<SignalThresholdInfo> buildSignalThresholdInfoWithAllFields() {
         ArrayList<SignalThresholdInfo> stList = new ArrayList<>();
 
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-                .setHysteresisMs(HYSTERESIS_MS).setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRssiThresholds).setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRscpThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRsrpThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRsrqThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mRssnrThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mSsrsrpThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mSsrsrqThresholds)
-                .setIsEnabled(false)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
-                .setHysteresisMs(HYSTERESIS_MS)
-                .setHysteresisDb(HYSTERESIS_DB)
-                .setThresholds(mSssinrThresholds)
-                .setIsEnabled(false)
-                .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssiThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRscpThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRsrpThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRsrqThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mRssnrThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mSsrsrpThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mSsrsrqThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mSssinrThresholds)
+                        .setIsEnabled(false)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO)
+                        .setHysteresisMs(HYSTERESIS_MS)
+                        .setHysteresisDb(HYSTERESIS_DB)
+                        .setThresholds(mEcnoThresholds)
+                        .setIsEnabled(false)
+                        .build());
 
         return stList;
     }
@@ -365,46 +488,63 @@
     private ArrayList<SignalThresholdInfo> buildSignalThresholdInfoWithPublicFields() {
         ArrayList<SignalThresholdInfo> stList = new ArrayList<>();
 
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-                .setThresholds(mRssiThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP)
-                .setThresholds(mRscpThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP)
-                .setThresholds(mRsrpThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ)
-                .setThresholds(mRsrqThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR)
-                .setThresholds(mRssnrThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP)
-                .setThresholds(mSsrsrpThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ)
-                .setThresholds(mSsrsrqThresholds)
-                .build());
-        stList.add(new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
-                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
-                .setThresholds(mSssinrThresholds)
-                .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                        .setThresholds(mRssiThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP)
+                        .setThresholds(mRscpThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP)
+                        .setThresholds(mRsrpThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ)
+                        .setThresholds(mRsrqThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR)
+                        .setThresholds(mRssnrThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP)
+                        .setThresholds(mSsrsrpThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ)
+                        .setThresholds(mSsrsrqThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.NGRAN)
+                        .setSignalMeasurementType(
+                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
+                        .setThresholds(mSssinrThresholds)
+                        .build());
+        stList.add(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
+                        .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO)
+                        .setThresholds(mEcnoThresholds)
+                        .build());
 
         return stList;
     }
@@ -418,6 +558,7 @@
             case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI:
                 return AccessNetworkConstants.AccessNetworkType.GERAN;
             case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP:
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_ECNO:
                 return AccessNetworkConstants.AccessNetworkType.UTRAN;
             case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP:
             case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ:
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 6a075da..1e4c939 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -21,6 +21,7 @@
 import android.hardware.radio.V1_0.DataRegStateResult;
 import android.hardware.radio.V1_0.SetupDataCallResult;
 import android.hardware.radio.V1_0.VoiceRegStateResult;
+import android.hardware.radio.modem.ImeiInfo;
 import android.net.KeepalivePacketData;
 import android.net.LinkProperties;
 import android.os.AsyncResult;
@@ -66,6 +67,7 @@
 import com.android.internal.telephony.RILUtils;
 import com.android.internal.telephony.RadioCapability;
 import com.android.internal.telephony.SmsResponse;
+import com.android.internal.telephony.SrvccConnection;
 import com.android.internal.telephony.UUSInfo;
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
@@ -186,8 +188,17 @@
     public boolean mSetRadioPowerForEmergencyCall;
     public boolean mSetRadioPowerAsSelectedPhoneForEmergencyCall;
 
+    public boolean mCallWaitActivated = false;
+    private SrvccConnection[] mSrvccConnections;
+
     // mode for Icc Sim Authentication
     private int mAuthenticationMode;
+
+    private int[] mImsRegistrationInfo = new int[4];
+
+    private boolean mN1ModeEnabled = false;
+    private boolean mVonrEnabled = false;
+
     //***** Constructor
     public
     SimulatedCommands() {
@@ -1432,6 +1443,14 @@
 
     @Override
     public void queryCallWaiting(int serviceClass, Message response) {
+        if (response != null && serviceClass == SERVICE_CLASS_NONE) {
+            int[] r = new int[2];
+            r[0] = (mCallWaitActivated ? 1 : 0);
+            r[1] = (mCallWaitActivated ? SERVICE_CLASS_VOICE : SERVICE_CLASS_NONE);
+            resultSuccess(response, r);
+            return;
+        }
+
         unimplemented(response);
     }
 
@@ -1440,11 +1459,15 @@
      * @param serviceClass is a sum of SERVICE_CLASS_*
      * @param response is callback message
      */
-
     @Override
     public void setCallWaiting(boolean enable, int serviceClass,
             Message response) {
-        unimplemented(response);
+        if ((serviceClass & SERVICE_CLASS_VOICE) == SERVICE_CLASS_VOICE) {
+            mCallWaitActivated = enable;
+        }
+        if (response != null) {
+            resultSuccess(response, null);
+        }
     }
 
     /**
@@ -1477,12 +1500,17 @@
     }
 
     @Override
-    public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
+    public void setNetworkSelectionModeAutomatic(Message result) {
+        SimulatedCommandsVerifier.getInstance().setNetworkSelectionModeAutomatic(result);
+        mMockNetworkSelectionMode = 0;
+    }
     @Override
     public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
     @Override
     public void setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result) {
-        unimplemented(result);
+        SimulatedCommandsVerifier.getInstance().setNetworkSelectionModeManual(
+                operatorNumeric, ran, result);
+        mMockNetworkSelectionMode = 1;
     }
 
     /**
@@ -1499,10 +1527,13 @@
         getNetworkSelectionModeCallCount.incrementAndGet();
         int ret[] = new int[1];
 
-        ret[0] = 0;
+        ret[0] = mMockNetworkSelectionMode;
         resultSuccess(result, ret);
     }
 
+    /** 0 for automatic selection and a 1 for manual selection. */
+    private int mMockNetworkSelectionMode = 0;
+
     private final AtomicInteger getNetworkSelectionModeCallCount = new AtomicInteger(0);
 
     @VisibleForTesting
@@ -1792,6 +1823,16 @@
     }
 
     @Override
+    public void getImei(Message response) {
+        SimulatedCommandsVerifier.getInstance().getImei(response);
+        ImeiInfo imeiInfo = new ImeiInfo();
+        imeiInfo.imei = FAKE_IMEI;
+        imeiInfo.svn = FAKE_IMEISV;
+        imeiInfo.type = ImeiInfo.ImeiType.SECONDARY;
+        resultSuccess(response, imeiInfo);
+    }
+
+    @Override
     public void
     getCDMASubscription(Message result) {
         String ret[] = new String[5];
@@ -1891,8 +1932,8 @@
 
     @Override
     public void setCdmaBroadcastActivation(boolean activate, Message response) {
-        unimplemented(response);
-
+        SimulatedCommandsVerifier.getInstance().setCdmaBroadcastActivation(activate, response);
+        resultSuccess(response, null);
     }
 
     @Override
@@ -1903,7 +1944,8 @@
 
     @Override
     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) {
-        unimplemented(response);
+        SimulatedCommandsVerifier.getInstance().setCdmaBroadcastConfig(configs, response);
+        resultSuccess(response, null);
     }
 
     public void forceDataDormancy(Message response) {
@@ -1913,7 +1955,8 @@
 
     @Override
     public void setGsmBroadcastActivation(boolean activate, Message response) {
-        unimplemented(response);
+        SimulatedCommandsVerifier.getInstance().setGsmBroadcastActivation(activate, response);
+        resultSuccess(response, null);
     }
 
 
@@ -1921,7 +1964,7 @@
     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
         SimulatedCommandsVerifier.getInstance().setGsmBroadcastConfig(config, response);
         if (mSendSetGsmBroadcastConfigResponse) {
-            unimplemented(response);
+            resultSuccess(response, null);
         }
     }
 
@@ -2135,19 +2178,18 @@
     }
 
     @Override
-    public void iccCloseLogicalChannel(int channel, Message response) {
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response) {
         unimplemented(response);
     }
 
     @Override
     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
-                                              int p1, int p2, int p3, String data,
-                                              Message response) {
+            int p1, int p2, int p3, String data, boolean isEs10Command, Message response) {
         SimulatedCommandsVerifier.getInstance().iccTransmitApduLogicalChannel(channel, cla,
-                instruction, p1, p2, p3, data, response);
-        if(mIccIoResultForApduLogicalChannel!=null) {
+                instruction, p1, p2, p3, data, isEs10Command, response);
+        if (mIccIoResultForApduLogicalChannel != null) {
             resultSuccess(response, mIccIoResultForApduLogicalChannel);
-        }else {
+        } else {
             resultFail(response, null, new RuntimeException("IccIoResult not set"));
         }
     }
@@ -2558,4 +2600,44 @@
         PcoData response = new PcoData(cid, bearerProto, pcoId, contents);
         mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
+
+    @Override
+    public void setSrvccCallInfo(SrvccConnection[] srvccConnections, Message result) {
+        mSrvccConnections = srvccConnections;
+    }
+
+    public SrvccConnection[] getSrvccConnections() {
+        return mSrvccConnections;
+    }
+
+    @Override
+    public void updateImsRegistrationInfo(int regState,
+            int imsRadioTech, int suggestedAction, int capabilities, Message result) {
+        mImsRegistrationInfo[0] = regState;
+        mImsRegistrationInfo[1] = imsRadioTech;
+        mImsRegistrationInfo[2] = suggestedAction;
+        mImsRegistrationInfo[3] = capabilities;
+    }
+
+    public int[] getImsRegistrationInfo() {
+        return mImsRegistrationInfo;
+    }
+
+    @Override
+    public void setN1ModeEnabled(boolean enable, Message result) {
+        mN1ModeEnabled = enable;
+    }
+
+    public boolean isN1ModeEnabled() {
+        return mN1ModeEnabled;
+    }
+
+    @Override
+    public void isVoNrEnabled(Message message, WorkSource workSource) {
+        resultSuccess(message, (Object) mVonrEnabled);
+    }
+
+    public void setVonrEnabled(boolean vonrEnable) {
+        mVonrEnabled = vonrEnable;
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
index 60add09..4d1c104 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
@@ -1160,6 +1160,11 @@
     }
 
     @Override
+    public void getImei(Message response) {
+
+    }
+
+    @Override
     public void getCDMASubscription(Message response) {
 
     }
@@ -1299,13 +1304,14 @@
     }
 
     @Override
-    public void iccCloseLogicalChannel(int channel, Message response) {
+    public void iccCloseLogicalChannel(int channel, boolean isEs10, Message response) {
 
     }
 
     @Override
     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1,
-                                              int p2, int p3, String data, Message response) {
+                                              int p2, int p3, String data,
+                                              boolean isEs10Command, Message response) {
 
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java
index a81a252..09c4173 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java
@@ -16,6 +16,17 @@
 
 package com.android.internal.telephony;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+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.content.pm.PackageManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -29,17 +40,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-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 java.util.ArrayList;
 
 @RunWith(AndroidTestingRunner.class)
@@ -195,4 +195,48 @@
 
         doReturn(false).when(mPhone).isInEcm();
     }
+
+    @Test
+    public void sendsendTextForSubscriberTest() {
+        int subId = 1;
+        doReturn(true).when(mSubscriptionManager)
+                .isSubscriptionAssociatedWithUser(eq(subId), any());
+
+        mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234",
+                null, "text", null, null, false, 0L, true, true);
+        verify(mIccSmsInterfaceManager, Mockito.times(1))
+                .sendText(mCallingPackage, "1234", null, "text", null, null, false, 0L, true);
+    }
+
+    @Test
+    public void sendTextForSubscriberTest_InteractAcrossUsers() {
+        int subId = 1;
+        // Sending text to subscriber should not fail when the caller has the
+        // INTERACT_ACROSS_USERS_FULL permission.
+        doReturn(false).when(mSubscriptionManager)
+                .isSubscriptionAssociatedWithUser(eq(subId), any());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(
+                eq(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL));
+
+        mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234",
+                null, "text", null, null, false, 0L, true, true);
+        verify(mIccSmsInterfaceManager, Mockito.times(1))
+                .sendText(mCallingPackage, "1234", null, "text", null, null, false, 0L, true);
+    }
+
+    @Test
+    public void sendTextForSubscriberTestFail() {
+        int subId = 1;
+        // Sending text to subscriber should fail when the caller does not have the
+        // INTERACT_ACROSS_USERS_FULL permission and is not associated with the subscription.
+        doReturn(false).when(mSubscriptionManager)
+                .isSubscriptionAssociatedWithUser(eq(subId), any());
+        doReturn(PackageManager.PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(
+                eq(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL));
+
+        mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234",
+                null, "text", null, null, false, 0L, true, true);
+        verify(mIccSmsInterfaceManager, Mockito.times(0))
+                .sendText(mCallingPackage, "1234", null, "text", null, null, false, 0L, true);
+    }
 }
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
index 6ef8508..b073cd4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
@@ -19,6 +19,8 @@
 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -28,13 +30,24 @@
 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;
 import static org.mockito.Mockito.when;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Looper;
 import android.os.Message;
 import android.provider.Telephony.Sms.Intents;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.SmsManager;
 import android.test.FlakyTest;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -42,36 +55,140 @@
 import android.testing.TestableLooper;
 import android.util.Singleton;
 
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.domainselection.DomainSelectionConnection;
+import com.android.internal.telephony.domainselection.EmergencySmsDomainSelectionConnection;
+import com.android.internal.telephony.domainselection.SmsDomainSelectionConnection;
+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.ArgumentCaptor;
+import org.mockito.Mockito;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.concurrent.CompletableFuture;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class SmsDispatchersControllerTest extends TelephonyTest {
+    /**
+     * Inherits the SmsDispatchersController to verify the protected methods.
+     */
+    private static class TestSmsDispatchersController extends SmsDispatchersController {
+        TestSmsDispatchersController(Phone phone, SmsStorageMonitor storageMonitor,
+                SmsUsageMonitor usageMonitor, Looper looper) {
+            super(phone, storageMonitor, usageMonitor, looper);
+        }
+
+        public DomainSelectionConnectionHolder testGetDomainSelectionConnectionHolder(
+                boolean emergency) {
+            return getDomainSelectionConnectionHolder(emergency);
+        }
+
+        public void testSendData(String callingPackage, String destAddr, String scAddr,
+                int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent,
+                boolean isForVvm) {
+            sendData(callingPackage, destAddr, scAddr,
+                    destPort, data, sentIntent, deliveryIntent, isForVvm);
+        }
+
+        public void testSendMultipartText(String destAddr, String scAddr,
+                ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
+                ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg,
+                boolean persistMessage, int priority, boolean expectMore, int validityPeriod,
+                long messageId) {
+            sendMultipartText(destAddr, scAddr, parts, sentIntents, deliveryIntents, messageUri,
+                    callingPkg, persistMessage, priority, expectMore, validityPeriod, messageId);
+        }
+    }
+
+    /**
+     * Inherits the SMSDispatcher to verify the abstract or protected methods.
+     */
+    protected abstract static class TestSmsDispatcher extends SMSDispatcher {
+        public TestSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
+            super(phone, smsDispatchersController);
+        }
+
+        @Override
+        public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
+                byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent,
+                boolean isForVvm) {
+            super.sendData(callingPackage, destAddr, scAddr, destPort,
+                    data, sentIntent, deliveryIntent, isForVvm);
+        }
+
+        @Override
+        public void sendSms(SmsTracker tracker) {
+        }
+
+        @Override
+        public String getFormat() {
+            return SmsConstants.FORMAT_3GPP;
+        }
+    }
+
+    /**
+     * Inherits the SMSDispatcher to verify the protected methods.
+     */
+    protected static class TestImsSmsDispatcher extends ImsSmsDispatcher {
+        public TestImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController,
+                FeatureConnectorFactory factory) {
+            super(phone, smsDispatchersController, factory);
+        }
+
+        @Override
+        public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
+                byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent,
+                boolean isForVvm) {
+            super.sendData(callingPackage, destAddr, scAddr, destPort,
+                    data, sentIntent, deliveryIntent, isForVvm);
+        }
+
+        @Override
+        public String getFormat() {
+            return SmsConstants.FORMAT_3GPP;
+        }
+    }
+
+    private static final String ACTION_TEST_SMS_SENT = "TEST_SMS_SENT";
+
     // Mocked classes
     private SMSDispatcher.SmsTracker mTracker;
+    private PendingIntent mSentIntent;
+    private TestImsSmsDispatcher mImsSmsDispatcher;
+    private TestSmsDispatcher mGsmSmsDispatcher;
+    private TestSmsDispatcher mCdmaSmsDispatcher;
+    private SmsDomainSelectionConnection mSmsDsc;
+    private EmergencySmsDomainSelectionConnection mEmergencySmsDsc;
 
-    private SmsDispatchersController mSmsDispatchersController;
+    private TestSmsDispatchersController mSmsDispatchersController;
     private boolean mInjectionCallbackTriggered = false;
+    private CompletableFuture<Integer> mDscFuture;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mTracker = mock(SMSDispatcher.SmsTracker.class);
         setupMockPackagePermissionChecks();
-
-        mSmsDispatchersController = new SmsDispatchersController(mPhone, mSmsStorageMonitor,
-            mSmsUsageMonitor);
+        mSmsDispatchersController = new TestSmsDispatchersController(mPhone, mSmsStorageMonitor,
+            mSmsUsageMonitor, mTestableLooper.getLooper());
+        setUpDomainSelectionConnectionAsNotSupported();
         processAllMessages();
     }
 
     @After
     public void tearDown() throws Exception {
+        mImsSmsDispatcher = null;
+        mGsmSmsDispatcher = null;
+        mCdmaSmsDispatcher = null;
+        mSmsDsc = null;
+        mEmergencySmsDsc = null;
+        mDscFuture = null;
         mSmsDispatchersController.dispose();
         mSmsDispatchersController = null;
         super.tearDown();
@@ -91,6 +208,30 @@
         assertTrue(mSmsDispatchersController.isIms());
     }
 
+    @Test @SmallTest
+    public void testReportSmsMemoryStatus() throws Exception {
+        int eventReportMemoryStatusDone = 3;
+        SmsStorageMonitor smsStorageMonnitor = new SmsStorageMonitor(mPhone);
+        Message result = smsStorageMonnitor.obtainMessage(eventReportMemoryStatusDone);
+        ImsSmsDispatcher mImsSmsDispatcher = Mockito.mock(ImsSmsDispatcher.class);
+        mSmsDispatchersController.setImsSmsDispatcher(mImsSmsDispatcher);
+        mSmsDispatchersController.reportSmsMemoryStatus(result);
+        AsyncResult ar = (AsyncResult) result.obj;
+        verify(mImsSmsDispatcher).onMemoryAvailable();
+        assertNull(ar.exception);
+    }
+
+    @Test @SmallTest
+    public void testReportSmsMemoryStatusFailure() throws Exception {
+        int eventReportMemoryStatusDone = 3;
+        SmsStorageMonitor smsStorageMonnitor = new SmsStorageMonitor(mPhone);
+        Message result = smsStorageMonnitor.obtainMessage(eventReportMemoryStatusDone);
+        mSmsDispatchersController.setImsSmsDispatcher(null);
+        mSmsDispatchersController.reportSmsMemoryStatus(result);
+        AsyncResult ar = (AsyncResult) result.obj;
+        assertNotNull(ar.exception);
+    }
+
     @Test @SmallTest @FlakyTest
     public void testSendImsGmsTest() throws Exception {
         switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM);
@@ -179,6 +320,225 @@
         assertEquals(true, mInjectionCallbackTriggered);
     }
 
+    @Test @SmallTest
+    public void testSendImsGmsTestWithSmsc() {
+        IccSmsInterfaceManager iccSmsInterfaceManager = Mockito.mock(IccSmsInterfaceManager.class);
+        when(mPhone.getIccSmsInterfaceManager()).thenReturn(iccSmsInterfaceManager);
+        when(iccSmsInterfaceManager.getSmscAddressFromIccEf("com.android.messaging"))
+                .thenReturn("222");
+        switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM);
+
+        mSmsDispatchersController.sendText("111", null /*scAddr*/, TAG,
+                null, null, null, "com.android.messaging",
+                false, -1, false, -1, false, 0L);
+        byte[] smscbyte = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
+                "222");
+        String smsc = IccUtils.bytesToHexString(smscbyte);
+        verify(mSimulatedCommandsVerifier).sendImsGsmSms(eq(smsc), anyString(),
+                anyInt(), anyInt(), any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testSendDataWhenDomainPs() throws Exception {
+        sendDataWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendDataWhenDomainCsAndCdma() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA);
+        sendDataWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, true);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendDataWhenDomainCsAndGsm() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
+        sendDataWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendTextWhenDomainPs() throws Exception {
+        sendTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendTextWhenDomainCsAndCdma() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA);
+        sendTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, true);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendTextWhenDomainCsAndGsm() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
+        sendTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendMultipartTextWhenDomainPs() throws Exception {
+        sendMultipartTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendMultipartTextWhenDomainCsAndCdma() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA);
+        sendMultipartTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, true);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendMultipartTextWhenDomainCsAndGsm() throws Exception {
+        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
+        sendMultipartTextWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS, false);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendRetrySmsWhenDomainPs() throws Exception {
+        sendRetrySmsWithDomainSelection(NetworkRegistrationInfo.DOMAIN_PS,
+                PhoneConstants.PHONE_TYPE_GSM, SmsConstants.FORMAT_3GPP);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendRetrySmsWhenDomainCsAndCdma() throws Exception {
+        sendRetrySmsWithDomainSelection(NetworkRegistrationInfo.DOMAIN_CS,
+                PhoneConstants.PHONE_TYPE_CDMA, SmsConstants.FORMAT_3GPP2);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendRetrySmsWhenDomainCsAndGsm() throws Exception {
+        sendRetrySmsWithDomainSelection(NetworkRegistrationInfo.DOMAIN_CS,
+                PhoneConstants.PHONE_TYPE_GSM, SmsConstants.FORMAT_3GPP);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendRetrySmsWhenImsAlreadyUsedAndCdma() throws Exception {
+        sendRetrySmsWhenImsAlreadyUsed(PhoneConstants.PHONE_TYPE_CDMA, SmsConstants.FORMAT_3GPP2);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendRetrySmsWhenImsAlreadyUsedAndGsm() throws Exception {
+        sendRetrySmsWhenImsAlreadyUsed(PhoneConstants.PHONE_TYPE_GSM, SmsConstants.FORMAT_3GPP);
+    }
+
+    @Test
+    @SmallTest
+    public void testSendEmergencyTextWhenDomainPs() throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        mSmsDispatchersController.sendText("911", "2222", "text", mSentIntent, null, null,
+                "test-app", false, 0, false, 10, false, 1L, false);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(true);
+        verify(mEmergencySmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isEmergency());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mDscFuture.complete(NetworkRegistrationInfo.DOMAIN_PS);
+        processAllMessages();
+
+        verify(mEmergencySmsDsc).finishSelection();
+        verify(mImsSmsDispatcher).sendText(eq("911"), eq("2222"), eq("text"), eq(mSentIntent),
+                any(), any(), eq("test-app"), eq(false), eq(0), eq(false), eq(10), eq(false),
+                eq(1L), eq(false));
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyDomainSelectionTerminated() throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        mSmsDispatchersController.sendText("1111", "2222", "text", mSentIntent, null, null,
+                "test-app", false, 0, false, 10, false, 1L, false);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> captor =
+                ArgumentCaptor.forClass(
+                        DomainSelectionConnection.DomainSelectionConnectionCallback.class);
+        verify(mSmsDsc).requestDomainSelection(any(), captor.capture());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        DomainSelectionConnection.DomainSelectionConnectionCallback callback = captor.getValue();
+        assertNotNull(callback);
+
+        mSmsDispatchersController.post(() -> {
+            callback.onSelectionTerminated(DisconnectCause.LOCAL);
+        });
+        processAllMessages();
+
+        verify(mSmsDsc, never()).finishSelection();
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+
+        // We can use the IntentReceiver for receiving the sent result, but it can be reported as
+        // a flaky test since sometimes broadcasts can take a long time if the system is under load.
+        // At this point, we couldn't use the PendingIntent as a mock because it's a final class
+        // so this test checks the method in the IActivityManager when the PendingIntent#send(int)
+        // is called.
+        verify(mIActivityManager).sendIntentSender(any(), any(), any(),
+                eq(SmsManager.RESULT_ERROR_GENERIC_FAILURE), any(), any(), any(), any(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testSendTextContinuously() throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        mSmsDispatchersController.sendText("1111", "2222", "text", mSentIntent, null, null,
+                "test-app", false, 0, false, 10, false, 1L, false);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mSmsDispatchersController.sendText("1111", "2222", "text", mSentIntent, null, null,
+                "test-app", false, 0, false, 10, false, 1L, false);
+
+        verify(mSmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(2, holder.getPendingRequests().size());
+
+        mDscFuture.complete(NetworkRegistrationInfo.DOMAIN_PS);
+        processAllMessages();
+
+        verify(mSmsDsc).finishSelection();
+        verify(mImsSmsDispatcher, times(2)).sendText(eq("1111"), eq("2222"), eq("text"),
+                eq(mSentIntent), any(), any(), eq("test-app"), eq(false), eq(0), eq(false), eq(10),
+                eq(false), eq(1L), eq(false));
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
     private void switchImsSmsFormat(int phoneType) {
         mSimulatedCommands.setImsRegistrationState(new int[]{1, phoneType});
         mSimulatedCommands.notifyImsNetworkStateChanged();
@@ -186,4 +546,249 @@
         processAllMessages();
         assertTrue(mSmsDispatchersController.isIms());
     }
+
+    @Test
+    public void testSetImsManager() {
+        ImsManager imsManager = mock(ImsManager.class);
+        assertTrue(mSmsDispatchersController.setImsManager(imsManager));
+    }
+
+    private void setUpDomainSelectionConnectionAsNotSupported() {
+        mSmsDispatchersController.setDomainSelectionResolverProxy(
+                new SmsDispatchersController.DomainSelectionResolverProxy() {
+                    @Override
+                    @Nullable
+                    public DomainSelectionConnection getDomainSelectionConnection(Phone phone,
+                            @DomainSelectionService.SelectorType int selectorType,
+                            boolean isEmergency) {
+                        return null;
+                    }
+
+                    @Override
+                    public boolean isDomainSelectionSupported() {
+                        return false;
+                    }
+                });
+    }
+
+    private void setUpDomainSelectionConnection()  {
+        mEmergencySmsDsc = Mockito.mock(EmergencySmsDomainSelectionConnection.class);
+        mSmsDsc = Mockito.mock(SmsDomainSelectionConnection.class);
+        mSmsDispatchersController.setDomainSelectionResolverProxy(
+                new SmsDispatchersController.DomainSelectionResolverProxy() {
+                    @Override
+                    @Nullable
+                    public DomainSelectionConnection getDomainSelectionConnection(Phone phone,
+                            @DomainSelectionService.SelectorType int selectorType,
+                            boolean isEmergency) {
+                        return isEmergency ? mEmergencySmsDsc : mSmsDsc;
+                    }
+
+                    @Override
+                    public boolean isDomainSelectionSupported() {
+                        return true;
+                    }
+                });
+
+        mDscFuture = new CompletableFuture<>();
+        when(mSmsDsc.requestDomainSelection(
+                any(DomainSelectionService.SelectionAttributes.class),
+                any(DomainSelectionConnection.DomainSelectionConnectionCallback.class)))
+                .thenReturn(mDscFuture);
+        when(mEmergencySmsDsc.requestDomainSelection(
+                any(DomainSelectionService.SelectionAttributes.class),
+                any(DomainSelectionConnection.DomainSelectionConnectionCallback.class)))
+                .thenReturn(mDscFuture);
+    }
+
+    private void setUpSmsDispatchers() throws Exception {
+        mImsSmsDispatcher = Mockito.mock(TestImsSmsDispatcher.class);
+        mGsmSmsDispatcher = Mockito.mock(TestSmsDispatcher.class);
+        mCdmaSmsDispatcher = Mockito.mock(TestSmsDispatcher.class);
+
+        replaceInstance(SmsDispatchersController.class, "mImsSmsDispatcher",
+                mSmsDispatchersController, mImsSmsDispatcher);
+        replaceInstance(SmsDispatchersController.class, "mGsmDispatcher",
+                mSmsDispatchersController, mGsmSmsDispatcher);
+        replaceInstance(SmsDispatchersController.class, "mCdmaDispatcher",
+                mSmsDispatchersController, mCdmaSmsDispatcher);
+
+        when(mTelephonyManager.isEmergencyNumber(eq("911"))).thenReturn(true);
+
+        mSentIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0,
+                new Intent(ACTION_TEST_SMS_SENT), PendingIntent.FLAG_MUTABLE
+                        | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT);
+    }
+
+    private void sendDataWithDomainSelection(@NetworkRegistrationInfo.Domain int domain,
+            boolean isCdmaMo) throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        byte[] data = new byte[] { 0x01 };
+        mSmsDispatchersController.testSendData(
+                "test-app", "1111", "2222", 8080, data, mSentIntent, null, false);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        verify(mSmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mDscFuture.complete(domain);
+        processAllMessages();
+
+        verify(mSmsDsc).finishSelection();
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            verify(mImsSmsDispatcher).sendData(eq("test-app"), eq("1111"), eq("2222"), eq(8080),
+                    eq(data), eq(mSentIntent), any(), eq(false));
+        } else if (isCdmaMo) {
+            verify(mCdmaSmsDispatcher).sendData(eq("test-app"), eq("1111"), eq("2222"), eq(8080),
+                    eq(data), eq(mSentIntent), any(), eq(false));
+        } else {
+            verify(mGsmSmsDispatcher).sendData(eq("test-app"), eq("1111"), eq("2222"), eq(8080),
+                    eq(data), eq(mSentIntent), any(), eq(false));
+        }
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
+    private void sendTextWithDomainSelection(@NetworkRegistrationInfo.Domain int domain,
+            boolean isCdmaMo) throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        mSmsDispatchersController.sendText("1111", "2222", "text", mSentIntent, null, null,
+                "test-app", false, 0, false, 10, false, 1L, false);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        verify(mSmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mDscFuture.complete(domain);
+        processAllMessages();
+
+        verify(mSmsDsc).finishSelection();
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            verify(mImsSmsDispatcher).sendText(eq("1111"), eq("2222"), eq("text"), eq(mSentIntent),
+                    any(), any(), eq("test-app"), eq(false), eq(0), eq(false), eq(10), eq(false),
+                    eq(1L), eq(false));
+        } else if (isCdmaMo) {
+            verify(mCdmaSmsDispatcher).sendText(eq("1111"), eq("2222"), eq("text"), eq(mSentIntent),
+                    any(), any(), eq("test-app"), eq(false), eq(0), eq(false), eq(10), eq(false),
+                    eq(1L), eq(false));
+        } else {
+            verify(mGsmSmsDispatcher).sendText(eq("1111"), eq("2222"), eq("text"), eq(mSentIntent),
+                    any(), any(), eq("test-app"), eq(false), eq(0), eq(false), eq(10), eq(false),
+                    eq(1L), eq(false));
+        }
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
+    private void sendMultipartTextWithDomainSelection(@NetworkRegistrationInfo.Domain int domain,
+            boolean isCdmaMo) throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+
+        ArrayList<String> parts = new ArrayList<>();
+        ArrayList<PendingIntent> sentIntents = new ArrayList<>();
+        ArrayList<PendingIntent> deliveryIntents = new ArrayList<>();
+        mSmsDispatchersController.testSendMultipartText("1111", "2222", parts, sentIntents,
+                deliveryIntents, null, "test-app", false, 0, false, 10, 1L);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        verify(mSmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mDscFuture.complete(domain);
+        processAllMessages();
+
+        verify(mSmsDsc).finishSelection();
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            verify(mImsSmsDispatcher).sendMultipartText(eq("1111"), eq("2222"), eq(parts),
+                    eq(sentIntents), eq(deliveryIntents), any(), eq("test-app"), eq(false), eq(0),
+                    eq(false), eq(10), eq(1L));
+        } else if (isCdmaMo) {
+            verify(mCdmaSmsDispatcher).sendMultipartText(eq("1111"), eq("2222"), eq(parts),
+                    eq(sentIntents), eq(deliveryIntents), any(), eq("test-app"), eq(false), eq(0),
+                    eq(false), eq(10), eq(1L));
+        } else {
+            verify(mGsmSmsDispatcher).sendMultipartText(eq("1111"), eq("2222"), eq(parts),
+                    eq(sentIntents), eq(deliveryIntents), any(), eq("test-app"), eq(false), eq(0),
+                    eq(false), eq(10), eq(1L));
+        }
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
+    private void sendRetrySmsWithDomainSelection(@NetworkRegistrationInfo.Domain int domain,
+            int phoneType, String smsFormat) throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+        when(mPhone.getPhoneType()).thenReturn(phoneType);
+        when(mImsSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
+        when(mCdmaSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP2);
+        when(mGsmSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
+        replaceInstance(SMSDispatcher.SmsTracker.class, "mFormat", mTracker, smsFormat);
+
+        mSmsDispatchersController.sendRetrySms(mTracker);
+
+        SmsDispatchersController.DomainSelectionConnectionHolder holder =
+                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(false);
+        verify(mSmsDsc).requestDomainSelection(any(), any());
+        assertNotNull(holder);
+        assertNotNull(holder.getConnection());
+        assertTrue(holder.isDomainSelectionRequested());
+        assertEquals(1, holder.getPendingRequests().size());
+
+        mDscFuture.complete(domain);
+        processAllMessages();
+
+        verify(mSmsDsc).finishSelection();
+        if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
+            verify(mImsSmsDispatcher).sendSms(eq(mTracker));
+        } else if (SmsConstants.FORMAT_3GPP2.equals(smsFormat)) {
+            verify(mCdmaSmsDispatcher).sendSms(eq(mTracker));
+        } else {
+            verify(mGsmSmsDispatcher).sendSms(eq(mTracker));
+        }
+        assertNull(holder.getConnection());
+        assertFalse(holder.isDomainSelectionRequested());
+        assertEquals(0, holder.getPendingRequests().size());
+    }
+
+    private void sendRetrySmsWhenImsAlreadyUsed(int phoneType, String smsFormat) throws Exception {
+        setUpDomainSelectionConnection();
+        setUpSmsDispatchers();
+        when(mPhone.getPhoneType()).thenReturn(phoneType);
+        when(mImsSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
+        when(mCdmaSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP2);
+        when(mGsmSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
+        replaceInstance(SMSDispatcher.SmsTracker.class, "mFormat", mTracker, smsFormat);
+        mTracker.mUsesImsServiceForIms = true;
+
+        mSmsDispatchersController.sendRetrySms(mTracker);
+
+        verify(mSmsDsc, never()).requestDomainSelection(any(), any());
+
+        if (SmsConstants.FORMAT_3GPP2.equals(smsFormat)) {
+            verify(mCdmaSmsDispatcher).sendSms(eq(mTracker));
+        } else {
+            verify(mGsmSmsDispatcher).sendSms(eq(mTracker));
+        }
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
index 2a7f35b..5057eea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
@@ -78,7 +78,7 @@
                 }
 
                 @Override
-                public boolean isCallerDefaultSmsPackage(String packageName) {
+                public boolean isCallerDefaultSmsPackage(String packageName, int uid) {
                     return mCallerIsDefaultSmsPackage;
                 }
             };
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
index 3eace63..b6775eb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
@@ -20,8 +20,11 @@
 
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
 
 import android.content.Intent;
+import android.content.res.Resources;
 import android.os.Message;
 import android.provider.Telephony;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -34,6 +37,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -138,6 +143,41 @@
     }
 
     @Test @SmallTest
+    public void testReportSmsMemoryStatusToIms() {
+        Resources mockResources = Mockito.mock(Resources.class);
+        doReturn(mockResources).when(mContext).getResources();
+        doReturn(true).when(mockResources).getBoolean(anyInt());
+        doReturn(true).when(mIccSmsInterfaceManager.mDispatchersController).isIms();
+
+        mSimulatedCommands.notifyRadioOn();
+        processAllMessages();
+
+        verify(mSimulatedCommandsVerifier, never()).reportSmsMemoryStatus(anyBoolean(),
+                any(Message.class));
+
+        // Send DEVICE_STORAGE_FULL
+        mContextFixture.getTestDouble().sendBroadcast(
+                new Intent(Intent.ACTION_DEVICE_STORAGE_FULL));
+        processAllMessages();
+
+        verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(false), any(Message.class));
+        assertFalse(mSmsStorageMonitor.isStorageAvailable());
+
+        mSimulatedCommands.notifyRadioOn();
+        processAllMessages();
+
+        verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(false), any(Message.class));
+
+        // Send DEVICE_STORAGE_NOT_FULL
+        mContextFixture.getTestDouble().sendBroadcast(
+                new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL));
+        processAllMessages();
+
+        verify(mIccSmsInterfaceManager.mDispatchersController)
+                .reportSmsMemoryStatus(any(Message.class));
+    }
+
+    @Test @SmallTest
     public void testReportSmsMemoryStatusDuringRetry() {
         mSimulatedCommands.setReportSmsMemoryStatusFailResponse(true);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
deleted file mode 100644
index 578fc87..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ /dev/null
@@ -1,2302 +0,0 @@
-/*
- * Copyright (C) 2016 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.SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION;
-
-import static com.android.internal.telephony.SubscriptionController.REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID;
-import static com.android.internal.telephony.uicc.IccCardStatus.CardState.CARDSTATE_PRESENT;
-
-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.assertNotEquals;
-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;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doNothing;
-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.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.Manifest;
-import android.compat.testing.PlatformCompatChangeRule;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ParcelUuid;
-import android.os.PersistableBundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-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;
-
-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.mockito.ArgumentCaptor;
-
-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.UUID;
-
-public class SubscriptionControllerTest extends TelephonyTest {
-    private static final int SINGLE_SIM = 1;
-    private static final int DUAL_SIM = 2;
-    private static final int FAKE_SUBID = 123;
-    private String mCallingPackage;
-    private String mCallingFeature;
-    private SubscriptionController mSubscriptionControllerUT;
-    private MockContentResolver mMockContentResolver;
-    private FakeTelephonyProvider mFakeTelephonyProvider;
-    private PersistableBundle mCarrierConfigs;
-
-    // Mocked classes
-    private UiccSlot mUiccSlot;
-    private ITelephonyRegistry.Stub mTelephonyRegistryMock;
-    private MultiSimSettingController mMultiSimSettingControllerMock;
-    private ISetOpportunisticDataCallback mSetOpptDataCallback;
-    private Handler mHandler;
-    private SubscriptionInfo mMockSubscriptionInfo;
-
-    private static final String MAC_ADDRESS_PREFIX = "mac_";
-    private static final String DISPLAY_NAME_PREFIX = "my_phone_";
-
-    private static final String UNAVAILABLE_ICCID = "";
-    private static final String UNAVAILABLE_NUMBER = "";
-    private static final String DISPLAY_NUMBER = "123456";
-    private static final String DISPLAY_NAME = "testing_display_name";
-
-    @Rule
-    public TestRule mCompatChangeRule = new PlatformCompatChangeRule();
-
-    @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);
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
-        doReturn(SINGLE_SIM).when(mTelephonyManager).getSimCount();
-        doReturn(SINGLE_SIM).when(mTelephonyManager).getPhoneCount();
-        mMockContentResolver = (MockContentResolver) mContext.getContentResolver();
-        mFakeTelephonyProvider = new FakeTelephonyProvider();
-        mMockContentResolver.addProvider(SubscriptionManager.CONTENT_URI.getAuthority(),
-                mFakeTelephonyProvider);
-        replaceInstance(SubscriptionController.class, "sInstance", null, null);
-        replaceInstance(MultiSimSettingController.class, "sInstance", null,
-                mMultiSimSettingControllerMock);
-
-        mSubscriptionControllerUT = SubscriptionController.init(mContext);
-        mCallingPackage = mContext.getOpPackageName();
-        mCallingFeature = mContext.getAttributionTag();
-
-        doReturn(1).when(mProxyController).getMaxRafSupported();
-
-        // Carrier Config
-        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 */
-        mContext.getContentResolver().delete(SubscriptionManager.CONTENT_URI, null, null);
-
-        /* Clear sub info in mSubscriptionControllerUT since they will otherwise be persistent
-         * between each test case. */
-        if (mSubscriptionControllerUT != null) {
-            mSubscriptionControllerUT.clearSubInfo();
-            mSubscriptionControllerUT = null;
-        }
-
-        /* 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);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        mCallingPackage = null;
-        mCallingFeature = null;
-        mMockContentResolver = null;
-        mFakeTelephonyProvider = null;
-        mCarrierConfigs = null;
-        super.tearDown();
-    }
-
-    @Test @SmallTest
-    public void testInsertSim() {
-        //verify there is no sim inserted in the SubscriptionManager
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
-                mCallingFeature));
-
-        int slotID = 0;
-        //insert one Subscription Info
-        mSubscriptionControllerUT.addSubInfo("test", null, slotID,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        //verify there is one sim
-        assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
-                mCallingFeature));
-
-        //sanity for slot id and sub id
-        List<SubscriptionInfo> mSubList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertTrue(mSubList != null && mSubList.size() > 0);
-        for (int i = 0; i < mSubList.size(); i++) {
-            assertTrue(SubscriptionManager.isValidSubscriptionId(
-                    mSubList.get(i).getSubscriptionId()));
-            assertTrue(SubscriptionManager.isValidSlotIndex(mSubList.get(i).getSimSlotIndex()));
-        }
-    }
-
-    @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;
-        String disName = "TESTING";
-        String disNum = "12345";
-        boolean isOpportunistic = true;
-
-        testInsertSim();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        int subID = subIds[0];
-
-        /* Getting, there is no direct getter function for each fields of property */
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
-
-        /* Setting */
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID,
-                SubscriptionManager.NAME_SOURCE_USER_INPUT);
-        mSubscriptionControllerUT.setDataRoaming(dataRoaming, subID);
-        mSubscriptionControllerUT.setDisplayNumber(disNum, subID);
-        mSubscriptionControllerUT.setIconTint(iconTint, subID);
-        mSubscriptionControllerUT.setOpportunistic(isOpportunistic, subID, mCallingPackage);
-
-        subInfo = mSubscriptionControllerUT
-            .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(dataRoaming, subInfo.getDataRoaming());
-        assertEquals(disName, subInfo.getDisplayName());
-        assertEquals(iconTint, subInfo.getIconTint());
-        assertEquals(disNum, subInfo.getNumber());
-        assertEquals(isOpportunistic, subInfo.isOpportunistic());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc() {
-        testInsertSim();
-
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        int subID = subIds[0];
-
-        /* Setting */
-        String disName = "TESTING";
-        int nameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID, nameSource);
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
-        assertNotNull(subInfo);
-        assertEquals(disName, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    private void setSimEmbedded(boolean isEmbedded) throws Exception {
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, isEmbedded ? 1 : 0);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + getFirstSubId(),
-                null);
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithEmbeddedSim()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        setSimEmbedded(true);
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        String newDisplayName = "display_name_pnn";
-        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_PNN;
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithConfigIsNull()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        setSimEmbedded(false);
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        String newDisplayName = "display_name_spn";
-        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
-        when(mCarrierConfigManager.getConfigForSubId(subId)).thenReturn(null);
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithCarrierNameOverride()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        setSimEmbedded(false);
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
-        String newDisplayName = "display_name_spn";
-        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourceCarrierWithSpnAndCarrierName()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        setSimEmbedded(false);
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_CARRIER;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
-        String carrierName = "testing_carrier_name";
-        String newDisplayName = "display_name_spn";
-        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
-        when(mUiccProfile.getServiceProviderName()).thenReturn(null);
-        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
-        mCarrierConfigs.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING, carrierName);
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourcePnnToNameSourceCarrierId()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_SIM_PNN;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        String newDisplayName = "display_name_carrier_id";
-        int newNameSource = SubscriptionManager.NAME_SOURCE_CARRIER_ID;
-        when(mPhone.getPlmn()).thenReturn("testing_pnn");
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testSetGetDisplayNameSrc_updateNameSourceUserInputToNameSourceSpn()
-            throws Exception {
-        testInsertSim();
-
-        // Set values of DB
-        int subId = getFirstSubId();
-        int nameSource = SubscriptionManager.NAME_SOURCE_USER_INPUT;
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(DISPLAY_NAME, subId, nameSource);
-
-        // Update with new value
-        String newDisplayName = "display_name_spn";
-        int newNameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
-
-        // Save to DB after updated
-        mSubscriptionControllerUT.setDisplayNameUsingSrc(newDisplayName, subId, newNameSource);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subInfo);
-        assertEquals(DISPLAY_NAME, subInfo.getDisplayName());
-        assertEquals(nameSource, subInfo.getDisplayNameSource());
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_pnnIsNotNull_returnTrue() {
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_SIM_PNN);
-        when(mPhone.getPlmn()).thenReturn("testing_pnn");
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_spnIsNotNull_returnTrue() {
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_SIM_SPN);
-        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
-        when(mUiccProfile.getServiceProviderName()).thenReturn("testing_spn");
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_simIsEmbedded_returnTrue() {
-        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(true);
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_carrierConfigIsNull_returnTrue() {
-        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
-        when(mCarrierConfigManager.getConfigForSubId(FAKE_SUBID)).thenReturn(null);
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_carrierNameOverrideIsTrue_returnTrue() {
-        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
-        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, true);
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testIsExistingNameSourceStillValid_spnIsNullAndCarrierNameIsNotNull_returnTrue() {
-        when(mMockSubscriptionInfo.isEmbedded()).thenReturn(false);
-        when((mMockSubscriptionInfo).getSubscriptionId()).thenReturn(FAKE_SUBID);
-        when(mMockSubscriptionInfo.getDisplayNameSource())
-                .thenReturn(SubscriptionManager.NAME_SOURCE_CARRIER);
-        when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
-        when(mUiccProfile.getServiceProviderName()).thenReturn(null);
-        mCarrierConfigs.putBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
-        mCarrierConfigs.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING,
-                "testing_carrier_name");
-
-        assertTrue(mSubscriptionControllerUT.isExistingNameSourceStillValid(mMockSubscriptionInfo));
-    }
-
-    @Test @SmallTest
-    public void testCleanUpSIM() {
-        testInsertSim();
-        assertFalse(mSubscriptionControllerUT.isActiveSubId(2));
-        mSubscriptionControllerUT.clearSubInfo();
-        assertFalse(mSubscriptionControllerUT.isActiveSubId(1));
-        assertEquals(SubscriptionManager.SIM_NOT_INSERTED,
-                mSubscriptionControllerUT.getSlotIndex(1));
-    }
-
-    @Test @SmallTest
-    public void testDefaultSubIdOnSingleSimDevice() {
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultDataSubId());
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultSmsSubId());
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultSmsSubId());
-        /* insert one sim */
-        testInsertSim();
-        // if support single sim, sms/data/voice default sub should be the same
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
-    }
-
-    @Test @SmallTest
-    public void testSetGetMCCMNC() {
-        testInsertSim();
-        String mCcMncVERIZON = "310004";
-        mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 1);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
-        assertNotNull(subInfo);
-        assertEquals(Integer.parseInt(mCcMncVERIZON.substring(0, 3)), subInfo.getMcc());
-        assertEquals(Integer.parseInt(mCcMncVERIZON.substring(3)), subInfo.getMnc());
-    }
-
-    @Test @SmallTest
-    public void testSetGetCarrierId() {
-        testInsertSim();
-        int carrierId = 1234;
-        mSubscriptionControllerUT.setCarrierId(carrierId, 1);
-
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
-        assertNotNull(subInfo);
-        assertEquals(carrierId, subInfo.getCarrierId());
-    }
-
-    @Test
-    @SmallTest
-    public void testSetDefaultDataSubId() throws Exception {
-        doReturn(1).when(mPhone).getSubId();
-
-        mSubscriptionControllerUT.setDefaultDataSubId(1);
-
-        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext, times(1)).sendStickyBroadcastAsUser(
-                captorIntent.capture(), eq(UserHandle.ALL));
-
-        Intent intent = captorIntent.getValue();
-        assertEquals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED, intent.getAction());
-
-        Bundle b = intent.getExtras();
-
-        assertTrue(b.containsKey(PhoneConstants.SUBSCRIPTION_KEY));
-        assertEquals(1, b.getInt(PhoneConstants.SUBSCRIPTION_KEY));
-    }
-
-    @Test
-    @SmallTest
-    public void testMigrateImsSettings() throws Exception {
-        testInsertSim();
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        int subID = subIds[0];
-
-        // Set default void subId.
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
-                subID);
-
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                1);
-
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.VT_IMS_ENABLED,
-                0);
-
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ENABLED,
-                1);
-
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_MODE,
-                2);
-
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ROAMING_MODE,
-                3);
-
-        mSubscriptionControllerUT.migrateImsSettings();
-
-        // Global settings should be all set.
-        assertEquals(-1,  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.ENHANCED_4G_MODE_ENABLED));
-
-        assertEquals(-1,  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.VT_IMS_ENABLED));
-
-        assertEquals(-1,  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ENABLED));
-
-        assertEquals(-1,  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_MODE));
-
-        assertEquals(-1,  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ROAMING_MODE));
-
-        // The values should be migrated to its DB.
-        assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
-                subID,
-                SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
-                mCallingPackage,
-                mCallingFeature));
-
-        assertEquals("0", mSubscriptionControllerUT.getSubscriptionProperty(
-                subID,
-                SubscriptionManager.VT_IMS_ENABLED,
-                mCallingPackage,
-                mCallingFeature));
-
-        assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
-                subID,
-                SubscriptionManager.WFC_IMS_ENABLED,
-                mCallingPackage,
-                mCallingFeature));
-
-        assertEquals("2", mSubscriptionControllerUT.getSubscriptionProperty(
-                subID,
-                SubscriptionManager.WFC_IMS_MODE,
-                mCallingPackage,
-                mCallingFeature));
-
-        assertEquals("3", mSubscriptionControllerUT.getSubscriptionProperty(
-                subID,
-                SubscriptionManager.WFC_IMS_ROAMING_MODE,
-                mCallingPackage,
-                mCallingFeature));
-    }
-
-    @Test
-    @SmallTest
-    public void testSkipMigrateImsSettings() throws Exception {
-
-        // Set default invalid subId.
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
-                -1);
-
-        int enhanced4gModeEnabled = 1;
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                enhanced4gModeEnabled);
-
-        int vtImsEnabled = 0;
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.VT_IMS_ENABLED,
-                vtImsEnabled);
-
-        int wfcImsEnabled = 1;
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ENABLED,
-                wfcImsEnabled);
-
-        int wfcImsMode = 2;
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_MODE,
-                wfcImsMode);
-
-        int wfcImsRoamingMode = 3;
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WFC_IMS_ROAMING_MODE,
-                wfcImsRoamingMode);
-
-        mSubscriptionControllerUT.migrateImsSettings();
-
-        // Migration should be skipped because subId was invalid
-        assertEquals(enhanced4gModeEnabled, Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.ENHANCED_4G_MODE_ENABLED));
-
-        assertEquals(vtImsEnabled, Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.VT_IMS_ENABLED));
-
-        assertEquals(wfcImsEnabled, Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.WFC_IMS_ENABLED));
-
-        assertEquals(wfcImsMode, Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.WFC_IMS_MODE));
-
-        assertEquals(wfcImsRoamingMode, Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.WFC_IMS_ROAMING_MODE));
-    }
-
-    @Test
-    @SmallTest
-    public void testOpptSubInfoListChanged() throws Exception {
-        registerMockTelephonyRegistry();
-        verify(mTelephonyRegistryManager, times(0))
-                .notifyOpportunisticSubscriptionInfoChanged();
-
-        testInsertSim();
-        mSubscriptionControllerUT.addSubInfo("test2", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        // Neither sub1 or sub2 are opportunistic. So getOpportunisticSubscriptions
-        // should return empty list and no callback triggered.
-        List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
-
-        assertTrue(opptSubList.isEmpty());
-        verify(mTelephonyRegistryManager, times(0))
-                .notifyOpportunisticSubscriptionInfoChanged();
-
-        // Setting sub2 as opportunistic should trigger callback.
-        mSubscriptionControllerUT.setOpportunistic(true, 2, mCallingPackage);
-
-        verify(mTelephonyRegistryManager, times(1))
-                .notifyOpportunisticSubscriptionInfoChanged();
-        opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
-        assertEquals(1, opptSubList.size());
-        assertEquals("test2", opptSubList.get(0).getIccId());
-
-        // Changing non-opportunistic sub1 shouldn't trigger callback.
-        mSubscriptionControllerUT.setDisplayNameUsingSrc("DisplayName", 1,
-                SubscriptionManager.NAME_SOURCE_SIM_SPN);
-        verify(mTelephonyRegistryManager, times(1))
-                .notifyOpportunisticSubscriptionInfoChanged();
-
-        mSubscriptionControllerUT.setDisplayNameUsingSrc("DisplayName", 2,
-                SubscriptionManager.NAME_SOURCE_SIM_SPN);
-        verify(mTelephonyRegistryManager, times(2))
-                .notifyOpportunisticSubscriptionInfoChanged();
-    }
-
-    @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,
-                mCallingFeature));
-
-        addAndVerifyRemoteSimAddition(1, 0);
-    }
-
-    private void addAndVerifyRemoteSimAddition(int num, int numOfCurrentSubs) {
-        // Verify the number of current subs in the system
-        assertEquals(numOfCurrentSubs,
-                mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage, mCallingFeature));
-
-        // if there are current subs in the system, get that info
-        List<SubscriptionInfo> mSubList;
-        ArrayList<String> macAddresses = new ArrayList<>();
-        ArrayList<String> displayNames = new ArrayList<>();
-        if (numOfCurrentSubs > 0) {
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                    mCallingFeature);
-            assertNotNull(mSubList);
-            assertEquals(numOfCurrentSubs, mSubList.size());
-            for (SubscriptionInfo info : mSubList) {
-                assertNotNull(info.getIccId());
-                assertNotNull(info.getDisplayName());
-                macAddresses.add(info.getIccId());
-                displayNames.add(info.getDisplayName().toString());
-            }
-        }
-
-        // To add more subs, we need to create macAddresses + displaynames.
-        for (int i = 0; i < num; i++) {
-            macAddresses.add(MAC_ADDRESS_PREFIX + (numOfCurrentSubs + i));
-            displayNames.add(DISPLAY_NAME_PREFIX + (numOfCurrentSubs + i));
-        }
-
-        // Add subs - one at a time and verify the contents in subscription info data structs
-        for (int i = 0; i < num; i++) {
-            int index = numOfCurrentSubs + i;
-            mSubscriptionControllerUT.addSubInfo(macAddresses.get(index), displayNames.get(index),
-                    SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB,
-                    SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
-
-            // make sure the subscription is added in SubscriptionController data structs
-            Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
-                    mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
-            assertNotNull(slotIndexToSubsMap);
-            // Since All remote sim's go to the same slot index, there should only be one entry
-            assertEquals(1, slotIndexToSubsMap.size());
-
-            // get all the subscriptions available. should be what is just added in this method
-            // PLUS the number of subs that already existed before
-            int expectedNumOfSubs = numOfCurrentSubs + i + 1;
-            ArrayList<Integer> subIdsList =
-                    slotIndexToSubsMap.get(SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB);
-            assertNotNull(subIdsList);
-            assertEquals(expectedNumOfSubs, subIdsList.size());
-
-            // validate slot index, sub id etc
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                    mCallingFeature);
-            assertNotNull(mSubList);
-            assertEquals(expectedNumOfSubs, mSubList.size());
-
-            // sort on subscription-id which will make sure the previously existing subscriptions
-            // are in earlier slots in the array
-            mSubList.sort(SUBSCRIPTION_INFO_COMPARATOR);
-
-            // Verify the subscription data. Skip the verification for the existing subs.
-            for (int j = numOfCurrentSubs; j < mSubList.size(); j++) {
-                SubscriptionInfo info = mSubList.get(j);
-                assertTrue(SubscriptionManager.isValidSubscriptionId(info.getSubscriptionId()));
-                assertEquals(SubscriptionManager.SLOT_INDEX_FOR_REMOTE_SIM_SUB,
-                        info.getSimSlotIndex());
-                assertEquals(SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM,
-                        info.getSubscriptionType());
-                assertEquals(macAddresses.get(j), info.getIccId());
-                assertEquals(displayNames.get(j), info.getDisplayName());
-            }
-        }
-    }
-
-    private static final Comparator<SubscriptionInfo> SUBSCRIPTION_INFO_COMPARATOR =
-            Comparator.comparingInt(o -> o.getSubscriptionId());
-
-    @Test @SmallTest
-    public void testInsertMultipleRemoteSims() {
-        makeThisDeviceMultiSimCapable();
-        mContextFixture.addSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-
-        // verify that there are no subscription info records
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
-                mCallingFeature));
-        Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
-                mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
-        assertNotNull(slotIndexToSubsMap);
-        assertTrue(slotIndexToSubsMap.isEmpty());
-
-        // Add a few subscriptions
-        addAndVerifyRemoteSimAddition(4, 0);
-    }
-
-    @FlakyTest
-    @Test @SmallTest
-    public void testDefaultSubIdOnMultiSimDevice() {
-        makeThisDeviceMultiSimCapable();
-
-        // Initially, defaults should be -1
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultDataSubId());
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultSmsSubId());
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getDefaultSmsSubId());
-
-        // Insert one Remote-Sim.
-        testInsertRemoteSim();
-
-        // defaults should be set to this newly-inserted subscription
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
-
-        // Add a few subscriptions
-        addAndVerifyRemoteSimAddition(4, 1);
-
-        // defaults should be still be set to the first sub - and unchanged by the addition of
-        // the above multiple sims.
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultDataSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSmsSubId());
-        assertEquals(1, mSubscriptionControllerUT.getDefaultVoiceSubId());
-    }
-
-    @Test @SmallTest
-    public void testRemoveSubscription() {
-        makeThisDeviceMultiSimCapable();
-
-        /* insert some sims */
-        testInsertMultipleRemoteSims();
-        assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
-        int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIdsArray.length > 0);
-        int len = subIdsArray.length;
-
-        // remove the first sim - which also is the default sim.
-        int result = mSubscriptionControllerUT.removeSubInfo(MAC_ADDRESS_PREFIX + 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
-
-        assertTrue(result > 0);
-        // now check the number of subs left. should be one less than earlier
-        int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(newSubIdsArray.length > 0);
-        assertEquals(len - 1, newSubIdsArray.length);
-
-        // now check that there is a new default
-        assertNotSame(1, mSubscriptionControllerUT.getDefaultSubId());
-    }
-
-    private void makeThisDeviceMultiSimCapable() {
-        doReturn(10).when(mTelephonyManager).getSimCount();
-    }
-
-    @Test
-    @SmallTest
-    public void testSetSubscriptionGroupWithModifyPermission() throws Exception {
-        testInsertSim();
-        mSubscriptionControllerUT.addSubInfo("test2", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-
-        int[] subIdList = new int[] {1, 2};
-        try {
-            mSubscriptionControllerUT.createSubscriptionGroup(
-                    subIdList, mContext.getOpPackageName());
-            fail("createSubscriptionGroup should fail with no permission.");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        // With modify permission it should succeed.
-        mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
-        ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, groupId);
-
-        // Calling it again should generate a new group ID.
-        ParcelUuid newGroupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, newGroupId);
-        assertNotEquals(groupId, newGroupId);
-    }
-
-    @Test
-    @SmallTest
-    public void testGetSubscriptionProperty() throws Exception {
-        testInsertSim();
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.GROUP_UUID, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1, null);
-
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-
-        // should succeed with read phone state permission
-        String prop = mSubscriptionControllerUT.getSubscriptionProperty(1,
-                SubscriptionManager.CB_EXTREME_THREAT_ALERT, mContext.getOpPackageName(),
-                mContext.getAttributionTag());
-
-        assertNotEquals(null, prop);
-
-        // group UUID requires privileged phone state permission
-        prop = mSubscriptionControllerUT.getSubscriptionProperty(1, SubscriptionManager.GROUP_UUID,
-                    mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertEquals(null, prop);
-
-        // group UUID should succeed once privileged phone state permission is granted
-        setupReadPrivilegePermission();
-        prop = mSubscriptionControllerUT.getSubscriptionProperty(1, SubscriptionManager.GROUP_UUID,
-                mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertNotEquals(null, prop);
-    }
-
-    @Test
-    @SmallTest
-    public void testCreateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
-        testInsertSim();
-        // Adding a second profile and mark as embedded.
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-
-        int[] subIdList = new int[] {1, 2};
-        // It should fail since it has no permission.
-        try {
-            mSubscriptionControllerUT.createSubscriptionGroup(
-                    subIdList, mContext.getOpPackageName());
-            fail("createSubscriptionGroup should fail with no permission.");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
-        try {
-            mSubscriptionControllerUT.createSubscriptionGroup(
-                    subIdList, mContext.getOpPackageName());
-            fail("createSubscriptionGroup should fail with no permission on sub 2.");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
-        ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, groupId);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
-                        mContext.getAttributionTag());
-
-        // Put sub3 into slot 1 to make sub2 inactive.
-        mContextFixture.addCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE);
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("test3", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        mContextFixture.removeCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE);
-        // As sub2 is inactive, it will checks carrier privilege against access rules in the db.
-        doReturn(true).when(mSubscriptionManager).canManageSubscription(
-                eq(subInfoList.get(1)), anyString());
-
-        ParcelUuid newGroupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, newGroupId);
-        assertNotEquals(groupId, newGroupId);
-    }
-
-    @Test
-    @SmallTest
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testAddSubscriptionIntoGroupWithCarrierPrivilegePermission() throws Exception {
-        testInsertSim();
-        // Adding a second profile and mark as embedded.
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-
-        // Create group for sub 1.
-        int[] subIdList = new int[] {1};
-        doReturn(subIdList).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
-        ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, "packageName1");
-
-        // Try to add sub 2 into group of sub 1.
-        // Should fail as it doesn't have carrier privilege on sub 2.
-        try {
-            mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                    new int[] {2}, groupId, "packageName1");
-            fail("addSubscriptionsIntoGroup should fail with no permission on sub 2.");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        doReturn(false).when(mTelephonyManager).hasCarrierPrivileges(1);
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
-        // Try to add sub 2 into group of sub 1.
-        // Should fail as it doesn't have carrier privilege on sub 1.
-        try {
-            mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                    new int[] {2}, groupId, "packageName2");
-            fail("addSubscriptionsIntoGroup should fail with no permission on the group (sub 1).");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
-        mSubscriptionControllerUT.addSubscriptionsIntoGroup(new int[] {2}, groupId, "packageName2");
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupId, "packageName2", "feature2");
-        assertEquals(2, infoList.size());
-    }
-
-    @Test
-    @SmallTest
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testUpdateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
-        testInsertSim();
-        // Adding a second profile and mark as embedded.
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-
-        int[] subIdList = new int[] {1};
-
-        doReturn(subIdList).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
-        doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
-
-        ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, "packageName1");
-        assertNotEquals(null, groupId);
-
-        mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                new int[] {2}, groupId, "packageName1");
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1", "feature1");
-        assertEquals(2, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-        assertEquals(2, infoList.get(1).getSubscriptionId());
-
-        mSubscriptionControllerUT.removeSubscriptionsFromGroup(
-                new int[] {2}, groupId, "packageName1");
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1", "feature1");
-        assertEquals(1, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-
-        // Make sub 1 inactive.
-        mSubscriptionControllerUT.clearSubInfoRecord(0);
-
-        try {
-            mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                    new int[] {2}, groupId, "packageName2");
-            fail("addSubscriptionsIntoGroup should fail with wrong callingPackage name");
-        } catch (SecurityException e) {
-            // Expected result.
-        }
-
-        // Adding and removing subscription should still work for packageName1, as it's the group
-        // owner who created the group earlier..
-        mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                new int[] {2}, groupId, "packageName1");
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1", "feature1");
-        assertEquals(2, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-        assertEquals(2, infoList.get(1).getSubscriptionId());
-
-        mSubscriptionControllerUT.removeSubscriptionsFromGroup(
-                new int[] {2}, groupId, "packageName1");
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1", "feature1");
-        assertEquals(1, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-    }
-
-    @Test
-    @SmallTest
-    public void testDisabledSubscriptionGroup() throws Exception {
-        registerMockTelephonyRegistry();
-
-        testInsertSim();
-        // Adding a second profile and mark as embedded.
-        mSubscriptionControllerUT.addSubInfo("test2", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, 1);
-        values.put(SubscriptionManager.IS_OPPORTUNISTIC, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-        mSubscriptionControllerUT.notifySubscriptionInfoChanged();
-
-        verify(mTelephonyRegistryManager, times(1))
-                .notifyOpportunisticSubscriptionInfoChanged();
-
-        // Set sub 1 and 2 into same group.
-        int[] subIdList = new int[] {1, 2};
-        ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, groupId);
-
-        mSubscriptionControllerUT.notifySubscriptionInfoChanged();
-        verify(mTelephonyRegistryManager, times(2))
-                .notifyOpportunisticSubscriptionInfoChanged();
-        List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
-        assertEquals(1, opptSubList.size());
-        assertEquals(2, opptSubList.get(0).getSubscriptionId());
-        assertEquals(false, opptSubList.get(0).isGroupDisabled());
-
-        // Unplug SIM 1. This should trigger subscription controller disabling sub 2.
-        values = new ContentValues();
-        values.put(SubscriptionManager.SIM_SLOT_INDEX, -1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-        mSubscriptionControllerUT.notifySubscriptionInfoChanged();
-
-        verify(mTelephonyRegistryManager, times(3))
-                .notifyOpportunisticSubscriptionInfoChanged();
-        opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage,
-                mCallingFeature);
-        assertEquals(1, opptSubList.size());
-        assertEquals(2, opptSubList.get(0).getSubscriptionId());
-        assertEquals(true, opptSubList.get(0).isGroupDisabled());
-    }
-
-    @Test
-    @SmallTest
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testSetSubscriptionGroup() throws Exception {
-        testInsertSim();
-        // Adding a second profile and mark as embedded.
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        ContentValues values = new ContentValues();
-        values.put(SubscriptionManager.IS_EMBEDDED, 1);
-        mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
-                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
-        mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
-
-        assertTrue(mSubscriptionControllerUT.isActiveSubId(1));
-        assertTrue(mSubscriptionControllerUT.isActiveSubId(2));
-        assertTrue(TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, 1,
-                mContext.getOpPackageName(), mContext.getAttributionTag(),
-                "getSubscriptionsInGroup"));
-
-        int[] subIdList = new int[] {1};
-        ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(
-                subIdList, mContext.getOpPackageName());
-        assertNotEquals(null, groupUuid);
-
-        // Sub 1 and sub 2 should be in same group.
-        doReturn(subIdList).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertNotEquals(null, infoList);
-        assertEquals(1, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-
-        subIdList = new int[] {2};
-
-        mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
-                mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertEquals(2, infoList.size());
-        assertEquals(2, infoList.get(1).getSubscriptionId());
-
-        // Remove group of sub 1.
-        subIdList = new int[] {1};
-        mSubscriptionControllerUT.removeSubscriptionsFromGroup(
-                subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
-                mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertEquals(1, infoList.size());
-        assertEquals(2, infoList.get(0).getSubscriptionId());
-
-        // Adding sub 1 into a non-existing UUID, which should be granted.
-        groupUuid = new ParcelUuid(UUID.randomUUID());
-        mSubscriptionControllerUT.addSubscriptionsIntoGroup(
-                subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
-                mContext.getOpPackageName(), mContext.getAttributionTag());
-        assertEquals(1, infoList.size());
-        assertEquals(1, infoList.get(0).getSubscriptionId());
-    }
-
-    private void registerMockTelephonyRegistry() {
-        mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegistryMock);
-        doReturn(mTelephonyRegistryMock).when(mTelephonyRegistryMock)
-                .queryLocalInterface(anyString());
-    }
-
-    @Test
-    @SmallTest
-    public void testEnableDisableSubscriptionSanity() throws Exception {
-        testInsertSim();
-
-        // Non existing subId.
-        assertFalse(mSubscriptionControllerUT.isSubscriptionEnabled(2));
-
-        // Test invalid arguments.
-        try {
-            assertFalse(mSubscriptionControllerUT.isSubscriptionEnabled(-1));
-            fail("Should throw IllegalArgumentException with invalid subId.");
-        } catch (IllegalArgumentException exception) {
-            // Expected.
-        }
-
-        try {
-            mSubscriptionControllerUT.getEnabledSubscriptionId(3);
-            fail("Should throw IllegalArgumentException with invalid subId.");
-        } catch (IllegalArgumentException exception) {
-            // Expected.
-        }
-    }
-
-    @Test
-    @SmallTest
-    public void testGetActiveSubIdList() throws Exception {
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("123", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 1
-        mSubscriptionControllerUT.addSubInfo("456", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 2
-
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        // Make sure the return sub ids are sorted by slot index
-        assertTrue("active sub ids = " + Arrays.toString(subIds),
-                Arrays.equals(subIds, new int[]{2, 1}));
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoWithNoPermissions() throws Exception {
-        // 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);
-
-        try {
-            mSubscriptionControllerUT.getActiveSubscriptionInfo(subId, mCallingPackage,
-                    mCallingFeature);
-            fail("getActiveSubscriptionInfo should fail when invoked with no permissions");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoWithReadPhoneState() throws Exception {
-        // If the calling package only has the READ_PHONE_STATE permission then
-        // getActiveSubscriptionInfo should still return a result but the ICC ID should not be
-        // available via getIccId or getCardString.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setIdentifierAccess(false);
-        setupReadPrivilegePermission();
-        int subId = getFirstSubId();
-
-        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
-                subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
-        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
-        assertEquals(UNAVAILABLE_NUMBER, subscriptionInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionWithPhoneNumberAccess() throws Exception {
-        // If the calling package meets any of the requirements for the
-        // LegacyPermissionManager#checkPhoneNumberAccess test then the number should be available
-        // in the SubscriptionInfo.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setPhoneNumberAccess(PackageManager.PERMISSION_GRANTED);
-        setupReadPrivilegePermission();
-        int subId = getFirstSubId();
-
-        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
-                subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertEquals(DISPLAY_NUMBER, subscriptionInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoWithCarrierPrivileges() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo.
-        testInsertSim();
-        setupIdentifierCarrierPrivilegesTest();
-        setupReadPrivilegePermission();
-        int subId = getFirstSubId();
-
-        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
-                subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertTrue(subscriptionInfo.getIccId().length() > 0);
-        assertTrue(subscriptionInfo.getCardString().length() > 0);
-    }
-
-    @Test
-    public void testGetActiveSubscriptionWithPrivilegedPermission() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo.
-        testInsertSim();
-        int subId = getFirstSubId();
-
-        SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
-                subId, mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertTrue(subscriptionInfo.getIccId().length() > 0);
-        assertTrue(subscriptionInfo.getCardString().length() > 0);
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoForSimSlotIndexWithNoPermission() throws Exception {
-        // If the calling package does not have the READ_PHONE_STATE permission or carrier
-        // privileges then getActiveSubscriptionInfoForSimSlotIndex should throw a
-        // SecurityException.
-        testInsertSim();
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        try {
-            mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0, mCallingPackage,
-                    mCallingFeature);
-            fail("getActiveSubscriptionInfoForSimSlotIndex should fail when invoked with no "
-                    + "permissions");
-        } catch (SecurityException expected) {
-        }
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoForSimSlotIndexWithReadPhoneState() throws Exception {
-        // If the calling package only has the READ_PHONE_STATE permission then
-        // getActiveSubscriptionInfoForSimlSlotIndex should still return the SubscriptionInfo but
-        // the ICC ID should not be available via getIccId or getCardString.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setIdentifierAccess(false);
-
-        SubscriptionInfo subscriptionInfo =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
-                        mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getIccId());
-        assertEquals(UNAVAILABLE_ICCID, subscriptionInfo.getCardString());
-        assertEquals(UNAVAILABLE_NUMBER, subscriptionInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoForSimSlotIndexWithPhoneNumberAccess()
-            throws Exception {
-        // If the calling package meets any of the requirements for the
-        // LegacyPermissionManager#checkPhoneNumberAccess test then the number should be available
-        // in the SubscriptionInfo.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setPhoneNumberAccess(PackageManager.PERMISSION_GRANTED);
-
-        SubscriptionInfo subscriptionInfo =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
-                        mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertEquals(DISPLAY_NUMBER, subscriptionInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoForSimSlotIndexWithCarrierPrivileges()
-            throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo.
-        testInsertSim();
-        setupIdentifierCarrierPrivilegesTest();
-
-        SubscriptionInfo subscriptionInfo =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
-                        mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertTrue(subscriptionInfo.getIccId().length() > 0);
-        assertTrue(subscriptionInfo.getCardString().length() > 0);
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoForSimSlotIndexWithPrivilegedPermission()
-            throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo.
-        testInsertSim();
-
-        SubscriptionInfo subscriptionInfo =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoForSimSlotIndex(0,
-                        mCallingPackage, mCallingFeature);
-
-        assertNotNull(subscriptionInfo);
-        assertTrue(subscriptionInfo.getIccId().length() > 0);
-        assertTrue(subscriptionInfo.getCardString().length() > 0);
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithNoPermission() throws Exception {
-        // If the calling package does not have the READ_PHONE_STATE permission or carrier
-        // privileges then getActiveSubscriptionInfoList should return a list with 0 elements.
-        testInsertSim();
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertNotNull(subInfoList);
-        assertTrue(subInfoList.size() == 0);
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithReadPhoneState() throws Exception {
-        // If the calling package only has the READ_PHONE_STATE permission then
-        // getActiveSubscriptionInfoList should still return the list of SubscriptionInfo objects
-        // but the ICC ID should not be available via getIccId or getCardString.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setIdentifierAccess(false);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
-            assertEquals(UNAVAILABLE_ICCID, info.getCardString());
-            assertEquals(UNAVAILABLE_NUMBER, info.getNumber());
-        }
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithPhoneNumberAccess() throws Exception {
-        // If the calling package meets any of the requirements for the
-        // LegacyPermissionManager#checkPhoneNumberAccess test then the number should be available
-        // in the SubscriptionInfo.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setPhoneNumberAccess(PackageManager.PERMISSION_GRANTED);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        SubscriptionInfo subInfo = subInfoList.get(0);
-        assertEquals(DISPLAY_NUMBER, subInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithCarrierPrivileges() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
-        testInsertSim();
-        setupIdentifierCarrierPrivilegesTest();
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertTrue(info.getIccId().length() > 0);
-            assertTrue(info.getCardString().length() > 0);
-        }
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithCarrierPrivilegesOnOneSubId()
-            throws Exception {
-        // If an app does not have the READ_PHONE_STATE permission but has carrier privileges on one
-        // out of multiple sub IDs then the SubscriptionInfo for that subId should be returned with
-        // the ICC ID and phone number.
-        testInsertSim();
-        doReturn(2).when(mTelephonyManager).getPhoneCount();
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        int firstSubId = getFirstSubId();
-        int secondSubId = getSubIdAtIndex(1);
-        mSubscriptionControllerUT.setDisplayNumber(DISPLAY_NUMBER, secondSubId);
-        setupIdentifierCarrierPrivilegesTest();
-        mContextFixture.removeCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-        setCarrierPrivilegesForSubId(false, firstSubId);
-        setCarrierPrivilegesForSubId(true, secondSubId);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertEquals(1, subInfoList.size());
-        SubscriptionInfo subInfo = subInfoList.get(0);
-        assertEquals("test2", subInfo.getIccId());
-        assertEquals(DISPLAY_NUMBER, subInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListCheckOrder()
-            throws Exception {
-        // If an app does not have the READ_PHONE_STATE permission but has carrier privileges on one
-        // out of multiple sub IDs then the SubscriptionInfo for that subId should be returned with
-        // the ICC ID and phone number.
-        testInsertSim();
-        doReturn(2).when(mTelephonyManager).getPhoneCount();
-        mSubscriptionControllerUT.addSubInfo("test2", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-        int firstSubId = getFirstSubId();
-        int secondSubId = getSubIdAtIndex(1);
-        setupIdentifierCarrierPrivilegesTest();
-        setCarrierPrivilegesForSubId(false, firstSubId);
-        setCarrierPrivilegesForSubId(true, secondSubId);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertEquals(2, subInfoList.size());
-        assertTrue(subInfoList.get(0).getSubscriptionId() < subInfoList.get(1).getSubscriptionId());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithIdentifierAccessWithoutNumberAccess()
-            throws Exception {
-        // An app with access to device identifiers may not have access to the device phone number
-        // (ie an app that passes the device / profile owner check or an app that has been granted
-        // the device identifiers appop); this test verifies that an app with identifier access
-        // can read the ICC ID but does not receive the phone number.
-        testInsertSim();
-        setupReadPhoneNumbersTest();
-        setIdentifierAccess(true);
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertEquals(1, subInfoList.size());
-        SubscriptionInfo subInfo = subInfoList.get(0);
-        assertEquals("test", subInfo.getIccId());
-        assertEquals(UNAVAILABLE_NUMBER, subInfo.getNumber());
-    }
-
-    @Test
-    public void testGetActiveSubscriptionInfoListWithPrivilegedPermission() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
-        testInsertSim();
-
-        List<SubscriptionInfo> subInfoList =
-                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
-                        mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertTrue(info.getIccId().length() > 0);
-            assertTrue(info.getCardString().length() > 0);
-        }
-    }
-
-    @Test
-    @DisableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionsInGroupWithReadPhoneState() throws Exception {
-        // For backward compatibility test
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-        setupReadPhoneNumbersTest();
-        setIdentifierAccess(false);
-
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertEquals(UNAVAILABLE_ICCID, info.getIccId());
-            assertEquals(UNAVAILABLE_ICCID, info.getCardString());
-            assertEquals(UNAVAILABLE_NUMBER, info.getNumber());
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionsInGroupWithoutAppropriatePermission() throws Exception {
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-
-        // no permission
-        setNoPermission();
-        try {
-            mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid, mCallingPackage,
-                    mCallingFeature);
-            fail("getSubscriptionsInGroup should fail when invoked with no permissions");
-        } catch (SecurityException expected) {
-        }
-
-        // only has the device identifiers permission
-        setIdentifierAccess(true);
-        try {
-            mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid, mCallingPackage,
-                    mCallingFeature);
-            fail("getSubscriptionsInGroup should fail when invoked with no"
-                    + "READ_PHONE_STATE permissions");
-        } catch (SecurityException expected) {
-        }
-
-        // only has the READ_PHONE_STATE permission
-        setIdentifierAccess(false);
-        setReadPhoneState();
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-        assertNotNull(subInfoList);
-        assertTrue(subInfoList.isEmpty());
-    }
-
-    @Test
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionsInGroupWithReadDeviceIdentifier() throws Exception {
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-        setNoPermission();
-        setCarrierPrivileges(false);
-        setIdentifierAccess(true);
-        setReadPhoneState();
-
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertTrue(info.getIccId().length() > 0);
-            assertTrue(info.getCardString().length() > 0);
-        }
-    }
-
-    private void setNoPermission() {
-        doThrow(new SecurityException()).when(mContext)
-                .enforcePermission(anyString(), anyInt(), anyInt(), anyString());
-    }
-
-    private void setReadPhoneState() {
-        doNothing().when(mContext).enforcePermission(
-                eq(android.Manifest.permission.READ_PHONE_STATE), anyInt(), anyInt(), anyString());
-    }
-
-    @Test
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionInGroupWithPhoneNumberAccess() throws Exception {
-        // If the calling package meets any of the requirements for the
-        // LegacyPermissionManager#checkPhoneNumberAccess test then the number should be available
-        // in the SubscriptionInfo.
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-        setupReadPhoneNumbersTest();
-        setPhoneNumberAccess(PackageManager.PERMISSION_GRANTED);
-
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        SubscriptionInfo subInfo = subInfoList.get(0);
-        assertEquals(DISPLAY_NUMBER, subInfo.getNumber());
-    }
-
-    @Test
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionsInGroupWithCarrierPrivileges() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-        setupIdentifierCarrierPrivilegesTest();
-
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertTrue(info.getIccId().length() > 0);
-            assertTrue(info.getCardString().length() > 0);
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
-    public void testGetSubscriptionsInGroupWithPrivilegedPermission() throws Exception {
-        // If the calling package has the READ_PRIVILEGED_PHONE_STATE permission or carrier
-        // privileges the ICC ID should be available in the SubscriptionInfo objects in the List.
-        ParcelUuid groupUuid = setupGetSubscriptionsInGroupTest();
-
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupUuid, mCallingPackage, mCallingFeature);
-
-        assertTrue(subInfoList.size() > 0);
-        for (SubscriptionInfo info : subInfoList) {
-            assertTrue(info.getIccId().length() > 0);
-            assertTrue(info.getCardString().length() > 0);
-        }
-    }
-
-    private ParcelUuid setupGetSubscriptionsInGroupTest() throws Exception {
-        testInsertSim();
-        int[] subIdList = new int[]{getFirstSubId()};
-        ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(subIdList,
-                mCallingPackage);
-        assertNotNull(groupUuid);
-        doReturn(subIdList).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
-        return groupUuid;
-    }
-
-    private void setupReadPhoneNumbersTest() throws Exception {
-        mSubscriptionControllerUT.setDisplayNumber(DISPLAY_NUMBER, getFirstSubId());
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-        setupMocksForTelephonyPermissions(Build.VERSION_CODES.R);
-        setPhoneNumberAccess(PackageManager.PERMISSION_DENIED);
-    }
-
-    private void setupIdentifierCarrierPrivilegesTest() throws Exception {
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
-        setupMocksForTelephonyPermissions();
-        setIdentifierAccess(false);
-        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);
-    }
-
-    private int getSubIdAtIndex(int index) throws Exception {
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibileOnly*/false);
-        assertTrue(subIds != null && subIds.length > index);
-        return subIds[index];
-    }
-
-    @Test
-    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 [] uiccSlotInfos = {slot0, slot1};
-        UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
-
-        doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
-        doReturn(uiccSlots).when(mUiccController).getUiccSlots();
-        assertEquals(2, UiccController.getInstance().getUiccSlots().length);
-
-        ContentResolver resolver = mContext.getContentResolver();
-        // logical 0 should find physical 1, has settings enabled subscription 0
-        Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 1, 0);
-
-        int enabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(0);
-        assertEquals(0, enabledSubscription);
-    }
-
-    @Test
-    public void testGetEnabledSubscriptionIdDualSIM() {
-        doReturn(SINGLE_SIM).when(mTelephonyManager).getSimCount();
-        doReturn(SINGLE_SIM).when(mTelephonyManager).getPhoneCount();
-        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 [] uiccSlotInfos = {slot0, slot1};
-        UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
-
-        doReturn(2).when(mTelephonyManager).getPhoneCount();
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
-        doReturn(uiccSlots).when(mUiccController).getUiccSlots();
-        assertEquals(2, UiccController.getInstance().getUiccSlots().length);
-
-        ContentResolver resolver = mContext.getContentResolver();
-        // logical 0 should find physical 0, has settings enabled subscription 0
-        Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 0, 0);
-        Settings.Global.putInt(resolver, Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT + 1, 1);
-
-        int enabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(0);
-        int secondEabledSubscription = mSubscriptionControllerUT.getEnabledSubscriptionId(1);
-        assertEquals(0, enabledSubscription);
-        assertEquals(1, secondEabledSubscription);
-    }
-
-
-    private UiccSlotInfo getFakeUiccSlotInfo(boolean active, int logicalSlotIndex, String iccId) {
-        return getFakeUiccSlotInfo(active, logicalSlotIndex, "fake card Id", iccId);
-    }
-
-    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)
-                ));
-    }
-
-    @Test
-    @SmallTest
-    public void testNameSourcePriority() throws Exception {
-        assertTrue(mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_USER_INPUT)
-                > mSubscriptionControllerUT.getNameSourcePriority(
-                        SubscriptionManager.NAME_SOURCE_CARRIER));
-
-        assertTrue(mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_CARRIER)
-                > mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_SIM_SPN));
-
-        assertTrue(mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_SIM_SPN)
-                > mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_SIM_PNN));
-
-        assertTrue(mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_SIM_PNN)
-                > mSubscriptionControllerUT.getNameSourcePriority(
-                SubscriptionManager.NAME_SOURCE_CARRIER_ID));
-    }
-
-    @Test
-    @SmallTest
-    public void testGetAvailableSubscriptionList() throws Exception {
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("123", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 1
-        mSubscriptionControllerUT.addSubInfo("456", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 2
-
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getAvailableSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertEquals(2, infoList.size());
-        assertEquals("456", infoList.get(0).getIccId());
-        assertEquals("123", infoList.get(1).getIccId());
-
-        // Remove "123" from active sim list but have it inserted.
-        UiccSlot[] uiccSlots = {mUiccSlot};
-        IccCardStatus.CardState cardState = CARDSTATE_PRESENT;
-        doReturn(uiccSlots).when(mUiccController).getUiccSlots();
-        doReturn(cardState).when(mUiccSlot).getCardState();
-        doReturn("123").when(mUiccSlot).getIccId(0); // default port index
-        mSubscriptionControllerUT.clearSubInfoRecord(1);
-
-        // Active sub list should return 1 now.
-        infoList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertEquals(1, infoList.size());
-        assertEquals("456", infoList.get(0).getIccId());
-
-        // Available sub list should still return two.
-        infoList = mSubscriptionControllerUT
-                .getAvailableSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertEquals(2, infoList.size());
-        assertEquals("123", infoList.get(0).getIccId());
-        assertEquals("456", infoList.get(1).getIccId());
-    }
-
-    @Test
-    @SmallTest
-    public void testGetAvailableSubscriptionList_withTrailingF() throws Exception {
-        // TODO b/123300875 slot index 1 is not expected to be valid
-        mSubscriptionControllerUT.addSubInfo("123", null, 1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 1
-        mSubscriptionControllerUT.addSubInfo("456", null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM); // sub 2
-
-        // Remove "123" from active sim list but have it inserted.
-        UiccSlot[] uiccSlots = {mUiccSlot};
-        IccCardStatus.CardState cardState = CARDSTATE_PRESENT;
-        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
-
-        mSubscriptionControllerUT.clearSubInfoRecord(1);
-
-        // Active sub list should return 1 now.
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertEquals(1, infoList.size());
-        assertEquals("456", infoList.get(0).getIccId());
-
-        // Available sub list should still return two.
-        infoList = mSubscriptionControllerUT
-                .getAvailableSubscriptionInfoList(mCallingPackage, mCallingFeature);
-        assertEquals(2, infoList.size());
-        assertEquals("123", infoList.get(0).getIccId());
-        assertEquals("456", infoList.get(1).getIccId());
-    }
-
-    @Test
-    @SmallTest
-    public void testSetPreferredDataSubscriptionId_phoneSwitcherNotInitialized() throws Exception {
-        replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, null);
-
-        mSubscriptionControllerUT.setPreferredDataSubscriptionId(1, true, mSetOpptDataCallback);
-        verify(mSetOpptDataCallback).onComplete(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION);
-    }
-
-    @Test
-    @SmallTest
-    public void testGetPreferredDataSubscriptionId_phoneSwitcherNotInitialized() throws Exception {
-        replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, null);
-
-        assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                mSubscriptionControllerUT.getPreferredDataSubscriptionId());
-    }
-
-    @Test
-    public void testSetSubscriptionEnabled_disableActivePsim_cardIdWithTrailingF() {
-        String iccId = "123F";
-        mSubscriptionControllerUT.addSubInfo(iccId, null, 0,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-        mSubscriptionControllerUT.registerForUiccAppsEnabled(mHandler, 0, null, false);
-        UiccSlotInfo slot = getFakeUiccSlotInfo(true, 0, iccId + "FF", iccId);
-        UiccSlotInfo[] uiccSlotInfos = {slot};
-        doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
-
-        mSubscriptionControllerUT.setSubscriptionEnabled(false, 1);
-        verify(mHandler).sendMessageAtTime(any(), anyLong());
-        assertFalse(mSubscriptionControllerUT.getActiveSubscriptionInfo(
-                1, mContext.getOpPackageName(), null).areUiccApplicationsEnabled());
-    }
-
-    @Test
-    @SmallTest
-    public void testInsertEmptySubInfoRecord_returnsNull_ifRecordExists() {
-        final String mockedIccid = "123456789";
-        final int mockedSlotIndex = 1;
-
-        assertNotNull(mSubscriptionControllerUT.insertEmptySubInfoRecord(
-                mockedIccid, mockedSlotIndex));
-        // Insert second time with the same iccid should result in no-op and return null.
-        assertNull(mSubscriptionControllerUT.insertEmptySubInfoRecord(
-                mockedIccid, mockedSlotIndex));
-        assertEquals(
-                1,
-                mSubscriptionControllerUT
-                        .getAllSubInfoList(mCallingPackage, mCallingFeature).size());
-    }
-
-    @Test
-    @SmallTest
-    public void testCheckPhoneIdAndIccIdMatch() {
-        try {
-            testSetSubscriptionGroupWithModifyPermission();
-        } catch (Exception e) {
-            fail("Unexpected exception: " + e);
-        }
-
-        mSubscriptionControllerUT.addSubInfo("test3", null,
-                SubscriptionManager.INVALID_SIM_SLOT_INDEX,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-
-        assertTrue(mSubscriptionControllerUT.checkPhoneIdAndIccIdMatch(0, "test"));
-        assertTrue(mSubscriptionControllerUT.checkPhoneIdAndIccIdMatch(0, "test2"));
-        assertFalse(mSubscriptionControllerUT.checkPhoneIdAndIccIdMatch(0, "test3"));
-    }
-
-    @Test
-    @SmallTest
-    public void testMessageRefDBFetchAndUpdate() throws Exception {
-        testInsertSim();
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-        SubscriptionController.getInstance().updateMessageRef(subId, 201);
-        int messageRef = SubscriptionController.getInstance().getMessageRef(subId);
-        assertTrue("201 :", messageRef == 201);
-    }
-
-    @Test
-    public void setSubscriptionUserHandle_withoutPermission() {
-        testInsertSim();
-        enableGetSubscriptionUserHandle();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        assertThrows(SecurityException.class,
-                () -> mSubscriptionControllerUT.setSubscriptionUserHandle(
-                        UserHandle.of(UserHandle.USER_SYSTEM), subId));
-    }
-
-    @Test
-    public void setGetSubscriptionUserHandle_userHandleNull() {
-        testInsertSim();
-        enableGetSubscriptionUserHandle();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-
-        mSubscriptionControllerUT.setSubscriptionUserHandle(null, subId);
-
-        assertThat(mSubscriptionControllerUT.getSubscriptionUserHandle(subId))
-                .isEqualTo(null);
-    }
-
-    @Test
-    public void setSubscriptionUserHandle_invalidSubId() {
-        enableGetSubscriptionUserHandle();
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mSubscriptionControllerUT.setSubscriptionUserHandle(
-                        UserHandle.of(UserHandle.USER_SYSTEM),
-                        SubscriptionManager.DEFAULT_SUBSCRIPTION_ID));
-    }
-
-    @Test
-    public void setGetSubscriptionUserHandle_withValidUserHandleAndSubId() {
-        testInsertSim();
-        enableGetSubscriptionUserHandle();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-
-        mSubscriptionControllerUT.setSubscriptionUserHandle(
-                UserHandle.of(UserHandle.USER_SYSTEM), subId);
-
-        assertThat(mSubscriptionControllerUT.getSubscriptionUserHandle(subId))
-                .isEqualTo(UserHandle.of(UserHandle.USER_SYSTEM));
-    }
-
-    @Test
-    public void getSubscriptionUserHandle_withoutPermission() {
-        testInsertSim();
-        enableGetSubscriptionUserHandle();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        assertThrows(SecurityException.class,
-                () -> mSubscriptionControllerUT.getSubscriptionUserHandle(subId));
-    }
-
-    @Test
-    public void getSubscriptionUserHandle_invalidSubId() {
-        enableGetSubscriptionUserHandle();
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mSubscriptionControllerUT.getSubscriptionUserHandle(
-                        SubscriptionManager.DEFAULT_SUBSCRIPTION_ID));
-    }
-
-    @Test
-    public void isSubscriptionAssociatedWithUser_withoutPermission() {
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        assertThrows(SecurityException.class,
-                () -> mSubscriptionControllerUT.isSubscriptionAssociatedWithUser(1,
-                        UserHandle.of(UserHandle.USER_SYSTEM)));
-    }
-
-    @Test
-    public void isSubscriptionAssociatedWithUser_noSubscription() {
-        // isSubscriptionAssociatedWithUser should return true if there are no active subscriptions.
-        assertThat(mSubscriptionControllerUT.isSubscriptionAssociatedWithUser(1,
-                UserHandle.of(UserHandle.USER_SYSTEM))).isEqualTo(true);
-    }
-
-    @Test
-    public void isSubscriptionAssociatedWithUser_unknownSubId() {
-        testInsertSim();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        int unknownSubId = 123;
-
-        assertThat(mSubscriptionControllerUT.isSubscriptionAssociatedWithUser(unknownSubId,
-                UserHandle.of(UserHandle.USER_SYSTEM))).isEqualTo(false);
-    }
-
-    @Test
-    public void isSubscriptionAssociatedWithUser_userAssociatedWithSubscription() {
-        testInsertSim();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-
-        mSubscriptionControllerUT.setSubscriptionUserHandle(
-                UserHandle.of(UserHandle.USER_SYSTEM), subId);
-
-        assertThat(mSubscriptionControllerUT.isSubscriptionAssociatedWithUser(subId,
-                UserHandle.of(UserHandle.USER_SYSTEM))).isEqualTo(true);
-    }
-
-    @Test
-    public void isSubscriptionAssociatedWithUser_userNotAssociatedWithSubscription() {
-        testInsertSim();
-        enableGetSubscriptionUserHandle();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-
-        mSubscriptionControllerUT.setSubscriptionUserHandle(UserHandle.of(UserHandle.USER_SYSTEM),
-                subId);
-
-        assertThat(mSubscriptionControllerUT.isSubscriptionAssociatedWithUser(subId,
-                UserHandle.of(10))).isEqualTo(false);
-    }
-
-
-    @Test
-    public void getSubscriptionInfoListAssociatedWithUser_withoutPermission() {
-        mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-
-        assertThrows(SecurityException.class,
-                () -> mSubscriptionControllerUT.getSubscriptionInfoListAssociatedWithUser(
-                        UserHandle.of(UserHandle.USER_SYSTEM)));
-    }
-
-    @Test
-    public void getSubscriptionInfoListAssociatedWithUser_noSubscription() {
-        List<SubscriptionInfo> associatedSubInfoList = mSubscriptionControllerUT
-                .getSubscriptionInfoListAssociatedWithUser(UserHandle.of(UserHandle.USER_SYSTEM));
-        assertThat(associatedSubInfoList.size()).isEqualTo(0);
-    }
-
-    private void enableGetSubscriptionUserHandle() {
-        Resources mResources = mock(Resources.class);
-        doReturn(true).when(mResources).getBoolean(
-                eq(com.android.internal.R.bool.config_enable_get_subscription_user_handle));
-        doReturn(mResources).when(mContext).getResources();
-    }
-}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
deleted file mode 100644
index 868b53a..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * Copyright (C) 2016 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.SubscriptionManager.UICC_APPLICATIONS_ENABLED;
-
-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.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-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;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.content.pm.UserInfo;
-import android.net.Uri;
-import android.os.Looper;
-import android.os.ParcelUuid;
-import android.os.PersistableBundle;
-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.UiccAccessRule;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.euicc.EuiccController;
-import com.android.internal.telephony.uicc.IccFileHandler;
-import com.android.internal.telephony.uicc.IccRecords;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.UiccSlot;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-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;
-    private static final String FAKE_EID = "89049032000001000000031328322874";
-    private static final String FAKE_ICCID_1 = "89012604200000000000";
-    private static final String FAKE_MCC_MNC_1 = "123456";
-    private static final String FAKE_MCC_MNC_2 = "456789";
-    private static final int FAKE_PHONE_ID_1 = 0;
-
-    private SubscriptionInfoUpdater mUpdater;
-    private IccRecords mIccRecord;
-
-    // Mocked classes
-    private UserInfo mUserInfo;
-    private SubscriptionInfo mSubInfo;
-    private ContentProvider mContentProvider;
-    private HashMap<String, Object> mSubscriptionContent;
-    private IccFileHandler mIccFileHandler;
-    private EuiccController mEuiccController;
-    private IntentBroadcaster mIntentBroadcaster;
-    private IPackageManager mPackageManager;
-    private UiccSlot mUiccSlot;
-
-    /*Custom ContentProvider */
-    private class FakeSubscriptionContentProvider extends MockContentProvider {
-        @Override
-        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-            return mContentProvider.update(uri, values, selection, selectionArgs);
-        }
-    }
-
-    @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);
-
-        replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null, new String[1]);
-        replaceInstance(SubscriptionInfoUpdater.class, "sContext", null, null);
-        replaceInstance(SubscriptionInfoUpdater.class, "SUPPORTED_MODEM_COUNT", null, 1);
-        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]);
-        replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, new int[1]);
-        replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, false);
-
-        replaceInstance(EuiccController.class, "sInstance", null, mEuiccController);
-        replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster);
-
-        doReturn(true).when(mUiccSlot).isActive();
-        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
-        doReturn(1).when(mTelephonyManager).getSimCount();
-        doReturn(1).when(mTelephonyManager).getPhoneCount();
-        doReturn(1).when(mTelephonyManager).getActiveModemCount();
-
-        when(mContentProvider.update(any(), any(), any(), isNull())).thenAnswer(
-                new Answer<Integer>() {
-                    @Override
-                    public Integer answer(InvocationOnMock invocation) throws Throwable {
-                        ContentValues values = invocation.getArgument(1);
-                        for (String key : values.keySet()) {
-                            mSubscriptionContent.put(key, values.get(key));
-                        }
-                        return 1;
-                    }
-                });
-
-        doReturn(mUserInfo).when(mIActivityManager).getCurrentUser();
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(0);
-        doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionManager).getActiveSubscriptionIdList();
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-        doReturn(new int[]{}).when(mSubscriptionController)
-                .getActiveSubIdList(/*visibleOnly*/false);
-        mIccRecord = mUiccProfile.getIccRecords();
-
-        mUpdater =
-                new SubscriptionInfoUpdater(Looper.myLooper(), mContext, mSubscriptionController);
-        processAllMessages();
-
-        assertFalse(mUpdater.isSubInfoInitialized());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mIccRecord = null;
-        mUpdater = null;
-        super.tearDown();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimAbsent() throws Exception {
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
-        doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController)
-                .getActiveSubIdList(/*visibleOnly*/false);
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
-
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT));
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimAbsentAndInactive() throws Exception {
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .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);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
-
-        // Verify that in the special absent and inactive case, we update subscriptions without
-        // broadcasting SIM state change
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, times(0)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT));
-        verify(mContext, times(0)).sendBroadcast(any(), anyString());
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimUnknown() throws Exception {
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertFalse(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionContent, times(0)).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_UNKNOWN));
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimNotReady() throws Exception {
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
-
-        processAllMessages();
-        assertFalse(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionContent, never()).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, never()).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
-        verify(mSubscriptionController, never()).clearSubInfoRecord(FAKE_PHONE_ID_1);
-        verify(mSubscriptionController, never()).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimNotReadyEmptyProfile() throws Exception {
-        doReturn(mIccCard).when(mPhone).getIccCard();
-        doReturn(true).when(mIccCard).isEmptyProfile();
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        // Sub info should be cleared and change should be notified.
-        verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_PHONE_ID_1));
-        verify(mSubscriptionController).notifySubscriptionInfoChanged();
-        // No new sub should be added.
-        verify(mSubscriptionManager, never()).addSubscriptionInfoRecord(any(), anyInt());
-        verify(mSubscriptionContent, never()).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
-    }
-
-    @Test
-    @SmallTest
-    public void testSimNotReadyDisabledUiccApps() throws Exception {
-        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(mSubInfo).when(mSubscriptionController).getSubInfoForIccId(iccId);
-        doReturn(false).when(mSubInfo).areUiccApplicationsEnabled();
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        // Sub info should be cleared and change should be notified.
-        verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_PHONE_ID_1));
-        verify(mSubscriptionController).notifySubscriptionInfoChanged();
-        // No new sub should be added.
-        verify(mSubscriptionManager, never()).addSubscriptionInfoRecord(any(), anyInt());
-        verify(mSubscriptionContent, never()).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
-
-        // When becomes ABSENT, UICC_APPLICATIONS_ENABLED should be reset to true.
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_PHONE_ID_1);
-        processAllMessages();
-        ArgumentCaptor<ContentValues> valueCapture = ArgumentCaptor.forClass(ContentValues.class);
-        verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), valueCapture.capture(),
-                eq(SubscriptionManager.ICC_ID + "=\'" + iccId + "\'"), eq(null));
-        ContentValues contentValues = valueCapture.getValue();
-        assertTrue(contentValues != null && contentValues.getAsBoolean(
-                UICC_APPLICATIONS_ENABLED));
-    }
-
-    @Test
-    @SmallTest
-    public void testSimRemovedWhileDisablingUiccApps() throws Exception {
-        loadSim();
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
-        processAllMessages();
-
-        // UICC_APPLICATIONS_ENABLED should be reset to true.
-        ArgumentCaptor<ContentValues> valueCapture = ArgumentCaptor.forClass(ContentValues.class);
-        verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), valueCapture.capture(),
-                eq(SubscriptionManager.ICC_ID + "=\'" + FAKE_ICCID_1 + "\'"), eq(null));
-        ContentValues contentValues = valueCapture.getValue();
-        assertTrue(contentValues != null && contentValues.getAsBoolean(
-                UICC_APPLICATIONS_ENABLED));
-    }
-
-    @Test
-    @SmallTest
-    public void testSimError() throws Exception {
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionContent, times(0)).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR));
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testWrongSimState() throws Exception {
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2);
-
-        processAllMessages();
-        assertFalse(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionContent, times(0)).put(anyString(), any());
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, times(0)).updateConfigForPhoneId(eq(2),
-                eq(IccCardConstants.INTENT_VALUE_ICC_IMSI));
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
-    }
-
-    private void loadSim() {
-        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
-        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
-        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
-        when(mActivityManager.updateMccMncConfiguration(anyString(), anyString())).thenReturn(
-                true);
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
-    }
-
-    @Test
-    @SmallTest
-    public void testSimLoaded() throws Exception {
-        loadSim();
-
-        // verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for
-        // READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE
-        /* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent()
-         * uncomment code below when that is fixed
-         */
-        /* ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
-        ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture(),
-                stringArgumentCaptor.capture());
-        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
-                intentArgumentCaptor.getAllValues().get(0).getAction());
-        assertEquals(Manifest.permission.READ_PHONE_STATE,
-                stringArgumentCaptor.getAllValues().get(0));
-        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
-                intentArgumentCaptor.getAllValues().get(1).getAction());
-        assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                stringArgumentCaptor.getAllValues().get(1)); */
-
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(1)).setMccMnc(FAKE_MCC_MNC_1, FAKE_SUB_ID_1);
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
-
-        // ACTION_USER_UNLOCKED should trigger another SIM_STATE_CHANGED
-        Intent intentSimStateChanged = new Intent(Intent.ACTION_USER_UNLOCKED);
-        mContext.sendBroadcast(intentSimStateChanged);
-        processAllMessages();
-
-        // verify SIM_STATE_CHANGED broadcast
-        /* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent()
-         * uncomment code below when that is fixed
-         */
-        /* verify(mContext, times(4)).sendBroadcast(intentArgumentCaptor.capture(),
-                stringArgumentCaptor.capture());
-        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
-                intentArgumentCaptor.getAllValues().get(2).getAction());
-        assertEquals(Manifest.permission.READ_PHONE_STATE,
-                stringArgumentCaptor.getAllValues().get(2));
-        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
-                intentArgumentCaptor.getAllValues().get(3).getAction());
-        assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                stringArgumentCaptor.getAllValues().get(3)); */
-    }
-
-    @Test
-    @SmallTest
-    public void testSimLoadedEmptyOperatorNumeric() throws Exception {
-        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
-        // operator numeric is empty
-        doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
-        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
-    }
-
-    @Test
-    @SmallTest
-    public void testSimLockedWithOutIccId() throws Exception {
-        /* mock no IccId Info present and try to query IccId
-         after IccId query, update subscriptionDB */
-        doReturn("98106240020000000000").when(mIccRecord).getFullIccId();
-
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                eq("98106240020000000000"), eq(FAKE_SUB_ID_1));
-
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED));
-    }
-
-    @Test
-    @SmallTest
-    public void testDualSimLoaded() throws Exception {
-        // Mock there is two sim cards
-        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, mPhone});
-        replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,
-                new String[]{null, null});
-        replaceInstance(SubscriptionInfoUpdater.class, "SUPPORTED_MODEM_COUNT", null, 2);
-        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null,
-                new int[]{0, 0});
-        replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null,
-                new int[]{0, 0});
-
-        doReturn(new int[]{FAKE_SUB_ID_1, FAKE_SUB_ID_2}).when(mSubscriptionManager)
-                .getActiveSubscriptionIdList();
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_1));
-        doReturn(FAKE_SUB_ID_2).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_2));
-        doReturn(2).when(mTelephonyManager).getPhoneCount();
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        when(mActivityManager.updateMccMncConfiguration(anyString(), anyString())).thenReturn(
-                true);
-        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1));
-        doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2));
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt());
-        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());
-
-        // Mock sending a sim loaded for SIM 1
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
-
-        processAllMessages();
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt());
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt());
-        assertFalse(mUpdater.isSubInfoInitialized());
-
-        // Mock sending a sim loaded for SIM 2
-        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2));
-        doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId();
-        doReturn("89012604200000000001").when(mIccRecord).getFullIccId();
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2);
-
-        processAllMessages();
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq(FAKE_ICCID_1),
-                eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000001"),
-                eq(FAKE_SUB_ID_2));
-        verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2));
-        verify(mSubscriptionController, times(2)).notifySubscriptionInfoChanged();
-        assertTrue(mUpdater.isSubInfoInitialized());
-    }
-
-    @Test
-    @SmallTest
-    public void testSimLockWithIccId() throws Exception {
-        // ICCID will be queried even if it is already available
-        doReturn("98106240020000000000").when(mIccRecord).getFullIccId();
-
-        replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,
-                new String[]{FAKE_ICCID_1});
-
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1);
-
-        processAllMessages();
-        assertTrue(mUpdater.isSubInfoInitialized());
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                anyString(), eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        CarrierConfigManager mConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        /* broadcast is done */
-        verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
-                eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED));
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateEmbeddedSubscriptions_listSuccess() throws Exception {
-        when(mEuiccManager.isEnabled()).thenReturn(true);
-        when(mEuiccManager.createForCardId(anyInt())).thenReturn(mEuiccManager);
-        when(mEuiccManager.getEid()).thenReturn(FAKE_EID);
-
-        EuiccProfileInfo[] euiccProfiles = new EuiccProfileInfo[] {
-                new EuiccProfileInfo("1", null /* accessRules */, null /* nickname */),
-                new EuiccProfileInfo("3", null /* accessRules */, null /* nickname */),
-        };
-        when(mEuiccController.blockingGetEuiccProfileInfoList(FAKE_CARD_ID)).thenReturn(
-                new GetEuiccProfileInfoListResult(
-                        EuiccService.RESULT_OK, euiccProfiles, false /* removable */));
-
-        List<SubscriptionInfo> subInfoList = new ArrayList<>();
-        // 1: not embedded, but has matching iccid with an embedded subscription.
-        subInfoList.add(new SubscriptionInfo.Builder()
-                .setSimSlotIndex(0)
-                .setIccId("1")
-                .build());
-        // 2: embedded but no longer present.
-        subInfoList.add(new SubscriptionInfo.Builder()
-                .setSimSlotIndex(0)
-                .setIccId("2")
-                .setEmbedded(true)
-                .build());
-
-        when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
-                new String[] { "1", "3"}, false /* removable */)).thenReturn(subInfoList);
-
-        List<Integer> cardIds = new ArrayList<>();
-        cardIds.add(FAKE_CARD_ID);
-        mUpdater.updateEmbeddedSubscriptions(cardIds, null /* callback */);
-        processAllMessages();
-
-        // 3 is new and so a new entry should have been created.
-        verify(mSubscriptionController).insertEmptySubInfoRecord(
-                "3", SubscriptionManager.SIM_NOT_INSERTED);
-        // 1 already existed, so no new entries should be created for it.
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        verify(mSubscriptionController, never()).insertEmptySubInfoRecord(eq("1"), anyInt());
-
-        // 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());
-        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());
-        assertEquals(1,
-                iccid3Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
-
-        // 2 should have been removed since it was returned from the cache but was not present
-        // 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());
-        assertEquals(0,
-                iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateEmbeddedSubscriptions_listFailure() throws Exception {
-        when(mEuiccManager.isEnabled()).thenReturn(true);
-        when(mEuiccController.blockingGetEuiccProfileInfoList(FAKE_CARD_ID))
-                .thenReturn(new GetEuiccProfileInfoListResult(
-                        42, null /* subscriptions */, false /* removable */));
-
-        List<SubscriptionInfo> subInfoList = new ArrayList<>();
-        // 1: not embedded, but has matching iccid with an embedded subscription.
-        subInfoList.add(new SubscriptionInfo.Builder()
-                .setSimSlotIndex(0)
-                .setIccId("1")
-                .build());
-        // 2: embedded.
-        subInfoList.add(new SubscriptionInfo.Builder()
-                .setSimSlotIndex(0)
-                .setIccId("2")
-                .setEmbedded(true)
-                .build());
-
-        when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
-                new String[0], false /* removable */)).thenReturn(subInfoList);
-
-        ArrayList<Integer> cardIds = new ArrayList<>(1);
-        cardIds.add(FAKE_CARD_ID);
-        mUpdater.updateEmbeddedSubscriptions(cardIds, null /* callback */);
-
-        // No new entries should be created.
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt());
-
-        // No existing entries should have been updated.
-        verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(),
-                any(), isNull());
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateEmbeddedSubscriptions_emptyToEmpty() throws Exception {
-        when(mEuiccManager.isEnabled()).thenReturn(true);
-        when(mEuiccController.blockingGetEuiccProfileInfoList(FAKE_CARD_ID))
-                .thenReturn(new GetEuiccProfileInfoListResult(
-                        42, null /* subscriptions */, true /* removable */));
-
-        List<SubscriptionInfo> subInfoList = new ArrayList<>();
-        // 1: not embedded.
-        subInfoList.add(new SubscriptionInfo.Builder()
-                .setSimSlotIndex(0)
-                .setIccId("1")
-                .build());
-
-        when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate(
-                new String[0], false /* removable */)).thenReturn(subInfoList);
-
-        ArrayList<Integer> cardIds = new ArrayList<>(1);
-        cardIds.add(FAKE_CARD_ID);
-        mUpdater.updateEmbeddedSubscriptions(cardIds, null /* callback */);
-
-        // No new entries should be created.
-        verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt());
-
-        // No existing entries should have been updated.
-        verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(),
-                any(), isNull());
-    }
-
-    @Test
-    @SmallTest
-    public void testHexIccIdSuffix() throws Exception {
-        doReturn(null).when(mSubscriptionController)
-                .getSubInfoUsingSlotIndexPrivileged(anyInt());
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-        doReturn("890126042000000000Ff").when(mIccRecord).getFullIccId();
-
-        // Mock sending a sim loaded for SIM 1
-        mUpdater.updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_LOADED, "TESTING", FAKE_SUB_ID_1);
-
-        processAllMessages();
-
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("890126042000000000"),
-                eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionController, times(0)).clearSubInfo();
-    }
-
-    PersistableBundle getCarrierConfigForSubInfoUpdate(
-            boolean isOpportunistic, String groupUuid) {
-        PersistableBundle p = new PersistableBundle();
-        p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, isOpportunistic);
-        p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, groupUuid);
-        return p;
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigOpportunisticUnchanged() throws Exception {
-        final int phoneId = mPhone.getPhoneId();
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
-                carrierPackageName, new PersistableBundle());
-
-        //at each call to updateSubscriptionByCarrierConfig, only carrier certs are updated
-        verify(mContentProvider, times(1)).update(any(), any(), any(), any());
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigOpportunisticSetOpportunistic() throws Exception {
-        final int phoneId = mPhone.getPhoneId();
-        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
-                true, "");
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(false).when(mSubInfo).isOpportunistic();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        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));
-        assertEquals(1, cvCaptor.getValue().getAsInteger(
-                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
-        // 2 updates: isOpportunistic, and carrier certs:
-        assertEquals(2, cvCaptor.getValue().size());
-        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testOpportunisticSubscriptionNotUnsetWithEmptyConfigKey() throws Exception {
-        final int phoneId = mPhone.getPhoneId();
-        PersistableBundle carrierConfig = new PersistableBundle();
-
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(true).when(mSubInfo).isOpportunistic();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        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));
-        // no key is added for the opportunistic bit
-        assertNull(cvCaptor.getValue().getAsInteger(SubscriptionManager.IS_OPPORTUNISTIC));
-        // only carrier certs updated
-        assertEquals(1, cvCaptor.getValue().size());
-        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigOpportunisticAddToGroup() throws Exception {
-        final int phoneId = mPhone.getPhoneId();
-        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
-                true, "11111111-2222-3333-4444-555555555555");
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(true).when(mSubscriptionController).canPackageManageGroup(
-                ParcelUuid.fromString("11111111-2222-3333-4444-555555555555"), carrierPackageName);
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        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));
-        assertEquals(1, cvCaptor.getValue().getAsInteger(
-                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
-        assertEquals("11111111-2222-3333-4444-555555555555",
-                cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID));
-        assertEquals(carrierPackageName,
-                cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_OWNER));
-        // 4 updates: isOpportunistic, groupUuid, groupOwner, and carrier certs:
-        assertEquals(4, cvCaptor.getValue().size());
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigOpportunisticRemoveFromGroup() throws Exception {
-        final int phoneId = mPhone.getPhoneId();
-        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
-                true, "00000000-0000-0000-0000-000000000000");
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(true).when(mSubscriptionController).canPackageManageGroup(
-                ParcelUuid.fromString("11111111-2222-3333-4444-555555555555"), carrierPackageName);
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        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));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        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));
-        assertEquals(1, cvCaptor.getValue().getAsInteger(
-                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
-        assertNull(cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID));
-        // 3 updates: isOpportunistic, groupUuid, and carrier certs:
-        assertEquals(3, cvCaptor.getValue().size());
-    }
-
-    @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).getSubId(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";
-        certs[1] = "b5d6";
-
-        UiccAccessRule[] carrierConfigAccessRules = new UiccAccessRule[certs.length];
-        for (int i = 0; i < certs.length; i++) {
-            carrierConfigAccessRules[i] = new UiccAccessRule(
-                IccUtils.hexStringToBytes(certs[i]), null, 0);
-        }
-
-        final int phoneId = mPhone.getPhoneId();
-        PersistableBundle carrierConfig = new PersistableBundle();
-        carrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY, certs);
-
-        String carrierPackageName = "FakeCarrierPackageName";
-
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(false).when(mSubInfo).isOpportunistic();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        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));
-        assertEquals(carrierConfigAccessRules, UiccAccessRule.decodeRules(cvCaptor.getValue()
-                .getAsByteArray(SubscriptionManager.ACCESS_RULES_FROM_CARRIER_CONFIGS)));
-        assertEquals(1, cvCaptor.getValue().size());
-        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @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();
-
-        mUpdater.updateInternalIccState(
-            IccCardConstants.INTENT_VALUE_ICC_READY, "TESTING", FAKE_SUB_ID_1);
-        processAllMessages();
-
-        verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
-        assertTrue(mUpdater.isSubInfoInitialized());
-        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void testSimReadyAndLoaded() throws Exception {
-        replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,new String[]{""});
-
-        doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
-        doReturn(null).when(mUiccPort).getIccId();
-
-        mUpdater.updateInternalIccState(
-            IccCardConstants.INTENT_VALUE_ICC_READY, "TESTING", FAKE_SUB_ID_1);
-        processAllMessages();
-
-        verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(
-                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
-
-        loadSim();
-
-        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
-        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
-                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/TelephonyAdminReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyAdminReceiverTest.java
new file mode 100644
index 0000000..118daa5
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyAdminReceiverTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 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.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+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.Intent;
+import android.os.UserManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TelephonyAdminReceiverTest extends TelephonyTest {
+
+    private TelephonyAdminReceiver mTelephonyAdminReceiver;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        mTelephonyAdminReceiver = new TelephonyAdminReceiver(mContext, mPhone);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void test_nullUserManager() {
+        mUserManager = null;
+        TelephonyAdminReceiver telephonyAdminReceiver = new TelephonyAdminReceiver(mContext,
+                mPhone);
+        assertFalse(telephonyAdminReceiver.isCellular2gDisabled());
+    }
+
+    @Test
+    public void test_nullIntent_noUpdate() {
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+
+        mContext.sendBroadcast(new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED));
+
+        verify(mPhone, never()).sendSubscriptionSettings(anyBoolean());
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+    }
+
+    @Test
+    public void test_userRestrictionsNotChanged_noUpdate() {
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(false);
+
+        mContext.sendBroadcast(new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED));
+
+        verify(mPhone, never()).sendSubscriptionSettings(anyBoolean());
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+    }
+
+    @Test
+    public void test_userRestrictionToggled_shouldUpdate() {
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(
+                true).thenReturn(false);
+
+        mContext.sendBroadcast(new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED));
+        assertTrue(mTelephonyAdminReceiver.isCellular2gDisabled());
+
+        mContext.sendBroadcast(new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED));
+        assertFalse(mTelephonyAdminReceiver.isCellular2gDisabled());
+        verify(mPhone, times(2)).sendSubscriptionSettings(false);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 0e6e2f7..a053c56 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -37,6 +38,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.permission.LegacyPermissionManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
@@ -530,6 +532,14 @@
         }
     }
 
+    @Test
+    public void testCheckSubscriptionAssociatedWithUser_emergencyNumber() {
+        doReturn(true).when(mTelephonyManagerMock).isEmergencyNumber(anyString());
+
+        assertTrue(TelephonyPermissions.checkSubscriptionAssociatedWithUser(mMockContext, SUB_ID,
+                UserHandle.SYSTEM, "911"));
+    }
+
     // Put mMockTelephony into service cache so that TELEPHONY_SUPPLIER will get it.
     private void setTelephonyMockAsService() throws Exception {
         when(mMockTelephonyBinder.queryLocalInterface(anyString())).thenReturn(mMockTelephony);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 91dd89d..35a3186 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -25,7 +25,9 @@
 import static android.telephony.TelephonyManager.RADIO_POWER_UNAVAILABLE;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -35,9 +37,11 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.Manifest;
 import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.net.LinkProperties;
+import android.os.Build;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -108,6 +112,8 @@
     private CellLocation mCellLocation;
     private List<CellInfo> mCellInfo;
     private BarringInfo mBarringInfo = null;
+    private CellIdentity mCellIdentityForRegiFail;
+    private int mRegistrationFailReason;
 
     // All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
     private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -151,6 +157,8 @@
                 TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
         READ_PRIVILEGED_PHONE_STATE_EVENTS.add(
                 TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
+        READ_PRIVILEGED_PHONE_STATE_EVENTS.add(
+                TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED);
     }
 
     // All events contribute to TelephonyRegistry#isActiveEmergencySessionPermissionRequired
@@ -176,7 +184,8 @@
             TelephonyCallback.CellLocationListener,
             TelephonyCallback.ServiceStateListener,
             TelephonyCallback.CellInfoListener,
-            TelephonyCallback.BarringInfoListener {
+            TelephonyCallback.BarringInfoListener,
+            TelephonyCallback.RegistrationFailedListener {
         // 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);
@@ -250,6 +259,15 @@
             invocationCount.incrementAndGet();
             mBarringInfo = barringInfo;
         }
+
+        public void onRegistrationFailed(@android.annotation.NonNull CellIdentity cellIdentity,
+                @android.annotation.NonNull String chosenPlmn,
+                @NetworkRegistrationInfo.Domain int domain,
+                int causeCode, int additionalCauseCode) {
+            invocationCount.incrementAndGet();
+            mCellIdentityForRegiFail = cellIdentity;
+            mRegistrationFailReason = causeCode;
+        }
     }
 
     private void addTelephonyRegistryService() {
@@ -897,24 +915,48 @@
     }
 
     @Test
-    public void testBarringInfoChanged() {
+    public void testBarringInfoChangedWithLocationFinePermission() throws Exception {
+        checkBarringInfoWithLocationPermission(Manifest.permission.ACCESS_FINE_LOCATION);
+    }
+
+    @Test
+    public void testBarringInfoChangedLocationCoarsePermission() throws Exception {
+        checkBarringInfoWithLocationPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
+    }
+
+    @Test
+    public void testBarringInfoChangedWithoutLocationPermission() throws Exception {
+        checkBarringInfoWithLocationPermission(null);
+    }
+
+    private void checkBarringInfoWithLocationPermission(String permission) 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();
         doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
 
+        mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.TIRAMISU;
+        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(anyString(), anyInt());
+        mContextFixture.addCallingOrSelfPermission("");
+        mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+        mContextFixture.addCallingOrSelfPermission(
+                android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+        if (permission != null) {
+            mContextFixture.addCallingOrSelfPermission(permission);
+        }
+
         final int subId = 1;
         int[] events = {TelephonyCallback.EVENT_BARRING_INFO_CHANGED};
         SparseArray<BarringInfo.BarringServiceInfo> bsi = new SparseArray(1);
-        bsi.set(BarringInfo.BARRING_SERVICE_TYPE_MO_DATA,
+        bsi.set(BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE,
                 new BarringInfo.BarringServiceInfo(
                         BarringInfo.BarringServiceInfo.BARRING_TYPE_CONDITIONAL,
                         false /*isConditionallyBarred*/,
                         30 /*conditionalBarringFactor*/,
                         10 /*conditionalBarringTimeSeconds*/));
-        BarringInfo info = new BarringInfo(new CellIdentityLte(), bsi);
-
-        // Registering for info causes Barring Info to be sent to caller
+        BarringInfo info = new BarringInfo(
+                new CellIdentityLte(777, 333, 12345, 222, 13579), bsi);
+        // 1. Register listener which requires location access.
         mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
@@ -925,12 +967,115 @@
         mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
         processAllMessages();
         assertEquals(2, mTelephonyCallback.invocationCount.get());
-        assertEquals(mBarringInfo, info);
+        assertEquals(mBarringInfo
+                        .getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE),
+                info.getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE));
+        String log = mBarringInfo.toString();
+        assertTrue(log.contains("777"));
+        assertTrue(log.contains("333"));
+        if (permission != null && permission.equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
+            assertTrue(log.contains("12345"));
+            assertTrue(log.contains("222"));
+            assertTrue(log.contains("13579"));
+        } else {
+            assertFalse(log.contains("12345"));
+            assertFalse(log.contains("222"));
+            assertFalse(log.contains("13579"));
+        }
 
         // Duplicate BarringInfo notifications do not trigger callback
         mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
         processAllMessages();
         assertEquals(2, mTelephonyCallback.invocationCount.get());
+
+        mTelephonyRegistry.listenWithEventList(true, true, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, new int[0], true);
+        // 2. Register listener renounces location access.
+        mTelephonyRegistry.listenWithEventList(true, true, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+        processAllMessages();
+        // check receiving barring info without location info.
+        assertEquals(3, mTelephonyCallback.invocationCount.get());
+        assertNotNull(mBarringInfo);
+        assertEquals(mBarringInfo
+                        .getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE),
+                info.getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE));
+        log = mBarringInfo.toString();
+        assertTrue(log.contains("777"));
+        assertTrue(log.contains("333"));
+        assertFalse(log.contains("12345"));
+        assertFalse(log.contains("222"));
+        assertFalse(log.contains("13579"));
+    }
+
+    @Test
+    public void testRegistrationFailedEventWithLocationFinePermission() throws Exception {
+        checkRegistrationFailedEventWithLocationPermission(
+                Manifest.permission.ACCESS_FINE_LOCATION);
+    }
+    @Test
+    public void testRegistrationFailedEventWithLocationCoarsePermission() throws Exception {
+        checkRegistrationFailedEventWithLocationPermission(
+                Manifest.permission.ACCESS_COARSE_LOCATION);
+    }
+
+    @Test
+    public void testRegistrationFailedEventWithoutLocationPermission() throws Exception {
+        checkRegistrationFailedEventWithLocationPermission(null);
+    }
+
+    private void checkRegistrationFailedEventWithLocationPermission(String permission)
+            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();
+        doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+        mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.TIRAMISU;
+        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(anyString(), anyInt());
+        mContextFixture.addCallingOrSelfPermission("");
+        mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+        mContextFixture.addCallingOrSelfPermission(
+                android.Manifest.permission.READ_PRECISE_PHONE_STATE);
+        if (permission != null) {
+            mContextFixture.addCallingOrSelfPermission(permission);
+        }
+
+        final int subId = 1;
+        int[] events = {TelephonyCallback.EVENT_REGISTRATION_FAILURE};
+        CellIdentity cellIdentity =
+                new CellIdentityLte(777, 333, 12345, 227, 13579);
+
+        // 1. Register listener which requires location access.
+        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+        processAllMessages();
+        int invocationCount = mTelephonyCallback.invocationCount.get();
+        // Updating the RegistrationFailed info to be updated
+        mTelephonyRegistry.notifyRegistrationFailed(
+                0, subId, cellIdentity, "88888", 1, 333, 22);
+        processAllMessages();
+        assertEquals(invocationCount + 1, mTelephonyCallback.invocationCount.get());
+        if (permission != null && permission.equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
+            assertEquals(cellIdentity, mCellIdentityForRegiFail);
+        } else {
+            assertEquals(cellIdentity.sanitizeLocationInfo(), mCellIdentityForRegiFail);
+        }
+        assertEquals(333, mRegistrationFailReason);
+        mTelephonyRegistry.listenWithEventList(true, true, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, new int[0], true);
+
+        // 2. Register listener which renounces location access.
+        mTelephonyRegistry.listenWithEventList(true, true, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+        invocationCount = mTelephonyCallback.invocationCount.get();
+        // Updating the RegistrationFailed info to be updated
+        mTelephonyRegistry.notifyRegistrationFailed(
+                0, subId, cellIdentity, "88888", 1, 555, 22);
+        processAllMessages();
+        assertEquals(invocationCount + 1, mTelephonyCallback.invocationCount.get());
+        assertEquals(cellIdentity.sanitizeLocationInfo(), mCellIdentityForRegiFail);
+        assertEquals(555, mRegistrationFailReason);
     }
 
     /**
@@ -1170,12 +1315,9 @@
         final int subId = 1;
 
         // Return a slotIndex / phoneId of 0 for subId 1.
-        doReturn(subId).when(mSubscriptionController).getSubId(phoneId);
+        doReturn(subId).when(mSubscriptionManagerService).getSubId(phoneId);
         doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(subId);
         doReturn(phoneId).when(mMockSubInfo).getSimSlotIndex();
-        mServiceManagerMockedServices.put("isub", mSubscriptionController);
-        doReturn(mSubscriptionController).when(mSubscriptionController)
-                .queryLocalInterface(anyString());
 
         UserInfo userInfo = new UserInfo(UserHandle.myUserId(), "" /* name */, 0 /* flags */);
         doReturn(userInfo.id).when(mIActivityManager).getCurrentUserId();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index da120d7..b044814 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -16,7 +16,8 @@
 
 package com.android.internal.telephony;
 
-import static org.junit.Assert.assertNotNull;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN;
+
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -107,13 +108,18 @@
 import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
+import com.android.internal.telephony.imsphone.ImsNrSaModeHandler;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
+import com.android.internal.telephony.metrics.DeviceStateHelper;
 import com.android.internal.telephony.metrics.ImsStats;
 import com.android.internal.telephony.metrics.MetricsCollector;
 import com.android.internal.telephony.metrics.PersistAtomsStorage;
+import com.android.internal.telephony.metrics.ServiceStateStats;
 import com.android.internal.telephony.metrics.SmsStats;
 import com.android.internal.telephony.metrics.VoiceCallSessionStats;
+import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.test.SimulatedCommandsVerifier;
 import com.android.internal.telephony.uicc.IccCardStatus;
@@ -177,6 +183,7 @@
 
     // Mocked classes
     protected GsmCdmaPhone mPhone;
+    protected GsmCdmaPhone mPhone2;
     protected ImsPhone mImsPhone;
     protected ServiceStateTracker mSST;
     protected EmergencyNumberTracker mEmergencyNumberTracker;
@@ -184,6 +191,7 @@
     protected ImsPhoneCallTracker mImsCT;
     protected UiccController mUiccController;
     protected UiccProfile mUiccProfile;
+    protected UiccSlot mUiccSlot;
     protected CallManager mCallManager;
     protected PhoneNotifier mNotifier;
     protected TelephonyComponentFactory mTelephonyComponentFactory;
@@ -200,7 +208,7 @@
     protected GsmCdmaCall mGsmCdmaCall;
     protected ImsCall mImsCall;
     protected ImsEcbm mImsEcbm;
-    protected SubscriptionController mSubscriptionController;
+    protected SubscriptionManagerService mSubscriptionManagerService;
     protected ServiceState mServiceState;
     protected IPackageManager.Stub mMockPackageManager;
     protected LegacyPermissionManagerService mMockLegacyPermissionManager;
@@ -228,6 +236,7 @@
     protected CarrierSignalAgent mCarrierSignalAgent;
     protected CarrierActionAgent mCarrierActionAgent;
     protected ImsExternalCallTracker mImsExternalCallTracker;
+    protected ImsNrSaModeHandler mImsNrSaModeHandler;
     protected AppSmsManager mAppSmsManager;
     protected IccSmsInterfaceManager mIccSmsInterfaceManager;
     protected SmsDispatchersController mSmsDispatchersController;
@@ -236,7 +245,6 @@
     protected IntentBroadcaster mIntentBroadcaster;
     protected NitzStateMachine mNitzStateMachine;
     protected RadioConfig mMockRadioConfig;
-    protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
     protected LocaleTracker mLocaleTracker;
     protected RestrictedState mRestrictedState;
     protected PhoneConfigurationManager mPhoneConfigurationManager;
@@ -262,6 +270,9 @@
     protected CellLocation mCellLocation;
     protected DataServiceManager mMockedWwanDataServiceManager;
     protected DataServiceManager mMockedWlanDataServiceManager;
+    protected ServiceStateStats mServiceStateStats;
+    protected SatelliteController mSatelliteController;
+    protected DeviceStateHelper mDeviceStateHelper;
 
     // Initialized classes
     protected ActivityManager mActivityManager;
@@ -408,6 +419,7 @@
         TAG = tag;
         enableStrictMode();
         mPhone = Mockito.mock(GsmCdmaPhone.class);
+        mPhone2 = Mockito.mock(GsmCdmaPhone.class);
         mImsPhone = Mockito.mock(ImsPhone.class);
         mSST = Mockito.mock(ServiceStateTracker.class);
         mEmergencyNumberTracker = Mockito.mock(EmergencyNumberTracker.class);
@@ -415,6 +427,7 @@
         mImsCT = Mockito.mock(ImsPhoneCallTracker.class);
         mUiccController = Mockito.mock(UiccController.class);
         mUiccProfile = Mockito.mock(UiccProfile.class);
+        mUiccSlot = Mockito.mock(UiccSlot.class);
         mCallManager = Mockito.mock(CallManager.class);
         mNotifier = Mockito.mock(PhoneNotifier.class);
         mTelephonyComponentFactory = Mockito.mock(TelephonyComponentFactory.class);
@@ -431,7 +444,7 @@
         mGsmCdmaCall = Mockito.mock(GsmCdmaCall.class);
         mImsCall = Mockito.mock(ImsCall.class);
         mImsEcbm = Mockito.mock(ImsEcbm.class);
-        mSubscriptionController = Mockito.mock(SubscriptionController.class);
+        mSubscriptionManagerService = Mockito.mock(SubscriptionManagerService.class);
         mServiceState = Mockito.mock(ServiceState.class);
         mMockPackageManager = Mockito.mock(IPackageManager.Stub.class);
         mMockLegacyPermissionManager = Mockito.mock(LegacyPermissionManagerService.class);
@@ -459,6 +472,7 @@
         mCarrierSignalAgent = Mockito.mock(CarrierSignalAgent.class);
         mCarrierActionAgent = Mockito.mock(CarrierActionAgent.class);
         mImsExternalCallTracker = Mockito.mock(ImsExternalCallTracker.class);
+        mImsNrSaModeHandler = Mockito.mock(ImsNrSaModeHandler.class);
         mAppSmsManager = Mockito.mock(AppSmsManager.class);
         mIccSmsInterfaceManager = Mockito.mock(IccSmsInterfaceManager.class);
         mSmsDispatchersController = Mockito.mock(SmsDispatchersController.class);
@@ -467,7 +481,6 @@
         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);
         mPhoneConfigurationManager = Mockito.mock(PhoneConfigurationManager.class);
@@ -493,6 +506,9 @@
         mCellLocation = Mockito.mock(CellLocation.class);
         mMockedWwanDataServiceManager = Mockito.mock(DataServiceManager.class);
         mMockedWlanDataServiceManager = Mockito.mock(DataServiceManager.class);
+        mServiceStateStats = Mockito.mock(ServiceStateStats.class);
+        mSatelliteController = Mockito.mock(SatelliteController.class);
+        mDeviceStateHelper = Mockito.mock(DeviceStateHelper.class);
 
         TelephonyManager.disableServiceHandleCaching();
         PropertyInvalidatedCache.disableForTestMode();
@@ -518,9 +534,15 @@
 
         Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
 
+        mServiceManagerMockedServices.put("isub", mSubscriptionManagerService);
+        doReturn(mSubscriptionManagerService).when(mSubscriptionManagerService)
+                .queryLocalInterface(anyString());
+
         mPhone.mCi = mSimulatedCommands;
         mCT.mCi = mSimulatedCommands;
         doReturn(mUiccCard).when(mPhone).getUiccCard();
+        doReturn(mUiccCard).when(mUiccSlot).getUiccCard();
+        doReturn(mUiccCard).when(mUiccController).getUiccCardForPhone(anyInt());
         doReturn(mUiccPort).when(mPhone).getUiccPort();
         doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
 
@@ -574,6 +596,8 @@
                         anyInt(), nullable(Object.class));
         doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory)
                 .makeImsExternalCallTracker(nullable(ImsPhone.class));
+        doReturn(mImsNrSaModeHandler).when(mTelephonyComponentFactory)
+                .makeImsNrSaModeHandler(nullable(ImsPhone.class));
         doReturn(mAppSmsManager).when(mTelephonyComponentFactory)
                 .makeAppSmsManager(nullable(Context.class));
         doReturn(mCarrierSignalAgent).when(mTelephonyComponentFactory)
@@ -662,7 +686,8 @@
                 }
             }
         }).when(mUiccController).getIccRecords(anyInt(), anyInt());
-        doReturn(new UiccSlot[] {}).when(mUiccController).getUiccSlots();
+        doReturn(new UiccSlot[] {mUiccSlot}).when(mUiccController).getUiccSlots();
+        doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
         doReturn(mPinStorage).when(mUiccController).getPinStorage();
 
         //UiccCardApplication
@@ -704,7 +729,14 @@
         doReturn(mPhone).when(mInboundSmsHandler).getPhone();
         doReturn(mImsCallProfile).when(mImsCall).getCallProfile();
         doReturn(mIBinder).when(mIIntentSender).asBinder();
-        doReturn(mIIntentSender).when(mIActivityManager).getIntentSenderWithFeature(anyInt(),
+        doAnswer(invocation -> {
+            Intent[] intents = invocation.getArgument(6);
+            if (intents != null && intents.length > 0) {
+                doReturn(intents[0]).when(mIActivityManager)
+                        .getIntentForIntentSender(mIIntentSender);
+            }
+            return mIIntentSender;
+        }).when(mIActivityManager).getIntentSenderWithFeature(anyInt(),
                 nullable(String.class), nullable(String.class), nullable(IBinder.class),
                 nullable(String.class), anyInt(), nullable(Intent[].class),
                 nullable(String[].class), anyInt(), nullable(Bundle.class), anyInt());
@@ -713,6 +745,7 @@
 
         doReturn(TelephonyManager.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType();
         doReturn(mServiceState).when(mSST).getServiceState();
+        doReturn(mServiceStateStats).when(mSST).getServiceStateStats();
         mSST.mSS = mServiceState;
         mSST.mRestrictedState = mRestrictedState;
         mServiceManagerMockedServices.put("connectivity_metrics_logger", mConnMetLoggerBinder);
@@ -722,13 +755,10 @@
         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(true).when(mDataSettingsManager).isDataEnabled();
         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
                 anyInt(), anyInt());
-        doReturn(RIL.RADIO_HAL_VERSION_2_0).when(mPhone).getHalVersion();
+        doReturn(RIL.RADIO_HAL_VERSION_2_0).when(mPhone).getHalVersion(anyInt());
         doReturn(2).when(mSignalStrength).getLevel();
 
         // WiFi
@@ -803,6 +833,11 @@
         doReturn(null).when(mContext).getFileStreamPath(anyString());
         doReturn(mPersistAtomsStorage).when(mMetricsCollector).getAtomsStorage();
         doReturn(mWifiManager).when(mContext).getSystemService(eq(Context.WIFI_SERVICE));
+        doReturn(mDeviceStateHelper).when(mMetricsCollector).getDeviceStateHelper();
+        doReturn(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN)
+                .when(mDeviceStateHelper)
+                .getFoldState();
+        doReturn(null).when(mContext).getSystemService(eq(Context.DEVICE_STATE_SERVICE));
 
         //Use reflection to mock singletons
         replaceInstance(CallManager.class, "INSTANCE", null, mCallManager);
@@ -810,7 +845,8 @@
                 mTelephonyComponentFactory);
         replaceInstance(UiccController.class, "mInstance", null, mUiccController);
         replaceInstance(CdmaSubscriptionSourceManager.class, "sInstance", null, mCdmaSSM);
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController);
+        replaceInstance(SubscriptionManagerService.class, "sInstance", null,
+                mSubscriptionManagerService);
         replaceInstance(ProxyController.class, "sProxyController", null, mProxyController);
         replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mPhoneSwitcher);
         replaceInstance(ActivityManager.class, "IActivityManagerSingleton", null,
@@ -829,7 +865,6 @@
         replaceInstance(PhoneFactory.class, "sMadeDefaults", null, true);
         replaceInstance(PhoneFactory.class, "sPhone", null, mPhone);
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
-        replaceInstance(PhoneFactory.class, "sSubInfoRecordUpdater", null, mSubInfoRecordUpdater);
         replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig);
         replaceInstance(PhoneConfigurationManager.class, "sInstance", null,
                 mPhoneConfigurationManager);
@@ -837,13 +872,11 @@
                 mCellularNetworkValidator);
         replaceInstance(MultiSimSettingController.class, "sInstance", null,
                 mMultiSimSettingController);
-        replaceInstance(SubscriptionInfoUpdater.class, "sIsSubInfoInitialized", null, true);
         replaceInstance(PhoneFactory.class, "sCommandsInterfaces", null,
                 new CommandsInterface[] {mSimulatedCommands});
         replaceInstance(PhoneFactory.class, "sMetricsCollector", null, mMetricsCollector);
+        replaceInstance(SatelliteController.class, "sInstance", null, mSatelliteController);
 
-        assertNotNull("Failed to set up SubscriptionController singleton",
-                SubscriptionController.getInstance());
         setReady(false);
         // create default TestableLooper for test and add to list of monitored loopers
         mTestableLooper = TestableLooper.get(TelephonyTest.this);
@@ -941,14 +974,17 @@
         private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
                 DeviceConfig.NAMESPACE_PRIVACY + "/"
                         + "device_identifier_access_restrictions_disabled";
+        private HashMap<String, String> mFlags = new HashMap<>();
 
         @Override
         public Bundle call(String method, String arg, Bundle extras) {
+            logd("FakeSettingsConfigProvider: call called,  method: " + method +
+                    " request: " + arg + ", args=" + extras);
+            Bundle bundle = new Bundle();
             switch (method) {
                 case Settings.CALL_METHOD_GET_CONFIG: {
                     switch (arg) {
                         case PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED: {
-                            Bundle bundle = new Bundle();
                             bundle.putString(
                                     PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED,
                                     "0");
@@ -960,6 +996,18 @@
                     }
                     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 = (extras != null)
+                            ? (HashMap) extras.getSerializable(Settings.CALL_METHOD_FLAGS_KEY)
+                            : new HashMap<>();
+                    bundle.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN,
+                            Settings.SET_ALL_RESULT_SUCCESS);
+                    return bundle;
                 default:
                     fail("Method not expected: " + method);
             }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
index f09c94e..9f76337 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
@@ -96,7 +96,7 @@
         VisualVoicemailSmsFilter.setPhoneAccountHandleConverterForTest(
                 new PhoneAccountHandleConverter() {
                     @Override
-                    public PhoneAccountHandle fromSubId(int subId) {
+                    public PhoneAccountHandle fromSubId(int subId, Context context) {
                         return new PhoneAccountHandle(
                                 new ComponentName("com.android.internal.telephony",
                                         "VisualVoicemailSmsFilterTest"), "foo");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cat/CATServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/cat/CATServiceTest.java
new file mode 100644
index 0000000..f2c1870
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/cat/CATServiceTest.java
@@ -0,0 +1,315 @@
+/*
+ * 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.cat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.ProxyController;
+import com.android.internal.telephony.SmsController;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.test.SimulatedCommands;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.IccFileHandler;
+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.UiccProfile;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class CATServiceTest extends TelephonyTest {
+
+    private static final String SMS_SENT_ACTION =
+            "com.android.internal.telephony.cat.SMS_SENT_ACTION";
+    private static final String SMS_DELIVERY_ACTION =
+            "com.android.internal.telephony.cat.SMS_DELIVERY_ACTION";
+    //Mocked Classes
+    @Mock
+    private RilMessageDecoder mRilMessageDecoder;
+    private IccFileHandler mIccFileHandler;
+    private SmsController mSmsController;
+    private CommandDetails mCommandDetails;
+    private CatService mCatService;
+    private IccCardStatus mIccCardStatus;
+    private IccIoResult mIccIoResult;
+    private String mData =
+            "D059810301130082028183051353656E64696E672072657175657374202E2E2E0607911989548056780B"
+                    + "3051FF05812143F500F6082502700000201115001500BFFF01BA23C2169EA9B02D7A7FBAA0"
+                    + "DAABFEE8B8DE9DA06DCD234E";
+    private byte[] mRawdata = IccUtils.hexStringToBytes(mData);
+    private List<ComprehensionTlv> mCtlvs;
+
+    /**
+     * Terminal Response with result code in last 3 bytes = length + SMS_RP_ERROR(0x35)
+     * + ErrorCode(= 41)
+     */
+    private String mTerminalResponseForSmsRpError = "81030113000202828183023529";
+
+    /**
+     * Terminal Response with result code in last 3 bytes = length + NETWORK_UNABLE_TO_PROCESS(0x21)
+     * + ErrorCode(= 41 with 8th bit set to 1)
+     */
+    private String mTerminalResponseForNetworkUnableToProcess = "810301130002028281830221A9";
+
+    /**
+     * Terminal Response with result code in last 2 bytes = length
+     * + TERMINAL_UNABLE_TO_PROCESS(0x20)
+     */
+    private String mTerminalResponseForTerminalUnableToProcess = "810301130002028281830120";
+
+    //Terminal Response with result code(0x00)for delivery success in last 2 bytes
+    private String mTerminalResponseForDeliverySuccess = "810301130002028281830100";
+
+    public CATServiceTest() {
+        super();
+    }
+
+    private IccCardApplicationStatus composeUiccApplicationStatus(
+            IccCardApplicationStatus.AppType appType,
+            IccCardApplicationStatus.AppState appState, String aid) {
+        IccCardApplicationStatus mIccCardAppStatus = new IccCardApplicationStatus();
+        mIccCardAppStatus.aid = aid;
+        mIccCardAppStatus.app_type = appType;
+        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());
+        mRilMessageDecoder = mock(RilMessageDecoder.class);
+        mIccFileHandler = mock(IccFileHandler.class);
+        mSmsController = mock(SmsController.class);
+        mIccCardStatus = mock(IccCardStatus.class);
+        mProxyController = mock(ProxyController.class);
+        mUiccCard = mock(UiccCard.class);
+        IccCardApplicationStatus umtsApp = composeUiccApplicationStatus(
+                IccCardApplicationStatus.AppType.APPTYPE_USIM,
+                IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA2");
+        mIccCardStatus.mApplications = new IccCardApplicationStatus[]{umtsApp};
+        mIccCardStatus.mCdmaSubscriptionAppIndex =
+                mIccCardStatus.mImsSubscriptionAppIndex =
+                        mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
+        mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
+        mSimulatedCommands = mock(SimulatedCommands.class);
+        mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
+        mUiccProfile = new UiccProfile(mContext, mSimulatedCommands, mIccCardStatus,
+                0 /* phoneId */, mUiccCard, new Object());
+        processAllMessages();
+        logd("Created UiccProfile");
+        processAllMessages();
+        mCatService = CatService.getInstance(mSimulatedCommands, mContext,
+                mUiccProfile, mUiccController.getSlotIdFromPhoneId(0));
+        logd("Created CATService");
+        createCommandDetails();
+        createComprehensionTlvList();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mCatService.dispose();
+        mUiccProfile = null;
+        mCatService = null;
+        mCtlvs = null;
+        mProxyController = null;
+        mRilMessageDecoder = null;
+        mCommandDetails = null;
+        mContext = null;
+        mSimulatedCommands = null;
+        mIccCardStatus = null;
+        mIccCard = null;
+        mIccFileHandler = null;
+        mIccIoResult = null;
+        mSmsController = null;
+        super.tearDown();
+    }
+
+    private void createCommandDetails() {
+        mCommandDetails = mock(CommandDetails.class);
+        mCommandDetails.compRequired = true;
+        mCommandDetails.commandNumber = 1;
+        mCommandDetails.typeOfCommand = 19;
+        mCommandDetails.commandQualifier = 0;
+    }
+
+    private void createComprehensionTlvList() {
+        ComprehensionTlv ctlv1 = new ComprehensionTlv(1, false, 3, mRawdata, 4);
+        ComprehensionTlv ctlv2 = new ComprehensionTlv(2, false, 2, mRawdata, 9);
+        ComprehensionTlv ctlv3 = new ComprehensionTlv(5, false, 19, mRawdata, 13);
+        ComprehensionTlv ctlv4 = new ComprehensionTlv(6, false, 7, mRawdata, 34);
+        ComprehensionTlv ctlv5 = new ComprehensionTlv(11, false, 48, mRawdata, 43);
+        mCtlvs = new ArrayList<>();
+        mCtlvs.add(ctlv1);
+        mCtlvs.add(ctlv2);
+        mCtlvs.add(ctlv3);
+        mCtlvs.add(ctlv4);
+        mCtlvs.add(ctlv5);
+    }
+
+    @Test
+    public void testSendSmsCommandParams() throws Exception {
+        ComprehensionTlv ctlv = new ComprehensionTlv(11, false, 48, mRawdata, 43);
+        SmsMessage smsMessage = ValueParser.retrieveTpduAsSmsMessage(ctlv);
+        assertNotNull(smsMessage);
+        assertEquals("12345", smsMessage.getRecipientAddress());
+    }
+
+    @Test
+    public void testSendSTKSmsViaCatService() {
+        CommandParams cmdPrms = new CommandParams(mCommandDetails);
+        when(mProxyController.getSmsController()).thenReturn(mSmsController);
+        mCatService.sendStkSms("test", "12345", 1, cmdPrms, mProxyController);
+        verify(mSmsController, Mockito.times(1)).sendTextForSubscriber(anyInt(),
+                anyString(), nullable(String.class), anyString(), nullable(String.class),
+                anyString(), Mockito.anyObject(), any(), eq(false), anyLong(), eq(true), eq(true));
+    }
+
+    @Test
+    public void testprocessSMSEventNotify() throws Exception {
+        CommandParamsFactory cmdPF = CommandParamsFactory.getInstance(mRilMessageDecoder,
+                mIccFileHandler, mContext);
+        assertEquals(false, cmdPF.processSMSEventNotify(mCommandDetails, mCtlvs));
+    }
+
+    @Test
+    public void testSkipFdnCheckforSTKSmsViaCatService() {
+        CommandParams cmdPrms = new CommandParams(mCommandDetails);
+        when(mProxyController.getSmsController()).thenReturn(mSmsController);
+        mCatService.sendStkSms("test", "12345", 1, cmdPrms, mProxyController);
+        verify(mSmsController, Mockito.times(0)).isNumberBlockedByFDN(1, "12345",
+                "com.android.internal.telephony");
+    }
+
+    //Create and assign a PendingResult object in BroadcastReceiver with which resultCode is updated
+    private void setBroadcastReceiverPendingResult(BroadcastReceiver receiver, int resultCode) {
+        BroadcastReceiver.PendingResult pendingResult =
+                new BroadcastReceiver.PendingResult(resultCode,
+                        "resultData",
+                        /* resultExtras= */ null,
+                        BroadcastReceiver.PendingResult.TYPE_UNREGISTERED,
+                        /* ordered= */ true,
+                        /* sticky= */ false,
+                        /* token= */ null,
+                        UserHandle.myUserId(),
+                        /* flags= */ 0);
+        receiver.setPendingResult(pendingResult);
+    }
+
+    @Test
+    public void testSendTerminalResponseForSendSuccess() {
+        setBroadcastReceiverPendingResult(mCatService.mSmsBroadcastReceiver, Activity.RESULT_OK);
+        Intent intent = new Intent(SMS_SENT_ACTION).putExtra("cmdDetails", mCommandDetails);
+        intent.putExtra("ims", true);
+        mContext.sendOrderedBroadcast(intent, null, mCatService.mSmsBroadcastReceiver, null,
+                Activity.RESULT_OK, null, null);
+        processAllMessages();
+        verify(mSimulatedCommands, never()).sendTerminalResponse(
+                any(), any());
+    }
+
+    @Test
+    public void testSendTerminalResponseForSendSmsRpError() {
+        setBroadcastReceiverPendingResult(mCatService.mSmsBroadcastReceiver,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+        Intent intent = new Intent(SMS_SENT_ACTION).putExtra("cmdDetails", mCommandDetails);
+        intent.putExtra("ims", true);
+        intent.putExtra("errorCode", 41);
+        mContext.sendOrderedBroadcast(intent, null, mCatService.mSmsBroadcastReceiver, null,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE, null, null);
+        processAllMessages();
+        //Verify if the command is encoded with correct Result byte as per TS 101.267
+        verify(mSimulatedCommands, atLeastOnce()).sendTerminalResponse(
+                eq(mTerminalResponseForSmsRpError), any());
+    }
+
+    @Test
+    public void testSendTerminalResponseForSendSmsNetworkError() {
+        setBroadcastReceiverPendingResult(mCatService.mSmsBroadcastReceiver,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+        Intent intent = new Intent(SMS_SENT_ACTION).putExtra("cmdDetails", mCommandDetails);
+        intent.putExtra("ims", false);
+        intent.putExtra("errorCode", 41);
+        mContext.sendOrderedBroadcast(intent, null, mCatService.mSmsBroadcastReceiver, null,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE, null, null);
+        processAllMessages();
+        //Verify if the command is encoded with correct Result byte as per TS 101.267
+        verify(mSimulatedCommands, atLeastOnce()).sendTerminalResponse(
+                eq(mTerminalResponseForNetworkUnableToProcess), any());
+    }
+
+    @Test
+    public void testSendTerminalResponseForDeliveryFailure() {
+        setBroadcastReceiverPendingResult(mCatService.mSmsBroadcastReceiver,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+        Intent intent = new Intent(SMS_DELIVERY_ACTION).putExtra("cmdDetails", mCommandDetails);
+        mContext.sendOrderedBroadcast(intent, null, mCatService.mSmsBroadcastReceiver, null,
+                SmsManager.RESULT_ERROR_GENERIC_FAILURE, null, null);
+        processAllMessages();
+        //Verify if the command is encoded with correct Result byte as per TS 101.267
+        verify(mSimulatedCommands, atLeastOnce()).sendTerminalResponse(
+                eq(mTerminalResponseForTerminalUnableToProcess), any());
+    }
+
+    @Test
+    public void testSendTerminalResponseForDeliverySuccess() {
+        setBroadcastReceiverPendingResult(mCatService.mSmsBroadcastReceiver,
+                Activity.RESULT_OK);
+        Intent intent = new Intent(SMS_DELIVERY_ACTION).putExtra("cmdDetails", mCommandDetails);
+        mContext.sendOrderedBroadcast(intent, null, mCatService.mSmsBroadcastReceiver, null,
+                Activity.RESULT_OK, null, null);
+        processAllMessages();
+        //Verify if the command is encoded with correct Result byte as per TS 101.267
+        verify(mSimulatedCommands, atLeastOnce()).sendTerminalResponse(
+                eq(mTerminalResponseForDeliverySuccess), any());
+    }
+}
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 5df94e5..3445939 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -57,11 +57,6 @@
 import com.android.internal.util.IState;
 import com.android.internal.util.StateMachine;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -69,6 +64,11 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CdmaInboundSmsHandlerTest extends TelephonyTest {
@@ -157,7 +157,7 @@
                 Telephony.Sms.CONTENT_URI.getAuthority(), mContentProvider);
 
         mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(mContext,
-            mSmsStorageMonitor, mPhone, null);
+            mSmsStorageMonitor, mPhone, null, mTestableLooper.getLooper());
         monitorTestableLooper(new TestableLooper(mCdmaInboundSmsHandler.getHandler().getLooper()));
         processAllMessages();
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
index c8eee8c..4d116a8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
@@ -18,7 +18,6 @@
 
 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;
@@ -27,13 +26,17 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
 import android.content.IntentFilter;
 import android.content.pm.ServiceInfo;
 import android.net.NetworkCapabilities;
+import android.os.AsyncResult;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.NetworkService;
@@ -66,6 +69,8 @@
     // The real callback passed created by AccessNetworksManager.
     private IQualifiedNetworksServiceCallback.Stub mQnsCallback;
 
+    private PersistableBundle mBundle;
+
     private void addQnsService() throws Exception {
         ServiceInfo QnsInfo = new ServiceInfo();
         QnsInfo.packageName = "fake.qns";
@@ -96,6 +101,9 @@
         mMockedQns = mock(IQualifiedNetworksService.class);
         mMockedIBinder = mock(IBinder.class);
 
+        mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
+
         addQnsService();
         mContextFixture.putResource(
                 com.android.internal.R.string.config_qualified_networks_service_package,
@@ -113,13 +121,14 @@
         processAllMessages();
         replaceInstance(AccessNetworksManager.class, "mDataConfigManager",
                 mAccessNetworksManager, mMockedDataConfigManager);
-        assumeFalse(mAccessNetworksManager.isInLegacyMode());
+
         logd("-setUp");
     }
 
     @After
     public void tearDown() throws Exception {
         mAccessNetworksManager = null;
+        mBundle = null;
         super.tearDown();
     }
 
@@ -150,6 +159,32 @@
     }
 
     @Test
+    public void testGuideTransportTypeForEmergencyDataNetwork() throws Exception {
+        doAnswer(invocation -> {
+            int accessNetwork = AccessNetworkType.UNKNOWN;
+            if (invocation.getArguments()[1].equals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)) {
+                accessNetwork = AccessNetworkType.IWLAN;
+            } else if (invocation.getArguments()[1]
+                    .equals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)) {
+                accessNetwork = AccessNetworkType.EUTRAN;
+            }
+            mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_EMERGENCY,
+                    new int[]{accessNetwork});
+            return null;
+        }).when(mMockedQns).reportEmergencyDataNetworkPreferredTransportChanged(anyInt(), anyInt());
+
+        AsyncResult asyncResult =
+                new AsyncResult(null, AccessNetworkConstants.TRANSPORT_TYPE_WLAN, null);
+        Message msg = this.mAccessNetworksManager
+                .obtainMessage(1 /* EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY */, asyncResult);
+        mAccessNetworksManager.sendMessage(msg);
+        processAllMessages();
+
+        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_EMERGENCY))
+                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+    }
+
+    @Test
     public void testEmptyNetworkTypes() throws Exception {
         testQualifiedNetworkTypesChanged();
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
index 3773756..428699f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
@@ -48,6 +48,7 @@
 import android.testing.TestableLooper;
 
 import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -76,7 +77,8 @@
         doReturn(CAPABILITY_WITH_VALIDATION_SUPPORTED).when(mPhoneConfigurationManager)
                 .getCurrentPhoneCapability();
         mValidatorUT = new CellularNetworkValidator(mContext);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
+        doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
         processAllMessages();
         setCacheTtlInCarrierConfig(5000);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index 0b2c10b..62a797c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.data;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_DATA;
+
 import static com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
 import static com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
 
@@ -112,6 +114,7 @@
 import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback;
 import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
 import com.android.internal.telephony.ims.ImsResolver;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -141,6 +144,12 @@
     private static final String FAKE_MMTEL_PACKAGE = "fake.mmtel.package";
     private static final String FAKE_RCS_PACKAGE = "fake.rcs.package";
 
+    // Events
+    private static final int EVENT_SIM_STATE_CHANGED = 9;
+    private static final int EVENT_REEVALUATE_EXISTING_DATA_NETWORKS = 16;
+    private static final int EVENT_VOICE_CALL_ENDED = 18;
+    private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23;
+
     // Mocked classes
     private PhoneSwitcher mMockedPhoneSwitcher;
     protected ISub mMockedIsub;
@@ -227,6 +236,36 @@
             .setPreferred(false)
             .build();
 
+    // Created to test preferred data profiles that apply to different network types
+    private final DataProfile mGeneralPurposeDataProfileAlternative = new DataProfile.Builder()
+            .setApnSetting(new ApnSetting.Builder()
+                    .setId(2161)
+                    .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_NR
+                            | 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(4321)
+                    .setMaxConns(321)
+                    .setWaitTime(456)
+                    .setMaxConnsTime(789)
+                    .build())
+            .setPreferred(false)
+            .build();
+
     private final DataProfile mImsCellularDataProfile = new DataProfile.Builder()
             .setApnSetting(new ApnSetting.Builder()
                     .setId(2164)
@@ -318,7 +357,7 @@
                     .setApnName("dun_apn")
                     .setUser("user")
                     .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+                    .setApnTypeBitmask(ApnSetting.TYPE_DUN | ApnSetting.TYPE_DEFAULT)
                     .setProtocol(ApnSetting.PROTOCOL_IPV6)
                     .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
                     .setCarrierEnabled(true)
@@ -515,9 +554,13 @@
 
     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));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
 
         serviceStateChanged(networkType, regState, regState,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
@@ -547,9 +590,13 @@
             @RegistrationState int dataRegState, @RegistrationState int voiceRegState,
             @RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
         if (dsri == null) {
-            dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                    new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                            LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+            dsri = new DataSpecificRegistrationInfo.Builder(8)
+                    .setNrAvailable(true)
+                    .setEnDcAvailable(true)
+                    .setVopsSupportInfo(new LteVopsSupportInfo(
+                            LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                            LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                    .build();
         }
 
         ServiceState ss = new ServiceState();
@@ -724,17 +771,13 @@
         doReturn(true).when(mSST).getPowerStateFromCarrier();
         doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        doReturn("").when(mSubscriptionController).getEnabledMobileDataPolicies(anyInt());
-        doReturn(true).when(mSubscriptionController).setEnabledMobileDataPolicies(
-                anyInt(), anyString());
+        doReturn(new SubscriptionInfoInternal.Builder().setId(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         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(1);
-        doReturn(1).when(mSubscriptionController).getPhoneId(2);
+        doReturn(0).when(mSubscriptionManagerService).getPhoneId(1);
+        doReturn(1).when(mSubscriptionManagerService).getPhoneId(2);
 
         for (int transport : new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN}) {
@@ -825,7 +868,8 @@
                 linkBandwidthEstimatorCallbackCaptor.capture());
         mLinkBandwidthEstimatorCallback = linkBandwidthEstimatorCallbackCaptor.getValue();
 
-        List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile, mImsCellularDataProfile,
+        List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile,
+                mGeneralPurposeDataProfileAlternative, mImsCellularDataProfile,
                 mImsIwlanDataProfile, mEmergencyDataProfile, mFotaDataProfile,
                 mTetheringDataProfile);
 
@@ -878,7 +922,6 @@
 
         doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
                 .getPreferredTransportByNetworkCapability(anyInt());
-        doReturn(true).when(mDataProfileManager).isDataProfilePreferred(any(DataProfile.class));
 
         doAnswer(invocation -> {
             ((Runnable) invocation.getArguments()[0]).run();
@@ -892,7 +935,7 @@
         mDataNetworkControllerUT.registerDataNetworkControllerCallback(
                 mMockedDataNetworkControllerCallback);
 
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
+        mDataNetworkControllerUT.obtainMessage(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))
@@ -1248,12 +1291,14 @@
     public void testSimRemovalDataTearDown() throws Exception {
         testSetupDataNetwork();
 
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SIM_STATE_CHANGED,
                 TelephonyManager.SIM_STATE_ABSENT, 0).sendToTarget();
         processAllMessages();
         verifyAllDataDisconnected();
         verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
         verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
+        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
     }
 
     @Test
@@ -1262,7 +1307,7 @@
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
 
         // Insert the SIM again.
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SIM_STATE_CHANGED,
                 TelephonyManager.SIM_STATE_LOADED, 0).sendToTarget();
         processAllMessages();
 
@@ -1416,7 +1461,8 @@
         verifyAllDataDisconnected();
         verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
         verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
-
+        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
 
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
         // Now RAT changes from GSM to UMTS
@@ -1471,7 +1517,7 @@
 
         // Call ended.
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        mDataNetworkControllerUT.obtainMessage(18/*EVENT_VOICE_CALL_ENDED*/).sendToTarget();
+        mDataNetworkControllerUT.obtainMessage(EVENT_VOICE_CALL_ENDED).sendToTarget();
         processAllMessages();
 
         // It should have no internet setup at the beginning.
@@ -1576,9 +1622,7 @@
         boolean isDataEnabled = mDataNetworkControllerUT.getDataSettingsManager().isDataEnabled();
         doReturn(mDataNetworkControllerUT.getDataSettingsManager())
                 .when(mPhone).getDataSettingsManager();
-        MultiSimSettingController instance = MultiSimSettingController.getInstance();
-        MultiSimSettingController controller = Mockito.spy(
-                new MultiSimSettingController(mContext, mSubscriptionController));
+        MultiSimSettingController controller = Mockito.spy(new MultiSimSettingController(mContext));
         doReturn(true).when(controller).isCarrierConfigLoadedForAllSub();
         replaceInstance(MultiSimSettingController.class, "sInstance", null, controller);
 
@@ -1628,6 +1672,14 @@
         verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
         verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
 
+        mDataNetworkControllerUT.obtainMessage(16 /*EVENT_REEVALUATE_EXISTING_DATA_NETWORKS*/,
+                DataEvaluation.DataEvaluationReason.DATA_SERVICE_STATE_CHANGED).sendToTarget();
+
+        processAllFutureMessages();
+
+        // Make sure IMS network is not torn down
+        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
+
         // Remove MMS data enabled override
         mDataNetworkControllerUT.getDataSettingsManager().setMobileDataPolicy(TelephonyManager
                 .MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, false);
@@ -1664,7 +1716,7 @@
     @Test
     public void testIsDataEnabledOverriddenForApnDataDuringCall() throws Exception {
         doReturn(1).when(mPhone).getSubId();
-        doReturn(2).when(mSubscriptionController).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
         // Data disabled
         mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
@@ -1706,7 +1758,7 @@
         // Assume phone2 is the default data phone
         Phone phone2 = Mockito.mock(Phone.class);
         replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, phone2});
-        doReturn(2).when(mSubscriptionController).getDefaultDataSubId();
+        doReturn(2).when(mSubscriptionManagerService).getDefaultDataSubId();
 
         // Data disabled on nonDDS
         mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
@@ -1735,9 +1787,20 @@
         // Verify internet connection
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
 
-        // Disable auto data switch mobile policy
+        // Disable auto data switch mobile policy, but enabled data during call
         mDataNetworkControllerUT.getDataSettingsManager().setMobileDataPolicy(TelephonyManager
                 .MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, false);
+        mDataNetworkControllerUT.getDataSettingsManager().setMobileDataPolicy(TelephonyManager
+                .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL, true);
+        doReturn(PhoneConstants.State.RINGING).when(phone2).getState();
+        processAllMessages();
+
+        // Verify internet connection
+        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        // Disable data during call
+        mDataNetworkControllerUT.getDataSettingsManager().setMobileDataPolicy(TelephonyManager
+                .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL, false);
         processAllMessages();
 
         // Verify no internet connection
@@ -1928,7 +1991,7 @@
 
         // Set 5G unmetered
         congestedNetworkTypes.add(TelephonyManager.NETWORK_TYPE_NR);
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED,
                 new int[]{TelephonyManager.NETWORK_TYPE_NR}).sendToTarget();
@@ -1950,7 +2013,7 @@
 
         // Set all network types metered
         congestedNetworkTypes.clear();
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED, 0,
                 TelephonyManager.getAllNetworkTypes()).sendToTarget();
         dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
@@ -1970,7 +2033,7 @@
 
         // Set 5G unmetered
         unmeteredNetworkTypes.add(TelephonyManager.NETWORK_TYPE_NR);
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED,
                 new int[]{TelephonyManager.NETWORK_TYPE_NR}).sendToTarget();
@@ -1994,7 +2057,7 @@
 
         // Set all network types metered
         unmeteredNetworkTypes.clear();
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE,
                 NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED, 0,
                 TelephonyManager.getAllNetworkTypes()).sendToTarget();
         dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
@@ -2089,7 +2152,7 @@
                 NetworkCapabilities.NET_CAPABILITY_MMTEL);
 
         // Both internet and IMS should be retained after network re-evaluation
-        mDataNetworkControllerUT.obtainMessage(16/*EVENT_REEVALUATE_EXISTING_DATA_NETWORKS*/)
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
                 .sendToTarget();
         processAllMessages();
 
@@ -2109,7 +2172,7 @@
                 NetworkCapabilities.NET_CAPABILITY_MMTEL);
 
         // Both internet and IMS should be retained after network re-evaluation
-        mDataNetworkControllerUT.obtainMessage(16/*EVENT_REEVALUATE_EXISTING_DATA_NETWORKS*/)
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
                 .sendToTarget();
         processAllMessages();
 
@@ -2273,6 +2336,8 @@
 
         // Verify all data disconnected.
         verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
+        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
 
         // A new data network should be connected on IWLAN
         List<DataNetwork> dataNetworkList = getDataNetworks();
@@ -2333,6 +2398,8 @@
 
         // Verify all data disconnected.
         verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
+        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
 
         // Should setup a new one instead of handover.
         verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
@@ -2444,6 +2511,7 @@
     public void testHandoverDataNetworkRetryReachedMaximum() throws Exception {
         testSetupImsDataNetwork();
 
+        // 1. Normal case
         setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                 DataFailCause.HANDOVER_FAILED, -1, true);
         updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
@@ -2464,6 +2532,30 @@
         verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
                 anyBoolean(), anyBoolean(), eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(),
                 any(), any(), anyBoolean(), any(Message.class));
+
+        // 2. Active VoPS call, should delay tear down
+        doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
+        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
+                true);
+        carrierConfigChanged();
+
+        setFailedSetupDataResponse(mMockedWwanDataServiceManager,
+                DataFailCause.HANDOVER_FAILED, -1, true);
+        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        processAllFutureMessages();
+
+        // Verify the network wasn't torn down
+        verify(mMockedWlanDataServiceManager, never()).deactivateDataCall(anyInt(),
+                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+
+        // Verify tear down after call ends
+        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
+        mDataNetworkControllerUT.obtainMessage(EVENT_VOICE_CALL_ENDED).sendToTarget();
+        processAllFutureMessages();
+
+        verify(mMockedWlanDataServiceManager).deactivateDataCall(anyInt(),
+                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
     }
 
     @Test
@@ -2614,8 +2706,9 @@
                 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(),
+        // The first 8 retries are short timers that scheduled by handler, future retries are
+        // scheduled by intent and require more complex mock, so we only verify the first 8 here.
+        verify(mMockedWwanDataServiceManager, times(9)).setupDataCall(anyInt(),
                 any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
                 any(), any(), anyBoolean(), any(Message.class));
     }
@@ -2765,7 +2858,7 @@
         processAllFutureMessages();
 
         // TAC changes should clear the already-scheduled retry and throttling.
-        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
+        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                 mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();
 
         // But DNC should re-evaluate unsatisfied request and setup IMS again.
@@ -2788,8 +2881,8 @@
         // 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));
+                eq(mGeneralPurposeDataProfile), anyBoolean(), anyBoolean(), anyInt(), any(),
+                anyInt(), any(), any(), anyBoolean(), any(Message.class));
 
         Mockito.clearInvocations(mMockedWwanDataServiceManager);
         mDataNetworkControllerUT.addNetworkRequest(
@@ -2870,6 +2963,35 @@
     }
 
     @Test
+    public void testHandoverDataNetworkNetworkSuggestedRetryTimerDataThrottled() throws Exception {
+        testSetupImsDataNetwork();
+
+        DataNetwork network = getDataNetworks().get(0);
+        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
+                DataFailCause.HANDOVER_FAILED, 10000, true);
+        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+
+        // Verify retry scheduled on this network
+        assertThat(mDataNetworkControllerUT.getDataRetryManager()
+                .isAnyHandoverRetryScheduled(network)).isTrue();
+        // Verify the data profile is throttled on WLAN
+        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
+                network.getDataProfile(), AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isTrue();
+
+        // Test even if network disconnected, the throttle status should remain
+        network.tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
+        processAllFutureMessages();
+
+        // Verify retry is cleared on this network
+        assertThat(mDataNetworkControllerUT.getDataRetryManager()
+                .isAnyHandoverRetryScheduled(network)).isFalse();
+        // Verify the data profile is still throttled
+        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
+                network.getDataProfile(), AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isTrue();
+    }
+
+    @Test
     public void testTacChangesClearThrottlingAndRetryHappens() throws Exception {
         testSetupDataNetworkNetworkSuggestedRetryTimerDataThrottled();
         processAllFutureMessages();
@@ -2882,7 +3004,7 @@
         processAllFutureMessages();
 
         // TAC changes should clear the already-scheduled retry and throttling.
-        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
+        assertThat(mDataNetworkControllerUT.getDataRetryManager().isDataProfileThrottled(
                 mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();
 
         // But DNC should re-evaluate unsatisfied request and setup IMS again.
@@ -3093,6 +3215,73 @@
     }
 
     @Test
+    public void testSetPreferredDataProfileMultiInternetDataProfile() throws Exception {
+        // No preferred data profile in the beginning
+        doReturn(false).when(mDataProfileManager).canPreferredDataProfileSatisfy(
+                any(NetworkRequestList.class));
+
+        testSetupDataNetwork();
+
+        // Verify this network still alive after evaluation
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
+                .sendToTarget();
+        processAllMessages();
+
+        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
+
+        // Network connected, became preferred data profile
+        doAnswer(invocation -> {
+            NetworkRequestList networkRequests =
+                    (NetworkRequestList) invocation.getArguments()[0];
+            return networkRequests.stream()
+                    .allMatch(request -> request.canBeSatisfiedBy(mGeneralPurposeDataProfile));
+        }).when(mDataProfileManager).canPreferredDataProfileSatisfy(
+                any(NetworkRequestList.class));
+        doReturn(true).when(mDataProfileManager)
+                .isDataProfilePreferred(mGeneralPurposeDataProfile);
+
+        // 1. Test DUN | DEFAULT data profile is compatible with preferred default internet
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_DUN));
+        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 2);
+        processAllMessages();
+
+        // Verify both DUN and preferred default network are alive
+        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
+        verifyConnectedNetworkHasDataProfile(mTetheringDataProfile);
+
+        // Verify this network still alive after evaluation
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
+                .sendToTarget();
+        processAllMessages();
+
+        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
+        verifyConnectedNetworkHasDataProfile(mTetheringDataProfile);
+
+        // 2. Test tear down when user changes preferred data profile
+        doAnswer(invocation -> {
+            NetworkRequestList networkRequests =
+                    (NetworkRequestList) invocation.getArguments()[0];
+            return networkRequests.stream()
+                    .allMatch(request -> request.canBeSatisfiedBy(
+                            mGeneralPurposeDataProfileAlternative));
+        }).when(mDataProfileManager).canPreferredDataProfileSatisfy(
+                any(NetworkRequestList.class));
+        doReturn(true).when(mDataProfileManager)
+                .isDataProfilePreferred(mGeneralPurposeDataProfileAlternative);
+        doReturn(false).when(mDataProfileManager)
+                .isDataProfilePreferred(mGeneralPurposeDataProfile);
+
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
+                .sendToTarget();
+        processAllMessages();
+
+        List<DataNetwork> dataNetworks = getDataNetworks();
+        assertThat(dataNetworks).hasSize(1);
+        verifyConnectedNetworkHasDataProfile(mTetheringDataProfile);
+    }
+
+    @Test
     public void testDataDisableNotAllowingBringingUpTetheringNetwork() throws Exception {
         // User data disabled
         mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
@@ -3122,9 +3311,13 @@
 
     @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));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
 
@@ -3144,9 +3337,13 @@
         carrierConfigChanged();
 
         // VOPS not supported
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
 
@@ -3157,9 +3354,13 @@
         verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
 
         // VoPS supported
-        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
 
@@ -3339,11 +3540,11 @@
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
 
         mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
         processAllFutureMessages();
         // Lower priority network should not trump the higher priority network.
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
 
         // Now send a higher priority network request
         TelephonyNetworkRequest fotaRequest = createNetworkRequest(
@@ -3515,38 +3716,63 @@
 
     @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());
+        // Config delay IMS tear down enabled
+        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
+                true);
+        carrierConfigChanged();
 
-        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());
-        processServiceStateRegStateForTest(ss);
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
+        // VoPS supported
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME /*data*/,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME /*voice*/,
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING /*iwlan*/,
+                dsri);
 
         testSetupImsDataNetwork();
+        DataNetwork dataNetwork = getDataNetworks().get(0);
+
+        // 1. Active VoPS call, mock target IWLAN OOS, should schedule retry
+        doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
         updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        // Process DRM event to schedule retry
+        processAllMessages();
+
+        // Verify scheduled new handover retry
+        assertTrue(mDataNetworkControllerUT.getDataRetryManager()
+                .isAnyHandoverRetryScheduled(dataNetwork));
+        // Verify the network wasn't torn down
+        verify(mMockedWwanDataServiceManager, never()).deactivateDataCall(anyInt(),
+                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+
+        // Get the scheduled retry
+        Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
+        field.setAccessible(true);
+        DataRetryManager.DataHandoverRetryEntry dataRetryEntry =
+                (DataRetryManager.DataHandoverRetryEntry) ((List<DataRetryManager.DataRetryEntry>)
+                        field.get(mDataNetworkControllerUT.getDataRetryManager())).get(0);
+
+        // Process the retry
+        moveTimeForward(1000 /*The retry delay of the first attempt*/);
+        processAllMessages();
+
+        // Verify the previous retry is set to FAILED
+        assertEquals(DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED, dataRetryEntry.getState());
+        // Verify a new retry is scheduled
+        assertTrue(mDataNetworkControllerUT.getDataRetryManager()
+                .isAnyHandoverRetryScheduled(dataNetwork));
+
+        // 2. Normal case (call ended), should tear down
+        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
+        mDataNetworkControllerUT.obtainMessage(EVENT_VOICE_CALL_ENDED).sendToTarget();
+        processAllFutureMessages();
 
         // Verify that handover is not performed.
         verify(mMockedWlanDataServiceManager, never()).setupDataCall(anyInt(),
@@ -3554,7 +3780,7 @@
                 eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(), anyBoolean(),
                 any(Message.class));
 
-        // IMS network should be torn down.
+        // Verify IMS network should be torn down.
         verifyAllDataDisconnected();
     }
 
@@ -3626,9 +3852,13 @@
     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));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -3689,9 +3919,13 @@
 
         ServiceState ss = new ServiceState();
 
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -3749,9 +3983,13 @@
     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));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -3817,9 +4055,13 @@
         ServiceState ss = new ServiceState();
 
         // VoPS network
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -3864,9 +4106,13 @@
 
         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));
+        dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -3902,7 +4148,7 @@
 
         mCarrierConfig.putBoolean(CarrierConfigManager.Ims.KEY_KEEP_PDN_UP_IN_NO_VOPS_BOOL, false);
         carrierConfigChanged();
-        mDataNetworkControllerUT.obtainMessage(16/*EVENT_REEVALUATE_EXISTING_DATA_NETWORKS*/)
+        mDataNetworkControllerUT.obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)
                 .sendToTarget();
         processAllMessages();
 
@@ -3918,9 +4164,13 @@
         carrierConfigChanged();
 
         // VoPS supported
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
 
@@ -3932,9 +4182,13 @@
 
         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));
+        dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
 
@@ -3944,7 +4198,7 @@
 
         // Call ends
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        mDataNetworkControllerUT.obtainMessage(18/*EVENT_VOICE_CALL_ENDED*/).sendToTarget();
+        mDataNetworkControllerUT.obtainMessage(EVENT_VOICE_CALL_ENDED).sendToTarget();
         processAllMessages();
 
         verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
@@ -3960,16 +4214,18 @@
         }).when(mMockedWwanDataServiceManager).deactivateDataCall(
                 anyInt(), anyInt(), any(Message.class));
         // Simulate old devices
-        doReturn(RIL.RADIO_HAL_VERSION_1_6).when(mPhone).getHalVersion();
+        doReturn(RIL.RADIO_HAL_VERSION_1_6).when(mPhone).getHalVersion(HAL_SERVICE_DATA);
 
         testSetupDataNetwork();
 
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
+        mDataNetworkControllerUT.obtainMessage(EVENT_SIM_STATE_CHANGED,
                 TelephonyManager.SIM_STATE_ABSENT, 0).sendToTarget();
         processAllMessages();
         verifyAllDataDisconnected();
         verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
         verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
+        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index 5da1164..b85081f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -202,30 +202,8 @@
         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();
+            DataCallResponse response = createDataCallResponse(
+                    cid, DataCallResponse.LINK_STATUS_ACTIVE, tds);
             msg.getData().putParcelable("data_call_response", response);
             msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
             msg.sendToTarget();
@@ -235,6 +213,34 @@
                 any(Message.class));
     }
 
+    private DataCallResponse createDataCallResponse(int cid, int linkStatus,
+            List<TrafficDescriptor> tds) {
+        return new DataCallResponse.Builder()
+                .setCause(0)
+                .setRetryDurationMillis(-1L)
+                .setId(cid)
+                .setLinkStatus(linkStatus)
+                .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();
+    }
+
     private void setFailedSetupDataResponse(DataServiceManager dsm,
             @DataServiceCallback.ResultCode int resultCode) {
         doAnswer(invocation -> {
@@ -340,7 +346,6 @@
         doReturn(true).when(mDataConfigManager).isTempNotMeteredSupportedByCarrier();
         doReturn(true).when(mDataConfigManager).isNetworkTypeUnmetered(
                 any(TelephonyDisplayInfo.class), any(ServiceState.class));
-        doReturn(true).when(mDataConfigManager).isImsDelayTearDownEnabled();
         doReturn(DEFAULT_MTU).when(mDataConfigManager).getDefaultMtu();
         doReturn(FAKE_IMSI).when(mPhone).getSubscriberId();
         doReturn(true).when(mDataNetworkController)
@@ -474,9 +479,13 @@
 
     @Test
     public void testCreateDataNetworkWhenOos() throws Exception {
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
         // Out of service
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri);
@@ -516,9 +525,13 @@
     public void testRecreateAgentWhenOos() throws Exception {
         testCreateDataNetwork();
 
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
         // Out of service
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, dsri);
@@ -1122,8 +1135,7 @@
                 any(Handler.class), anyInt());
         verify(mMockedWlanDataServiceManager).registerForDataCallListChanged(
                 any(Handler.class), anyInt());
-        verify(mCarrierPrivilegesTracker).registerCarrierPrivilegesListener(any(Handler.class),
-                anyInt(), eq(null));
+        verify(mTelephonyManager).registerCarrierPrivilegesCallback(anyInt(), any(), any());
         verify(mLinkBandwidthEstimator).registerCallback(
                 any(LinkBandwidthEstimatorCallback.class));
         verify(mSimulatedCommandsVerifier).registerForNattKeepaliveStatus(any(Handler.class),
@@ -1146,7 +1158,7 @@
         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(mTelephonyManager).unregisterCarrierPrivilegesCallback(any());
         verify(mLinkBandwidthEstimator).unregisterCallback(
                 any(LinkBandwidthEstimatorCallback.class));
         verify(mSimulatedCommandsVerifier).unregisterForNattKeepaliveStatus(any(Handler.class));
@@ -1367,9 +1379,13 @@
 
     @Test
     public void testMovingToNonVops() throws Exception {
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED))
+                .build();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
         testCreateImsDataNetwork();
@@ -1377,9 +1393,13 @@
         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));
+        dsri = new DataSpecificRegistrationInfo.Builder(8)
+                .setNrAvailable(true)
+                .setEnDcAvailable(true)
+                .setVopsSupportInfo(new LteVopsSupportInfo(
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
+                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED))
+                .build();
         logd("Trigger non VoPS");
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
@@ -1755,4 +1775,36 @@
         assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
                 InetAddresses.parseNumericAddress(IPV4_ADDRESS));
     }
+
+    @Test
+    public void testLinkStatusUpdate() throws Exception {
+        setupDataNetwork();
+
+        // verify link status sent on connected
+        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
+        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
+                eq(DataCallResponse.LINK_STATUS_ACTIVE));
+
+        // data state updated
+        DataCallResponse response = createDataCallResponse(123,
+                DataCallResponse.LINK_STATUS_DORMANT, Collections.emptyList());
+        mDataNetworkUT.sendMessage(8 /*EVENT_DATA_STATE_CHANGED*/, new AsyncResult(
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, List.of(response), null));
+        processAllMessages();
+
+        // verify link status sent on data state updated
+        assertThat(mDataNetworkUT.isConnected()).isTrue();
+        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
+                eq(DataCallResponse.LINK_STATUS_DORMANT));
+
+        // RIL crash
+        mDataNetworkUT.sendMessage(4 /*EVENT_RADIO_NOT_AVAILABLE*/);
+        processAllMessages();
+
+        // verify link status sent on disconnected
+        verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT),
+                eq(DataFailCause.RADIO_NOT_AVAILABLE), eq(DataNetwork.TEAR_DOWN_REASON_NONE));
+        verify(mDataNetworkCallback).onLinkStatusChanged(eq(mDataNetworkUT),
+                eq(DataCallResponse.LINK_STATUS_INACTIVE));
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index 0c01c90..e10c2a5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -75,6 +75,7 @@
 @TestableLooper.RunWithLooper
 public class DataProfileManagerTest extends TelephonyTest {
     private static final String GENERAL_PURPOSE_APN = "GP_APN";
+    private static final String GENERAL_PURPOSE_APN_LEGACY_RAT = "GP_APN_RAT";
     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";
@@ -170,6 +171,41 @@
                         -1,                     // skip_464xlat
                         0                       // always_on
                 },
+                // default internet data profile for RAT CDMA, to test update preferred data profile
+                new Object[]{
+                        9,                      // id
+                        PLMN,                   // numeric
+                        GENERAL_PURPOSE_APN_LEGACY_RAT,    // name
+                        GENERAL_PURPOSE_APN_LEGACY_RAT,    // 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_CDMA, // network_type_bitmask
+                        0,                      // lingering_network_type_bitmask
+                        DEFAULT_APN_SET_ID,     // apn_set_id
+                        -1,                     // carrier_id
+                        -1,                     // skip_464xlat
+                        0                       // always_on
+                },
                 new Object[]{
                         2,                      // id
                         PLMN,                   // numeric
@@ -777,13 +813,51 @@
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
         dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
         dataProfile.setPreferred(true);
-        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
+        DataNetwork internetNetwork = Mockito.mock(DataNetwork.class);
+        doReturn(dataProfile).when(internetNetwork).getDataProfile();
+        doReturn(new DataNetworkController.NetworkRequestList(List.of(tnr)))
+                .when(internetNetwork).getAttachedNetworkRequestList();
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(internetNetwork));
         processAllMessages();
 
-        // See if the same one can be returned.
+        // Test See if the same one can be returned.
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
+        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
+
+        // Test Another default internet network connected due to RAT changed. Verify the preferred
+        // data profile is updated.
+        DataProfile legacyRatDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+                tnr, TelephonyManager.NETWORK_TYPE_CDMA, false);
+        DataNetwork legacyRatInternetNetwork = Mockito.mock(DataNetwork.class);
+        doReturn(legacyRatDataProfile).when(legacyRatInternetNetwork).getDataProfile();
+        doReturn(new DataNetworkController.NetworkRequestList(List.of(tnr)))
+                .when(legacyRatInternetNetwork).getAttachedNetworkRequestList();
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(
+                // Because internetNetwork is torn down due to network type mismatch
+                legacyRatInternetNetwork));
+        processAllMessages();
+
+        assertThat(mDataProfileManagerUT.isDataProfilePreferred(legacyRatDataProfile)).isTrue();
+
+        // Test Another supl default internet network temporarily connected. Verify preferred
+        // doesn't change.
+        TelephonyNetworkRequest suplTnr = new TelephonyNetworkRequest(
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
+                        .build(), mPhone);
+        DataProfile suplDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+                suplTnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+        DataNetwork suplInternetNetwork = Mockito.mock(DataNetwork.class);
+        doReturn(suplDataProfile).when(suplInternetNetwork).getDataProfile();
+        doReturn(new DataNetworkController.NetworkRequestList(List.of(suplTnr)))
+                .when(suplInternetNetwork).getAttachedNetworkRequestList();
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(
+                legacyRatInternetNetwork, suplInternetNetwork));
+        processAllMessages();
+
+        assertThat(mDataProfileManagerUT.isDataProfilePreferred(legacyRatDataProfile)).isTrue();
     }
 
     @Test
@@ -1065,11 +1139,12 @@
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
         dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
+        DataNetwork internetNetwork = Mockito.mock(DataNetwork.class);
+        doReturn(dataProfile).when(internetNetwork).getDataProfile();
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(internetNetwork));
         processAllMessages();
 
         // After internet connected, preferred APN should be set
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
 
         // APN reset
@@ -1078,7 +1153,6 @@
         processAllMessages();
 
         // preferred APN should set to be the last data profile that succeeded for internet setup
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
 
         // Test user selected a bad data profile, expects to adopt the last data profile that
@@ -1088,7 +1162,6 @@
         mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
         processAllMessages();
 
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();
 
         // APN reset, preferred APN should set to be the last data profile that succeeded for
@@ -1097,11 +1170,10 @@
         mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
         processAllMessages();
 
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
 
         // Test removed data profile(user created after reset) shouldn't show up
-        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(internetNetwork));
         processAllMessages();
         //APN reset and removed GENERAL_PURPOSE_APN from APN DB
         mPreferredApnId = -1;
@@ -1110,7 +1182,6 @@
         processAllMessages();
 
         // There should be no preferred APN after APN reset because last working profile is removed
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isFalse();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();
 
         // restore mApnSettingContentProvider
@@ -1194,7 +1265,7 @@
     }
 
     @Test
-    public void testDataProfileCompatibility() throws Exception {
+    public void testDataProfileCompatibility() {
         DataProfile enterpriseDataProfile = new DataProfile.Builder()
                 .setTrafficDescriptor(new TrafficDescriptor(null,
                         new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index 25ca7b1..84b3302 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -24,12 +24,17 @@
 
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 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.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.os.AsyncResult;
@@ -130,6 +135,7 @@
             .build();
 
     // Mocked classes
+    private AlarmManager mAlarmManager;
     private DataRetryManagerCallback mDataRetryManagerCallbackMock;
 
     private DataRetryManager mDataRetryManagerUT;
@@ -147,6 +153,7 @@
             ((Runnable) invocation.getArguments()[0]).run();
             return null;
         }).when(mDataRetryManagerCallbackMock).invokeFromExecutor(any(Runnable.class));
+        mAlarmManager = Mockito.mock(AlarmManager.class);
         SparseArray<DataServiceManager> mockedDataServiceManagers = new SparseArray<>();
         mockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 mMockedWwanDataServiceManager);
@@ -166,6 +173,8 @@
                 dataNetworkControllerCallbackCaptor.capture());
         mDataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue();
 
+        replaceInstance(DataRetryManager.class, "mAlarmManager",
+                mDataRetryManagerUT, mAlarmManager);
         logd("DataRetryManagerTest -Setup!");
     }
 
@@ -356,14 +365,28 @@
                 .setSetupRetryType(1)
                 .build();
         mDataRetryEntries.addAll(List.of(scheduledRetry1, scheduledRetry2));
+        // Suppose we set the data profile as permanently failed.
+        mDataProfile3.getApnSetting().setPermanentFailed(true);
+
+        DataProfile dataProfile3ReconstructedFromModem = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName("some_fake_ims")
+                        .setApnName("fake_ims")
+                        .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
+                        .build())
+                .build();
 
         // unthrottle the data profile, expect previous retries of the same transport is cancelled
         mDataRetryManagerUT.obtainMessage(6/*EVENT_DATA_PROFILE_UNTHROTTLED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
+                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                        dataProfile3ReconstructedFromModem, null))
                 .sendToTarget();
         processAllMessages();
 
         // check unthrottle
+        assertThat(mDataProfile3.getApnSetting().getPermanentFailed()).isFalse();
         ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
                 ArgumentCaptor.forClass(List.class);
         verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
@@ -497,7 +520,6 @@
         processAllMessages();
 
         NetworkRequest request = new NetworkRequest.Builder()
-
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .build();
         TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
@@ -587,6 +609,16 @@
         // Verify there is no retry.
         verify(mDataRetryManagerCallbackMock, never())
                 .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
+
+        // 4th failed on a different transport and retry.
+        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN, networkRequestList, 123,
+                DataCallResponse.RETRY_DURATION_UNDEFINED);
+        processAllFutureMessages();
+
+        // Verify retry occurs
+        verify(mDataRetryManagerCallbackMock)
+                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
     }
 
     @Test
@@ -740,6 +772,43 @@
     }
 
     @Test
+    public void testDataRetryLongTimer() {
+        // Rule requires a long timer
+        DataSetupRetryRule retryRule = new DataSetupRetryRule(
+                "capabilities=internet, retry_interval=120000, maximum_retries=2");
+        doReturn(Collections.singletonList(retryRule)).when(mDataConfigManager)
+                .getDataSetupRetryRules();
+        mDataConfigManagerCallback.onCarrierConfigChanged();
+        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 scheduled via Alarm Manager
+        ArgumentCaptor<PendingIntent> pendingIntentArgumentCaptor =
+                ArgumentCaptor.forClass(PendingIntent.class);
+        verify(mAlarmManager).setAndAllowWhileIdle(anyInt(), anyLong(),
+                pendingIntentArgumentCaptor.capture());
+
+        // Verify starts retry attempt after receiving intent
+        PendingIntent pendingIntent = pendingIntentArgumentCaptor.getValue();
+        Intent intent = pendingIntent.getIntent();
+        mContext.sendBroadcast(intent);
+        processAllFutureMessages();
+
+        verify(mDataRetryManagerCallbackMock)
+                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
+    }
+
+    @Test
     public void testDataHandoverRetryInvalidRulesFromString() {
         assertThrows(IllegalArgumentException.class,
                 () -> new DataHandoverRetryRule("V2hhdCBUaGUgRnVjayBpcyB0aGlzIQ=="));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
index 4984879..f7525c1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -34,6 +33,7 @@
 
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -63,9 +63,8 @@
         mBundle = mContextFixture.getCarrierConfigBundle();
         doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific();
 
-        doReturn("").when(mSubscriptionController).getEnabledMobileDataPolicies(anyInt());
-        doReturn(true).when(mSubscriptionController).setEnabledMobileDataPolicies(
-                anyInt(), anyString());
+        doReturn(new SubscriptionInfoInternal.Builder().setId(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mDataSettingsManagerUT = new DataSettingsManager(mPhone, mDataNetworkController,
                 Looper.myLooper(), mMockedDataSettingsManagerCallback);
@@ -105,7 +104,7 @@
         processAllMessages();
 
         ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        verify(mSubscriptionController, times(2))
+        verify(mSubscriptionManagerService, times(2))
                 .setEnabledMobileDataPolicies(anyInt(), stringArgumentCaptor.capture());
         assertEquals("1,2", stringArgumentCaptor.getValue());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
index 5bf66c5..35d3b92 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
@@ -19,7 +19,6 @@
 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;
@@ -29,7 +28,6 @@
 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;
 
@@ -71,14 +69,10 @@
                 .getDataStallRecoveryShouldSkipArray();
         doReturn(true).when(mDataNetworkController).isInternetDataAllowed();
 
-        doAnswer(
-                invocation -> {
-                    ((Runnable) invocation.getArguments()[0]).run();
-                    return null;
-                })
-                .when(mDataStallRecoveryManagerCallback)
-                .invokeFromExecutor(any(Runnable.class));
-        doReturn("").when(mSubscriptionController).getEnabledMobileDataPolicies(anyInt());
+        doAnswer(invocation -> {
+            ((Runnable) invocation.getArguments()[0]).run();
+            return null;
+        }).when(mDataStallRecoveryManagerCallback).invokeFromExecutor(any(Runnable.class));
 
         mDataStallRecoveryManager =
                 new DataStallRecoveryManager(
@@ -117,7 +111,7 @@
                 dataNetworkControllerCallbackCaptor.getValue();
 
         if (isConnected) {
-            List<DataProfile> dataprofile = new ArrayList<DataProfile>();
+            List<DataNetwork> dataprofile = new ArrayList<>();
             dataNetworkControllerCallback.onInternetDataNetworkConnected(dataprofile);
         } else {
             dataNetworkControllerCallback.onInternetDataNetworkDisconnected();
@@ -352,54 +346,6 @@
     }
 
     @Test
-    public void testNextRecoveryAfterSkippingUnderPoorSignal() throws Exception {
-        // Test to validate if the next recovery action is performed in good signal
-        // soon after skipping the recovery action under poor signal condition
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(1);
-        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);
-        processAllMessages();
-        moveTimeForward(101);
-
-        // verify skipping recovery action under poor signal condition
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-
-        // Set the signal condition to good
-        doReturn(3).when(mSignalStrength).getLevel();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-
-        // verify next recovery action is performed under good signal condition
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-    }
-
-    @Test
-    public void testDoNotRecoveryForAlwaysInvalidNetwork() throws Exception {
-        // Test to verify that recovery action is not performed for always invalid network
-        // In some lab testing scenarios, n/w validation always remain invalid.
-        sendOnInternetDataNetworkCallback(false);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-        mDataStallRecoveryManager
-                .setRecoveryAction(DataStallRecoveryManager.RECOVERY_ACTION_GET_DATA_CALL_LIST);
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-        moveTimeForward(101);
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-    }
-
-    @Test
     public void testStartTimeNotZero() throws Exception {
         sendOnInternetDataNetworkCallback(false);
         doReturn(mSignalStrength).when(mPhone).getSignalStrength();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index a968dc7..bc691f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -80,6 +80,7 @@
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -108,7 +109,6 @@
     CompletableFuture<Boolean> mFuturePhone;
     private CommandsInterface mCommandsInterface0;
     private CommandsInterface mCommandsInterface1;
-    private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
     private ServiceStateTracker mSST2;
     private Phone mImsPhone;
     private DataSettingsManager mDataSettingsManager2;
@@ -144,7 +144,6 @@
         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.
         mSST2 = mock(ServiceStateTracker.class);
         mImsPhone = mock(Phone.class);
         mDataSettingsManager2 = mock(DataSettingsManager.class);
@@ -200,7 +199,7 @@
         initialize();
 
         // verify nothing has been done while there are no inputs
-        assertFalse("data allowed initially", mDataAllowed[0]);
+        assertTrue("data should be always allowed for emergency", mDataAllowed[0]);
         assertFalse("data allowed initially", mDataAllowed[1]);
 
         NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50);
@@ -306,7 +305,7 @@
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong());
         clearInvocations(mActivePhoneSwitchHandler);
-        assertFalse("data allowed", mDataAllowed[0]);
+        assertTrue("data not allowed", mDataAllowed[0]);
         assertFalse("data allowed", mDataAllowed[1]);
 
         // 6 gain subscription-specific request
@@ -350,7 +349,7 @@
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong());
         clearInvocations(mActivePhoneSwitchHandler);
-        assertFalse("data allowed", mDataAllowed[0]);
+        assertTrue("data not allowed", mDataAllowed[0]);
         assertFalse("data allowed", mDataAllowed[1]);
 
         // 10 don't switch phones when in emergency mode
@@ -563,7 +562,7 @@
 
     @Test
     @SmallTest
-    public void testAutoDataSwitchRetry() throws Exception {
+    public void testAutoDataSwitch_retry() throws Exception {
         initialize();
         // Phone 0 has sub 1, phone 1 has sub 2.
         // Sub 1 is default data sub.
@@ -591,10 +590,10 @@
 
     @Test
     @SmallTest
-    public void testAutoDataSwitchSetNotification() throws Exception {
+    public void testAutoDataSwitch_setNotification() throws Exception {
         SubscriptionInfo mockedInfo = mock(SubscriptionInfo.class);
         doReturn(false).when(mockedInfo).isOpportunistic();
-        doReturn(mockedInfo).when(mSubscriptionController).getSubscriptionInfo(anyInt());
+        doReturn(mockedInfo).when(mSubscriptionManagerService).getSubscriptionInfo(anyInt());
         initialize();
         // Phone 0 has sub 1, phone 1 has sub 2.
         // Sub 1 is default data sub.
@@ -603,23 +602,59 @@
         setDefaultDataSubId(1);
 
         testAutoSwitchToSecondarySucceed();
-        clearInvocations(mSubscriptionController);
+        clearInvocations(mSubscriptionManagerService);
         Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1, null,  null))
                 .sendToTarget();
         processAllMessages();
-        verify(mSubscriptionController).getSubscriptionInfo(2);
-
+        verify(mSubscriptionManagerService).getSubscriptionInfo(2);
         // switch back to primary
-        clearInvocations(mSubscriptionController);
+        clearInvocations(mSubscriptionManagerService);
         Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(0, null,  null))
                 .sendToTarget();
         processAllMessages();
-        verify(mSubscriptionController, never()).getSubscriptionInfo(1);
+        verify(mSubscriptionManagerService, never()).getSubscriptionInfo(1);
 
         Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1, null,  null))
                 .sendToTarget();
         processAllMessages();
-        verify(mSubscriptionController, never()).getSubscriptionInfo(2);
+        verify(mSubscriptionManagerService, never()).getSubscriptionInfo(2);
+    }
+
+    @Test
+    @SmallTest
+    public void testAutoDataSwitch_exemptPingTest() throws Exception {
+        initialize();
+        // Change resource overlay
+        doReturn(false).when(mDataConfigManager).isPingTestBeforeAutoDataSwitchRequired();
+        mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper());
+        processAllMessages();
+
+        // Phone 0 has sub 1, phone 1 has sub 2.
+        // Sub 1 is default data sub.
+        setSlotIndexToSubId(0, 1);
+        setSlotIndexToSubId(1, 2);
+        setDefaultDataSubId(1);
+
+        //1. Attempting to switch to nDDS, switch even if validation failed
+        prepareIdealAutoSwitchCondition();
+        processAllFutureMessages();
+
+        verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false),
+                eq(mPhoneSwitcherUT.mValidationCallback));
+        mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 2);
+        processAllMessages();
+
+        assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId()); // switch succeeds
+
+        //2. Attempting to switch back to DDS, switch even if validation failed
+        serviceStateChanged(0, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+        processAllFutureMessages();
+        verify(mCellularNetworkValidator).validate(eq(1), anyLong(), eq(false),
+                eq(mPhoneSwitcherUT.mValidationCallback));
+        mPhoneSwitcherUT.mValidationCallback.onValidationDone(false, 1);
+        processAllMessages();
+
+        assertEquals(1, mPhoneSwitcherUT.getActiveDataSubId()); // switch succeeds
     }
 
     /**
@@ -718,7 +753,9 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
 
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
 
         // Notify phoneSwitcher about default data sub and default network request.
         addInternetNetworkRequest(null, 50);
@@ -762,7 +799,7 @@
         setSlotIndexToSubId(0, 1);
         setSlotIndexToSubId(1, 2);
         // single visible sub, as the other one is CBRS
-        doReturn(new int[1]).when(mSubscriptionController).getActiveSubIdList(true);
+        doReturn(new int[1]).when(mSubscriptionManagerService).getActiveSubIdList(true);
         setDefaultDataSubId(1);
 
         // Notify phoneSwitcher about default data sub and default network request.
@@ -818,7 +855,7 @@
         setDefaultDataSubId(1);
 
         clearInvocations(mCellularNetworkValidator);
-        doReturn(new int[1]).when(mSubscriptionController).getActiveSubIdList(true);
+        doReturn(new int[1]).when(mSubscriptionManagerService).getActiveSubIdList(true);
         prepareIdealAutoSwitchCondition();
         processAllFutureMessages();
 
@@ -871,7 +908,10 @@
                 new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
 
         // Set sub 2 as preferred sub should make phone 1 preferredDataModem
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
         mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, null);
         processAllMessages();
         mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2);
@@ -929,8 +969,6 @@
         doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
         initialize();
 
-        // Mark sub 2 as opportunistic.
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
         // 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.
@@ -938,6 +976,10 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
 
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
         // Phone 0 (sub 1) should be activated as it has default data sub.
         assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId());
 
@@ -1487,14 +1529,16 @@
         doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
         initialize();
 
-        // Mark sub 2 as opportunistic.
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
         // 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);
 
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
         // Switch to primary before a primary is selected/inactive.
         setDefaultDataSubId(-1);
         mPhoneSwitcherUT.trySetOpportunisticDataSubscription(
@@ -1646,7 +1690,10 @@
         setAllPhonesInactive();
         // Initialization done.
 
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
         mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1);
         processAllMessages();
         verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false),
@@ -1684,7 +1731,10 @@
         setAllPhonesInactive();
         // Initialization done.
 
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
+        doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+                .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
         mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1);
         processAllMessages();
         verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false),
@@ -1731,8 +1781,8 @@
         verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any());
 
         clearInvocations(mMockRadioConfig);
-        doReturn(mSubscriptionInfo).when(mSubscriptionController)
-            .getActiveSubscriptionInfoForSimSlotIndex(eq(0), any(), any());
+        doReturn(mSubscriptionInfo).when(mSubscriptionManagerService)
+                .getActiveSubscriptionInfoForSimSlotIndex(eq(0), any(), any());
         doReturn(true).when(mSubscriptionInfo).areUiccApplicationsEnabled();
         doReturn(mIccCard).when(mPhone).getIccCard();
         doReturn(true).when(mIccCard).isEmptyProfile();
@@ -1754,6 +1804,36 @@
         verify(mMockRadioConfig, times(1)).setPreferredDataModem(eq(0), any());
     }
 
+    @Test
+    public void testScheduledRetryWhileMultiSimConfigChange() throws Exception {
+        doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
+        initialize();
+
+        // Phone 0 has sub 1, phone 1 has sub 2.
+        // Sub 1 is default data sub.
+        setSlotIndexToSubId(0, 1);
+        setSlotIndexToSubId(1, 2);
+
+        // for EVENT_MODEM_COMMAND_RETRY
+        AsyncResult res = new AsyncResult(
+                1, null,  new CommandException(CommandException.Error.GENERIC_FAILURE));
+        Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget();
+        processAllMessages();
+
+        // reduce count of phone
+        setNumPhones(1, 1);
+        AsyncResult result = new AsyncResult(null, 1, null);
+        Message.obtain(mPhoneSwitcherUT, EVENT_MULTI_SIM_CONFIG_CHANGED, result).sendToTarget();
+        processAllMessages();
+
+        // fire retries
+        moveTimeForward(5000);
+        processAllMessages();
+
+        verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any());
+        verify(mCommandsInterface1, never()).setDataAllowed(anyBoolean(), any());
+    }
+
     /* Private utility methods start here */
 
     private void prepareIdealAutoSwitchCondition() {
@@ -1921,9 +2001,9 @@
         initializeCommandInterfacesMock();
         initializeTelRegistryMock();
         initializeConnManagerMock();
+        initializeConfigMock();
 
         mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper());
-        processAllMessages();
 
         Field field = PhoneSwitcher.class.getDeclaredField("mDataSettingsManagerCallbacks");
         field.setAccessible(true);
@@ -1931,11 +2011,7 @@
                 (Map<Integer, DataSettingsManager.DataSettingsManagerCallback>)
                         field.get(mPhoneSwitcherUT);
 
-        int deviceConfigValue = 10000;
-        field = PhoneSwitcher.class.getDeclaredField(
-                "mAutoDataSwitchAvailabilityStabilityTimeThreshold");
-        field.setAccessible(true);
-        field.setInt(mPhoneSwitcherUT, deviceConfigValue);
+        processAllMessages();
 
         verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any());
     }
@@ -2027,22 +2103,12 @@
      * network requests on PhoneSwitcher.
      */
     private void initializeSubControllerMock() throws Exception {
-        doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId();
+        doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId();
         doReturn(mDefaultDataSub).when(mMockedIsub).getDefaultDataSubId();
-        doReturn(0).when(mSubscriptionController).getPhoneId(1);
+        doReturn(0).when(mSubscriptionManagerService).getPhoneId(1);
         doReturn(0).when(mMockedIsub).getPhoneId(1);
-        doReturn(1).when(mSubscriptionController).getPhoneId(2);
+        doReturn(1).when(mSubscriptionManagerService).getPhoneId(2);
         doReturn(1).when(mMockedIsub).getPhoneId(2);
-        doAnswer(invocation -> {
-            int phoneId = (int) invocation.getArguments()[0];
-            if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
-                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-            } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
-                return mSlotIndexToSubId[0][0];
-            } else {
-                return mSlotIndexToSubId[phoneId][0];
-            }
-        }).when(mSubscriptionController).getSubId(anyInt());
 
         doAnswer(invocation -> {
             int phoneId = (int) invocation.getArguments()[0];
@@ -2056,23 +2122,45 @@
         }).when(mMockedIsub).getSubId(anyInt());
 
         doAnswer(invocation -> {
+            int phoneId = (int) invocation.getArguments()[0];
+            if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
+                return mSlotIndexToSubId[0][0];
+            } else {
+                return mSlotIndexToSubId[phoneId][0];
+            }
+        }).when(mSubscriptionManagerService).getSubId(anyInt());
+
+        doAnswer(invocation -> {
             int subId = (int) invocation.getArguments()[0];
 
-            if (!SubscriptionManager.isUsableSubIdValue(subId)) return false;
+            if (!SubscriptionManager.isUsableSubIdValue(subId)) return null;
 
+            int slotIndex = -1;
             for (int i = 0; i < mSlotIndexToSubId.length; i++) {
-                if (mSlotIndexToSubId[i][0] == subId) return true;
+                if (mSlotIndexToSubId[i][0] == subId) slotIndex = i;
             }
-            return false;
-        }).when(mSubscriptionController).isActiveSubId(anyInt());
-        doReturn(new int[mSlotIndexToSubId.length]).when(mSubscriptionController)
+            return new SubscriptionInfoInternal.Builder()
+                    .setSimSlotIndex(slotIndex).setId(subId).build();
+        }).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+        doReturn(new int[mSlotIndexToSubId.length]).when(mSubscriptionManagerService)
                 .getActiveSubIdList(true);
     }
 
+    private void initializeConfigMock() {
+        doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
+        doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager();
+        doReturn(1000L).when(mDataConfigManager)
+                .getAutoDataSwitchAvailabilityStabilityTimeThreshold();
+        doReturn(7).when(mDataConfigManager).getAutoDataSwitchValidationMaxRetry();
+        doReturn(true).when(mDataConfigManager).isPingTestBeforeAutoDataSwitchRequired();
+    }
+
     private void setDefaultDataSubId(int defaultDataSub) throws Exception {
         mDefaultDataSub = defaultDataSub;
-        doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId();
-        doReturn(mDefaultDataSub).when(mMockedIsub).getDefaultDataSubId();
+        doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId();
         if (defaultDataSub == 1) {
             doReturn(true).when(mPhone).isUserDataEnabled();
             doReturn(false).when(mPhone2).isUserDataEnabled();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
index a99518d..5941f06 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
@@ -49,7 +49,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -213,8 +212,7 @@
         // test at this time.
         doAnswer(invocation -> {
             final NetworkCapabilities capabilitiesFilter =
-                    mTelephonyNetworkFactoryUT.makeNetworkFilter(
-                            mSubscriptionController.getSubId(0));
+                    mTelephonyNetworkFactoryUT.makeNetworkFilter(mMockedIsub.getSubId(0));
             for (final TelephonyNetworkRequest request : mAllNetworkRequestSet) {
                 final int message = request.canBeSatisfiedBy(capabilitiesFilter)
                         ? CMD_REQUEST_NETWORK : CMD_CANCEL_REQUEST;
@@ -239,7 +237,6 @@
         createMockedTelephonyComponents();
 
         doReturn(false).when(mPhoneSwitcher).shouldApplyNetworkRequest(any(), anyInt());
-        doReturn(subId).when(mSubscriptionController).getSubId(phoneId);
         doReturn(subId).when(mMockedIsub).getSubId(phoneId);
         // fake onSubscriptionChangedListener being triggered.
         mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
@@ -302,7 +299,6 @@
      */
     @Test
     @SmallTest
-    @Ignore("b/256052233")
     public void testRequests() throws Exception {
         mTestName = "testActive";
         final int numberOfPhones = 2;
@@ -314,7 +310,6 @@
 
         createMockedTelephonyComponents();
 
-        doReturn(subId).when(mSubscriptionController).getSubId(phoneId);
         doReturn(subId).when(mMockedIsub).getSubId(phoneId);
         mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
                 TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
@@ -329,7 +324,6 @@
         processAllMessages();
         assertEquals(1, mNetworkRequestList.size());
 
-        doReturn(altSubId).when(mSubscriptionController).getSubId(altPhoneId);
         doReturn(altSubId).when(mMockedIsub).getSubId(altPhoneId);
         processAllMessages();
         assertEquals(1, mNetworkRequestList.size());
@@ -345,7 +339,6 @@
         processAllMessages();
         assertEquals(1, mNetworkRequestList.size());
 
-        doReturn(unusedSubId).when(mSubscriptionController).getSubId(phoneId);
         doReturn(unusedSubId).when(mMockedIsub).getSubId(phoneId);
         mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
                 TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
@@ -356,7 +349,6 @@
         processAllMessages();
         assertEquals(0, mNetworkRequestList.size());
 
-        doReturn(subId).when(mSubscriptionController).getSubId(phoneId);
         doReturn(subId).when(mMockedIsub).getSubId(phoneId);
         mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
                 TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
new file mode 100644
index 0000000..ce59cc6
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
@@ -0,0 +1,311 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
+import static android.telephony.DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.os.AsyncResult;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelector;
+import android.telephony.EmergencyRegResult;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.telephony.ims.ImsReasonInfo;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.CallFailCause;
+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.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DomainSelectionConnectionTest extends TelephonyTest {
+
+    private static final String TELECOM_CALL_ID1 = "TC1";
+
+    private DomainSelectionController mDomainSelectionController;
+    private DomainSelectionConnection.DomainSelectionConnectionCallback mConnectionCallback;
+    private DomainSelectionConnection mDsc;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(this.getClass().getSimpleName());
+
+        mDomainSelectionController = Mockito.mock(DomainSelectionController.class);
+        mConnectionCallback =
+                Mockito.mock(DomainSelectionConnection.DomainSelectionConnectionCallback.class);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mDsc = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testTransportSelectorCallback() {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomain() {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
+                false, 0, null, null, null, null);
+
+        mDsc.selectDomain(attr);
+
+        verify(mDomainSelectionController).selectDomain(any(), eq(transportCallback));
+    }
+
+    @Test
+    @SmallTest
+    public void testWwanSelectorCallback() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        WwanSelectorCallback wwanCallback = null;
+        wwanCallback = transportCallback.onWwanSelected();
+
+        assertNotNull(wwanCallback);
+    }
+
+    @Test
+    @SmallTest
+    public void testWwanSelectorCallbackAsync() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+        replaceInstance(DomainSelectionConnection.class, "mWwanSelectedExecutor",
+                mDsc, new Executor() {
+                    public void execute(Runnable command) {
+                        command.run();
+                    }
+                });
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        Consumer<WwanSelectorCallback> consumer = Mockito.mock(Consumer.class);
+        transportCallback.onWwanSelected(consumer);
+
+        verify(consumer).accept(any());
+    }
+
+    @Test
+    @SmallTest
+    public void testWwanSelectorCallbackOnRequestEmergencyNetworkScan() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        WwanSelectorCallback wwanCallback = transportCallback.onWwanSelected();
+
+        assertNotNull(wwanCallback);
+
+        replaceInstance(DomainSelectionConnection.class, "mLooper",
+                mDsc, mTestableLooper.getLooper());
+        List<Integer> preferredNetworks = new ArrayList<>();
+        preferredNetworks.add(EUTRAN);
+        preferredNetworks.add(UTRAN);
+        int scanType = SCAN_TYPE_NO_PREFERENCE;
+        Consumer<EmergencyRegResult> consumer = Mockito.mock(Consumer.class);
+
+        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, null, consumer);
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);
+
+        verify(mPhone).registerForEmergencyNetworkScan(
+                handlerCaptor.capture(), eventCaptor.capture(), any());
+
+        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
+
+        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
+                eq(scanType), any());
+
+        Handler handler = handlerCaptor.getValue();
+        int event = eventCaptor.getValue();
+
+        assertNotNull(handler);
+
+        doReturn(new Executor() {
+            public void execute(Runnable r) {
+                r.run();
+            }
+        }).when(mDomainSelectionController).getDomainSelectionServiceExecutor();
+        EmergencyRegResult regResult =
+                new EmergencyRegResult(UTRAN, 0, 0, true, false, 0, 0, "", "", "");
+        handler.sendMessage(handler.obtainMessage(event, new AsyncResult(null, regResult, null)));
+        processAllMessages();
+
+        verify(consumer).accept(eq(regResult));
+    }
+
+    @Test
+    @SmallTest
+    public void testWwanSelectorCallbackOnRequestEmergencyNetworkScanAndCancel() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        WwanSelectorCallback wwanCallback = transportCallback.onWwanSelected();
+
+        assertNotNull(wwanCallback);
+
+        replaceInstance(DomainSelectionConnection.class, "mLooper",
+                mDsc, mTestableLooper.getLooper());
+        CancellationSignal signal = new CancellationSignal();
+        wwanCallback.onRequestEmergencyNetworkScan(new ArrayList<>(),
+                SCAN_TYPE_NO_PREFERENCE, signal, Mockito.mock(Consumer.class));
+
+        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());
+
+        signal.cancel();
+
+        verify(mPhone).cancelEmergencyNetworkScan(eq(false), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectorCancelSelection() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelector domainSelector = Mockito.mock(DomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        mDsc.cancelSelection();
+
+        verify(domainSelector).cancelSelection();
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectorReselectDomain() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelector domainSelector = Mockito.mock(DomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
+                false, CallFailCause.ERROR_UNSPECIFIED, null, null, null, null);
+
+        CompletableFuture<Integer> future = mDsc.reselectDomain(attr);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(domainSelector).reselectDomain(any());
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectorFinishSelection() throws Exception {
+        mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelector domainSelector = Mockito.mock(DomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        mDsc.finishSelection();
+
+        verify(domainSelector).finishSelection();
+    }
+
+    private DomainSelectionService.SelectionAttributes getSelectionAttributes(
+            int slotId, int subId, int selectorType, boolean isEmergency,
+            boolean exited, int callFailCause, String callId, String number,
+            ImsReasonInfo imsReasonInfo, EmergencyRegResult regResult) {
+        DomainSelectionService.SelectionAttributes.Builder builder =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        slotId, subId, selectorType)
+                .setEmergency(isEmergency)
+                .setExitedFromAirplaneMode(exited)
+                .setCsDisconnectCause(callFailCause);
+
+        if (callId != null) builder.setCallId(callId);
+        if (number != null) builder.setNumber(number);
+        if (imsReasonInfo != null) builder.setPsDisconnectCause(imsReasonInfo);
+        if (regResult != null) builder.setEmergencyRegResult(regResult);
+
+        return builder.build();
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java
new file mode 100644
index 0000000..2c65b50
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+
+import static com.android.internal.telephony.RIL.RADIO_HAL_VERSION_2_0;
+import static com.android.internal.telephony.RIL.RADIO_HAL_VERSION_2_1;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+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.Mockito.when;
+
+import android.content.Context;
+import android.telephony.DomainSelectionService;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.HalVersion;
+import com.android.internal.telephony.Phone;
+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;
+
+/**
+ * Unit tests for DomainSelectionResolver.
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DomainSelectionResolverTest extends TelephonyTest {
+    // Mock classes
+    private DomainSelectionController mDsController;
+    private DomainSelectionConnection mDsConnection;
+    private DomainSelectionService mDsService;
+
+    private DomainSelectionResolver mDsResolver;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+
+        mDsController = Mockito.mock(DomainSelectionController.class);
+        mDsConnection = Mockito.mock(DomainSelectionConnection.class);
+        mDsService = Mockito.mock(DomainSelectionService.class);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mDsResolver = null;
+        mDsService = null;
+        mDsConnection = null;
+        mDsController = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testGetInstance() throws IllegalStateException {
+        assertThrows(IllegalStateException.class, () -> {
+            DomainSelectionResolver.getInstance();
+        });
+
+        DomainSelectionResolver.make(mContext, true);
+        DomainSelectionResolver resolver = DomainSelectionResolver.getInstance();
+
+        assertNotNull(resolver);
+    }
+
+    @Test
+    @SmallTest
+    public void testIsDomainSelectionSupportedWhenDeviceConfigDisabled() {
+        setUpResolver(false, RADIO_HAL_VERSION_2_1);
+
+        assertFalse(mDsResolver.isDomainSelectionSupported());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsDomainSelectionSupportedWhenHalVersionLessThan20() {
+        setUpResolver(true, RADIO_HAL_VERSION_2_0);
+
+        assertFalse(mDsResolver.isDomainSelectionSupported());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsDomainSelectionSupported() {
+        setUpResolver(true, RADIO_HAL_VERSION_2_1);
+
+        assertTrue(mDsResolver.isDomainSelectionSupported());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetDomainSelectionConnectionWhenNotInitialized() throws Exception {
+        setUpResolver(true, RADIO_HAL_VERSION_2_1);
+
+        assertThrows(IllegalStateException.class, () -> {
+            mDsResolver.getDomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true);
+        });
+    }
+
+    @Test
+    @SmallTest
+    public void testGetDomainSelectionConnectionWhenPhoneNull() throws Exception {
+        setUpResolver(true, RADIO_HAL_VERSION_2_1);
+        mDsResolver.initialize(mDsService);
+        assertNull(mDsResolver.getDomainSelectionConnection(null, SELECTOR_TYPE_CALLING, true));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetDomainSelectionConnectionWhenImsNotAvailable() throws Exception {
+        setUpResolver(true, RADIO_HAL_VERSION_2_1);
+        mDsResolver.initialize(mDsService);
+        when(mPhone.isImsAvailable()).thenReturn(false);
+
+        assertNull(mDsResolver.getDomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetDomainSelectionConnection() throws Exception {
+        setUpResolver(true, RADIO_HAL_VERSION_2_1);
+        setUpController();
+        mDsResolver.initialize(mDsService);
+        when(mPhone.isImsAvailable()).thenReturn(true);
+
+        assertNotNull(mDsResolver.getDomainSelectionConnection(
+                mPhone, SELECTOR_TYPE_CALLING, true));
+    }
+
+    private void setUpResolver(boolean deviceConfigEnabled, HalVersion halVersion) {
+        mDsResolver = new DomainSelectionResolver(mContext, deviceConfigEnabled);
+        when(mPhone.getHalVersion(eq(HAL_SERVICE_NETWORK))).thenReturn(halVersion);
+    }
+
+    private void setUpController() {
+        mDsResolver.setDomainSelectionControllerFactory(
+                new DomainSelectionResolver.DomainSelectionControllerFactory() {
+                    @Override
+                    public DomainSelectionController create(Context context,
+                            DomainSelectionService service) {
+                        return mDsController;
+                    }
+                });
+
+        when(mDsController.getDomainSelectionConnection(any(Phone.class), anyInt(), anyBoolean()))
+                .thenReturn(mDsConnection);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnectionTest.java
new file mode 100644
index 0000000..0c64b82
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencyCallDomainSelectionConnectionTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+import static android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
+
+import static com.android.internal.telephony.PhoneConstants.DOMAIN_NON_3GPP_PS;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+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.data.AccessNetworksManager;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.concurrent.CompletableFuture;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class EmergencyCallDomainSelectionConnectionTest extends TelephonyTest {
+
+    private static final String TELECOM_CALL_ID1 = "TC1";
+
+    private DomainSelectionController mDomainSelectionController;
+    private DomainSelectionConnection.DomainSelectionConnectionCallback mConnectionCallback;
+    private EmergencyCallDomainSelectionConnection mEcDsc;
+    private AccessNetworksManager mAnm;
+    private TransportSelectorCallback mTransportCallback;
+    private EmergencyStateTracker mEmergencyStateTracker;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(this.getClass().getSimpleName());
+
+        mDomainSelectionController = Mockito.mock(DomainSelectionController.class);
+        mConnectionCallback =
+                Mockito.mock(DomainSelectionConnection.DomainSelectionConnectionCallback.class);
+        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
+        mAnm = Mockito.mock(AccessNetworksManager.class);
+        doReturn(mAnm).when(mPhone).getAccessNetworksManager();
+        mEcDsc = new EmergencyCallDomainSelectionConnection(mPhone,
+                mDomainSelectionController, mEmergencyStateTracker);
+        mTransportCallback = mEcDsc.getTransportSelectorCallback();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mEcDsc = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWifi() throws Exception {
+        doReturn(TRANSPORT_TYPE_WLAN).when(mAnm).getPreferredTransport(anyInt());
+        replaceInstance(EmergencyCallDomainSelectionConnection.class,
+                "mEmergencyStateTracker", mEcDsc, mEmergencyStateTracker);
+
+        EmergencyRegResult regResult = new EmergencyRegResult(
+                EUTRAN, REGISTRATION_STATE_UNKNOWN,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "", "");
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        mPhone.getPhoneId(), mPhone.getSubId(), false,
+                        TELECOM_CALL_ID1, "911", 0, null, regResult);
+
+        CompletableFuture<Integer> future =
+                mEcDsc.createEmergencyConnection(attr, mConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mDomainSelectionController).selectDomain(any(), any());
+
+        mTransportCallback.onWlanSelected(true);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_NON_3GPP_PS, (long) future.get());
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_CALL), eq(MODE_EMERGENCY_WLAN));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainCs() throws Exception {
+        doReturn(TRANSPORT_TYPE_WWAN).when(mAnm).getPreferredTransport(anyInt());
+        replaceInstance(EmergencyCallDomainSelectionConnection.class,
+                "mEmergencyStateTracker", mEcDsc, mEmergencyStateTracker);
+
+        EmergencyRegResult regResult = new EmergencyRegResult(
+                UTRAN, REGISTRATION_STATE_UNKNOWN,
+                NetworkRegistrationInfo.DOMAIN_CS,
+                true, false, 0, 0, "", "", "");
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        mPhone.getPhoneId(), mPhone.getSubId(), false,
+                        TELECOM_CALL_ID1, "911", 0, null, regResult);
+
+        CompletableFuture<Integer> future =
+                mEcDsc.createEmergencyConnection(attr, mConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mDomainSelectionController).selectDomain(any(), any());
+
+        WwanSelectorCallback wwanCallback = null;
+        wwanCallback = mTransportCallback.onWwanSelected();
+
+        assertFalse(future.isDone());
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_CALL), eq(MODE_EMERGENCY_WWAN));
+
+        wwanCallback.onDomainSelected(DOMAIN_CS, false);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_CS, (long) future.get());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainPs() throws Exception {
+        doReturn(TRANSPORT_TYPE_WWAN).when(mAnm).getPreferredTransport(anyInt());
+        replaceInstance(EmergencyCallDomainSelectionConnection.class,
+                "mEmergencyStateTracker", mEcDsc, mEmergencyStateTracker);
+
+        EmergencyRegResult regResult = new EmergencyRegResult(
+                EUTRAN, REGISTRATION_STATE_UNKNOWN,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "", "");
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        mPhone.getPhoneId(), mPhone.getSubId(), false,
+                        TELECOM_CALL_ID1, "911", 0, null, regResult);
+
+        CompletableFuture<Integer> future =
+                mEcDsc.createEmergencyConnection(attr, mConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mDomainSelectionController).selectDomain(any(), any());
+
+        WwanSelectorCallback wwanCallback = null;
+        wwanCallback = mTransportCallback.onWwanSelected();
+
+        assertFalse(future.isDone());
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_CALL), eq(MODE_EMERGENCY_WWAN));
+
+        wwanCallback.onDomainSelected(DOMAIN_PS, true);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_PS, (long) future.get());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnSelectionTerminated() throws Exception {
+        EmergencyRegResult regResult = new EmergencyRegResult(
+                EUTRAN, REGISTRATION_STATE_UNKNOWN,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "", "");
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        mPhone.getPhoneId(), mPhone.getSubId(), false,
+                        TELECOM_CALL_ID1, "911", 0, null, regResult);
+
+        mEcDsc.createEmergencyConnection(attr, mConnectionCallback);
+        mTransportCallback.onSelectionTerminated(ERROR_UNSPECIFIED);
+
+        verify(mConnectionCallback).onSelectionTerminated(eq(ERROR_UNSPECIFIED));
+    }
+
+    @Test
+    @SmallTest
+    public void testCancelSelection() throws Exception {
+        mEcDsc.cancelSelection();
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnectionTest.java
new file mode 100644
index 0000000..25ccecb
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/EmergencySmsDomainSelectionConnectionTest.java
@@ -0,0 +1,459 @@
+/*
+ * 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.domainselection;
+
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelector;
+import android.telephony.NetworkRegistrationInfo;
+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.data.AccessNetworksManager;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
+
+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.concurrent.CompletableFuture;
+
+/**
+ * Unit tests for EmergencySmsDomainSelectionConnection.
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class EmergencySmsDomainSelectionConnectionTest extends TelephonyTest {
+    private DomainSelectionController mDsController;
+    private DomainSelectionConnection.DomainSelectionConnectionCallback mDscCallback;
+    private DomainSelector mDomainSelector;
+    private EmergencyStateTracker mEmergencyStateTracker;
+
+    private Handler mHandler;
+    private AccessNetworksManager mAnm;
+    private DomainSelectionService.SelectionAttributes mDsAttr;
+    private EmergencySmsDomainSelectionConnection mDsConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(this.getClass().getSimpleName());
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mHandler = new Handler(Looper.myLooper());
+        mDsController = Mockito.mock(DomainSelectionController.class);
+        mDscCallback = Mockito.mock(
+                DomainSelectionConnection.DomainSelectionConnectionCallback.class);
+        mDomainSelector = Mockito.mock(DomainSelector.class);
+        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
+        mAnm = Mockito.mock(AccessNetworksManager.class);
+        when(mPhone.getAccessNetworksManager()).thenReturn(mAnm);
+
+        mDsConnection = new EmergencySmsDomainSelectionConnection(
+                mPhone, mDsController, mEmergencyStateTracker);
+        mDsConnection.getTransportSelectorCallback().onCreated(mDomainSelector);
+        mDsAttr = new DomainSelectionService.SelectionAttributes.Builder(
+                mPhone.getPhoneId(), mPhone.getSubId(), DomainSelectionService.SELECTOR_TYPE_SMS)
+                .setEmergency(true)
+                .build();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mDomainSelector = null;
+        mDsAttr = null;
+        mDsConnection = null;
+        mDscCallback = null;
+        mDsController = null;
+        mEmergencyStateTracker = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnWlanSelected() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt()))
+                .thenReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onWlanSelected(true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_SMS), eq(MODE_EMERGENCY_WLAN));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnWlanSelectedWithDifferentTransportType() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onWlanSelected(true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_SMS), eq(MODE_EMERGENCY_WLAN));
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnWlanSelectedWithDifferentTransportTypeAndImsPdn() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onWlanSelected(false);
+        processAllMessages();
+
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_SMS), eq(MODE_EMERGENCY_WLAN));
+        verify(mAnm, never()).registerForQualifiedNetworksChanged(any(Handler.class), anyInt());
+        verify(mPhone, never()).notifyEmergencyDomainSelected(anyInt());
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnWlanSelectedWithDifferentTransportTypeWhilePreferredTransportChanged()
+            throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onWlanSelected(true);
+        // When onWlanSelected() is called again,
+        // it will be ignored because the change of preferred transport is in progress.
+        // => onEmergencyTransportChanged() is called only once.
+        mDsConnection.onWlanSelected(true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_SMS), eq(MODE_EMERGENCY_WLAN));
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnWwanSelected() throws Exception {
+        mDsConnection.onWwanSelected();
+
+        verify(mEmergencyStateTracker).onEmergencyTransportChanged(
+                eq(EmergencyStateTracker.EMERGENCY_TYPE_SMS), eq(MODE_EMERGENCY_WWAN));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPs() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt()))
+                .thenReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPsWithDifferentTransportType() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPsWithDifferentTransportTypeAndImsPdn() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, false);
+        processAllMessages();
+
+        verify(mAnm, never()).registerForQualifiedNetworksChanged(any(Handler.class), anyInt());
+        verify(mPhone, never()).notifyEmergencyDomainSelected(anyInt());
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPsWithDifferentTransportTypeAndNotChanged() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+
+        assertFalse(future.isDone());
+        verify(mAnm, never()).unregisterForQualifiedNetworksChanged(any(Handler.class));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPsWithDifferentTransportTypeWhilePreferredTransportChanged()
+            throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        // When onDomainSelected() is called again with the different domain,
+        // it will be ignored because the change of preferred transport is in progress.
+        // => The domain selection result is DOMAIN_PS.
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS, false);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+
+        assertTrue(future.isDone());
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedCs() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt()))
+                .thenReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_CS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS, false);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testFinishSelection() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+
+        mDsConnection.finishSelection();
+        processAllMessages();
+
+        assertFalse(future.isDone());
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+        verify(mDomainSelector).cancelSelection();
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testFinishSelectionAfterDomainSelectionCompleted() throws Exception {
+        when(mAnm.getPreferredTransport(anyInt())).thenReturn(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, true);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> msgCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mAnm).registerForQualifiedNetworksChanged(
+                handlerCaptor.capture(), msgCaptor.capture());
+        verify(mPhone).notifyEmergencyDomainSelected(
+                eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
+
+        Handler handler = handlerCaptor.getValue();
+        Integer msg = msgCaptor.getValue();
+        handler.handleMessage(Message.obtain(handler, msg.intValue()));
+        processAllMessages();
+        mDsConnection.finishSelection();
+
+        assertTrue(future.isDone());
+        // This method should be invoked one time.
+        verify(mAnm).unregisterForQualifiedNetworksChanged(any(Handler.class));
+        verify(mDomainSelector).finishSelection();
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnectionTest.java
new file mode 100644
index 0000000..0403232
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/NormalCallDomainSelectionConnectionTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.domainselection;
+
+import static android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.telephony.DomainSelectionService;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.telephony.ims.ImsReasonInfo;
+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.data.AccessNetworksManager;
+import com.android.internal.telephony.domainselection.DomainSelectionConnection;
+import com.android.internal.telephony.domainselection.DomainSelectionController;
+import com.android.internal.telephony.domainselection.NormalCallDomainSelectionConnection;
+
+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;
+
+import java.util.concurrent.CompletableFuture;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class NormalCallDomainSelectionConnectionTest extends TelephonyTest {
+
+    private static final String TELECOM_CALL_ID1 = "TC1";
+
+    @Mock
+    private DomainSelectionController mMockDomainSelectionController;
+    @Mock
+    private DomainSelectionConnection.DomainSelectionConnectionCallback mMockConnectionCallback;
+    @Mock
+    private AccessNetworksManager mMockAccessNetworksManager;
+
+    private TransportSelectorCallback mTransportCallback;
+    private NormalCallDomainSelectionConnection mNormalCallDomainSelectionConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(this.getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+        doReturn(mMockAccessNetworksManager).when(mPhone).getAccessNetworksManager();
+        mNormalCallDomainSelectionConnection =
+                new NormalCallDomainSelectionConnection(mPhone, mMockDomainSelectionController);
+        mTransportCallback = mNormalCallDomainSelectionConnection.getTransportSelectorCallback();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mNormalCallDomainSelectionConnection = null;
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWifi() throws Exception {
+        DomainSelectionService.SelectionAttributes attributes =
+                NormalCallDomainSelectionConnection.getSelectionAttributes(mPhone.getPhoneId(),
+                        mPhone.getSubId(), TELECOM_CALL_ID1, "123", false, 0, null);
+
+        CompletableFuture<Integer> future =
+                mNormalCallDomainSelectionConnection
+                        .createNormalConnection(attributes, mMockConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mMockDomainSelectionController).selectDomain(any(), any());
+
+        mTransportCallback.onWlanSelected(false);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_PS, (long) future.get());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainCs() throws Exception {
+        DomainSelectionService.SelectionAttributes attributes =
+                NormalCallDomainSelectionConnection.getSelectionAttributes(mPhone.getPhoneId(),
+                        mPhone.getSubId(), TELECOM_CALL_ID1, "123", false, 0, null);
+
+        CompletableFuture<Integer> future =
+                mNormalCallDomainSelectionConnection
+                        .createNormalConnection(attributes, mMockConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mMockDomainSelectionController).selectDomain(any(), any());
+
+        WwanSelectorCallback wwanCallback = mTransportCallback.onWwanSelected();
+
+        assertFalse(future.isDone());
+        wwanCallback.onDomainSelected(DOMAIN_CS, false);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_CS, (long) future.get());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainPs() throws Exception {
+        DomainSelectionService.SelectionAttributes attributes =
+                NormalCallDomainSelectionConnection.getSelectionAttributes(mPhone.getPhoneId(),
+                        mPhone.getSubId(), TELECOM_CALL_ID1, "123", false, 0, null);
+
+        CompletableFuture<Integer> future =
+                mNormalCallDomainSelectionConnection
+                        .createNormalConnection(attributes, mMockConnectionCallback);
+
+        assertNotNull(future);
+        assertFalse(future.isDone());
+
+        verify(mMockDomainSelectionController).selectDomain(any(), any());
+
+        WwanSelectorCallback wwanCallback = mTransportCallback.onWwanSelected();
+
+        assertFalse(future.isDone());
+        wwanCallback.onDomainSelected(DOMAIN_PS, false);
+
+        assertTrue(future.isDone());
+        assertEquals((long) DOMAIN_PS, (long) future.get());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnSelectionTerminated() throws Exception {
+        DomainSelectionService.SelectionAttributes attributes =
+                NormalCallDomainSelectionConnection.getSelectionAttributes(mPhone.getPhoneId(),
+                        mPhone.getSubId(), TELECOM_CALL_ID1, "123", false, 0, null);
+
+        CompletableFuture<Integer> future = mNormalCallDomainSelectionConnection
+                .createNormalConnection(attributes, mMockConnectionCallback);
+        mTransportCallback.onSelectionTerminated(ERROR_UNSPECIFIED);
+
+        verify(mMockConnectionCallback).onSelectionTerminated(eq(ERROR_UNSPECIFIED));
+        assertNotNull(future);
+    }
+
+    @Test
+    public void testGetSelectionAttributes() throws Exception {
+        ImsReasonInfo imsReasonInfo = new ImsReasonInfo();
+        DomainSelectionService.SelectionAttributes attributes =
+                NormalCallDomainSelectionConnection.getSelectionAttributes(1, 2,
+                        TELECOM_CALL_ID1, "123", false, 10, imsReasonInfo);
+
+        assertEquals(1, attributes.getSlotId());
+        assertEquals(2, attributes.getSubId());
+        assertEquals(TELECOM_CALL_ID1, attributes.getCallId());
+        assertEquals("123", attributes.getNumber());
+        assertEquals(false, attributes.isVideoCall());
+        assertEquals(false, attributes.isEmergency());
+        assertEquals(SELECTOR_TYPE_CALLING, attributes.getSelectorType());
+        assertEquals(10, attributes.getCsDisconnectCause());
+        assertEquals(imsReasonInfo, attributes.getPsDisconnectCause());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/SmsDomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/SmsDomainSelectionConnectionTest.java
new file mode 100644
index 0000000..e4afa79
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/SmsDomainSelectionConnectionTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.domainselection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelector;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TransportSelectorCallback;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.telephony.Phone;
+
+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;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Unit tests for SmsDomainSelectionConnection.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SmsDomainSelectionConnectionTest {
+    private static final int SLOT_ID = 0;
+    private static final int SUB_ID = 1;
+
+    @Mock private Phone mPhone;
+    @Mock private DomainSelectionController mDsController;
+    @Mock private DomainSelectionConnection.DomainSelectionConnectionCallback mDscCallback;
+    @Mock private DomainSelector mDomainSelector;
+
+    private Handler mHandler;
+    private TestableLooper mTestableLooper;
+    private DomainSelectionService.SelectionAttributes mDsAttr;
+    private SmsDomainSelectionConnection mDsConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        HandlerThread handlerThread = new HandlerThread(
+                SmsDomainSelectionConnectionTest.class.getSimpleName());
+        handlerThread.start();
+
+        mHandler = new Handler(handlerThread.getLooper());
+        mDsConnection = new SmsDomainSelectionConnection(mPhone, mDsController);
+        mDsConnection.getTransportSelectorCallback().onCreated(mDomainSelector);
+        mDsAttr = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID, DomainSelectionService.SELECTOR_TYPE_SMS).build();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestableLooper != null) {
+            mTestableLooper.destroy();
+            mTestableLooper = null;
+        }
+
+        if (mHandler != null) {
+            mHandler.getLooper().quit();
+            mHandler = null;
+        }
+
+        mDomainSelector = null;
+        mDsAttr = null;
+        mDsConnection = null;
+        mDscCallback = null;
+        mDsController = null;
+        mPhone = null;
+    }
+
+    @Test
+    @SmallTest
+    public void testRequestDomainSelection() {
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+
+        assertNotNull(future);
+        verify(mDsController).selectDomain(eq(mDsAttr), any(TransportSelectorCallback.class));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnWlanSelected() throws Exception {
+        setUpTestableLooper();
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onWlanSelected();
+        processAllMessages();
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnSelectionTerminated() {
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        mDsConnection.onSelectionTerminated(DisconnectCause.LOCAL);
+
+        assertFalse(future.isDone());
+        verify(mDscCallback).onSelectionTerminated(eq(DisconnectCause.LOCAL));
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedPs() throws Exception {
+        setUpTestableLooper();
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testOnDomainSelectedCs() throws Exception {
+        setUpTestableLooper();
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_CS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS);
+        processAllMessages();
+
+        assertTrue(future.isDone());
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testFinishSelection() throws Exception {
+        setUpTestableLooper();
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS);
+        processAllMessages();
+        mDsConnection.finishSelection();
+
+        verify(mDomainSelector).finishSelection();
+    }
+
+    @Test
+    @SmallTest
+    @SuppressWarnings("FutureReturnValueIgnored")
+    public void testCancelSelection() throws Exception {
+        CompletableFuture<Integer> future =
+                mDsConnection.requestDomainSelection(mDsAttr, mDscCallback);
+        future.thenAcceptAsync((domain) -> {
+            assertEquals(Integer.valueOf(NetworkRegistrationInfo.DOMAIN_PS), domain);
+        }, mHandler::post);
+
+        mDsConnection.finishSelection();
+
+        verify(mDomainSelector).cancelSelection();
+    }
+
+    private void setUpTestableLooper() throws Exception {
+        mTestableLooper = new TestableLooper(mHandler.getLooper());
+    }
+
+    private void processAllMessages() {
+        while (!mTestableLooper.getLooper().getQueue().isIdle()) {
+            mTestableLooper.processAllMessages();
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
index 1273148..5653209 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTest.java
@@ -261,7 +261,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
 
@@ -284,7 +284,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testSameEmergencyNumberDifferentMnc() throws Exception {
@@ -306,7 +306,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testSameEmergencyNumberDifferentCategories() throws Exception {
@@ -328,7 +328,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testSameEmergencyNumberDifferentUrns() throws Exception {
@@ -357,7 +357,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testSameEmergencyNumberCallRouting() throws Exception {
@@ -379,7 +379,36 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        /* case 1: Check routing is not checked when comparing the same numbers. As routing will
+        be unknown for all numbers apart from DB. Check merge when both are not from DB then
+        routing value is merged from first number. */
+        assertTrue(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
+        assertEquals(num1, EmergencyNumber.mergeSameEmergencyNumbers(num1, num2));
+
+        num2 = new EmergencyNumber(
+                "911",
+                "jp",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        /* case 1: Check routing is not checked when comparing the same numbers. Check merge when
+        one of the number is from DB then routing value is merged from DB number. Along with
+        source value is masked with both*/
+        assertTrue(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
+
+        num2 = new EmergencyNumber(
+                "911",
+                "jp",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        assertEquals(num2, EmergencyNumber.mergeSameEmergencyNumbers(num1, num2));
     }
 
     public void testSameEmergencyNumberDifferentSource() throws Exception {
@@ -401,7 +430,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertTrue(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertTrue(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testSameEmergencyNumberDifferentSourceTestOrNot() throws Exception {
@@ -423,7 +452,7 @@
                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
 
-        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2));
+        assertFalse(EmergencyNumber.areSameEmergencyNumbers(num1, num2, false));
     }
 
     public void testMergeSameNumbersInEmergencyNumberListWithDifferentSources() throws Exception {
@@ -595,4 +624,246 @@
 
         assertEquals(outputNumberList, inputNumberList);
     }
+
+    public void testMergeSameNumbersEmergencyNumberListByDeterminingFields() throws Exception {
+        List<String> urn1 = new ArrayList<>();
+        urn1.add("sos");
+
+        List<String> urn2 = new ArrayList<>();
+        urn2.add("sos:ambulance");
+
+        List<EmergencyNumber> inputNumberList = new ArrayList<>();
+        EmergencyNumber num1 = new EmergencyNumber(
+                "110",
+                "jp",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        EmergencyNumber num2 = new EmergencyNumber(
+                "110",
+                "jp",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                urn1,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num3 = new EmergencyNumber(
+                "911",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num4 = new EmergencyNumber(
+                "911",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        EmergencyNumber num5 = new EmergencyNumber(
+                "112",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        EmergencyNumber num6 = new EmergencyNumber(
+                "112",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                urn1,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num7 = new EmergencyNumber(
+                "108",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num8 = new EmergencyNumber(
+                "108",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num9 = new EmergencyNumber(
+                "102",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num10 = new EmergencyNumber(
+                "102",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE,
+                urn1,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber num11 = new EmergencyNumber(
+                "100",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_MIEC,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        EmergencyNumber num12 = new EmergencyNumber(
+                "100",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+
+        EmergencyNumber num13 = new EmergencyNumber(
+                "200",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        EmergencyNumber num14 = new EmergencyNumber(
+                "200",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        inputNumberList.add(num1);
+        inputNumberList.add(num2);
+        inputNumberList.add(num3);
+        inputNumberList.add(num4);
+        inputNumberList.add(num5);
+        inputNumberList.add(num6);
+        inputNumberList.add(num7);
+        inputNumberList.add(num8);
+        inputNumberList.add(num9);
+        inputNumberList.add(num10);
+        inputNumberList.add(num11);
+        inputNumberList.add(num12);
+        inputNumberList.add(num13);
+        inputNumberList.add(num14);
+
+        EmergencyNumber mergeOfNum1AndNum2 = new EmergencyNumber(
+                "110",
+                "jp",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                urn1,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        EmergencyNumber mergeOfNum3AndNum4 = new EmergencyNumber(
+                "911",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        List<String> mergedUrns1And2 = new ArrayList<>();
+        mergedUrns1And2.add("sos");
+        mergedUrns1And2.add("sos:ambulance");
+
+        EmergencyNumber mergeOfNum5AndNum6 = new EmergencyNumber(
+                "112",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                mergedUrns1And2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        EmergencyNumber mergeOfNum7AndNum8 = new EmergencyNumber(
+                "108",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber mergeOfNum11AndNum12 = new EmergencyNumber(
+                "100",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                urn2,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        List<String> mergedUrns2And1 = new ArrayList<>();
+        mergedUrns2And1.add("sos:ambulance");
+        mergedUrns2And1.add("sos");
+
+        EmergencyNumber mergeOfNum9AndNum10 = new EmergencyNumber(
+                "102",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                mergedUrns2And1,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_SIM,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+
+        EmergencyNumber mergeOfNum13AndNum14 = new EmergencyNumber(
+                "200",
+                "in",
+                "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        List<EmergencyNumber> outputNumberList = new ArrayList<>();
+        outputNumberList.add(mergeOfNum1AndNum2);
+        outputNumberList.add(mergeOfNum3AndNum4);
+        outputNumberList.add(mergeOfNum5AndNum6);
+        outputNumberList.add(mergeOfNum7AndNum8);
+        outputNumberList.add(mergeOfNum9AndNum10);
+        outputNumberList.add(mergeOfNum11AndNum12);
+        outputNumberList.add(mergeOfNum13AndNum14);
+        Collections.sort(outputNumberList);
+
+        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(inputNumberList, true);
+        assertEquals(outputNumberList, inputNumberList);
+    }
 }
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..c47eb3b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
@@ -19,27 +19,39 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.any;
 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.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.IntentFilter;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
 import android.os.AsyncResult;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
 import androidx.test.InstrumentationRegistry;
 
-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.ServiceStateTracker;
 import com.android.internal.telephony.TelephonyTest;
 
 import com.google.i18n.phonenumbers.ShortNumberInfo;
@@ -48,6 +60,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
 
 import java.io.BufferedInputStream;
 import java.io.File;
@@ -73,6 +87,7 @@
     private static final String EMERGENCY_NUMBER_DB_OTA_FILE = "eccdata_ota";
     private static final int CONFIG_UNIT_TEST_EMERGENCY_NUMBER_DB_VERSION = 99999;
     private static final String CONFIG_EMERGENCY_NUMBER_ADDRESS = "54321";
+    private static final String CONFIG_EMERGENCY_DUPLICATE_NUMBER = "4321";
     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";
@@ -96,13 +111,12 @@
     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 VALID_SLOT_INDEX_VALID_1 = 0;
+    private static final int VALID_SLOT_INDEX_VALID_2 = 1;
     private static final int INVALID_SLOT_INDEX_VALID = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-    private ParcelFileDescriptor mOtaPracelFileDescriptor = null;
+    private ParcelFileDescriptor mOtaParcelFileDescriptor = null;
     // Mocked classes
-    private SubscriptionController mSubControllerMock;
-    private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
+    private CarrierConfigManager mCarrierConfigManagerMock;
 
     // mEmergencyNumberTrackerMock for mPhone
     private EmergencyNumberTracker mEmergencyNumberTrackerMock;
@@ -115,15 +129,19 @@
 
     private File mLocalDownloadDirectory;
     private ShortNumberInfo mShortNumberInfo;
+    private Context mMockContext;
+    private Resources mResources;
 
     @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);
-        mContext = InstrumentationRegistry.getTargetContext();
+        mCarrierConfigManagerMock = mock(CarrierConfigManager.class);
+
+        mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext());
+        mMockContext = mock(Context.class);
+        mResources = mock(Resources.class);
 
         doReturn(mContext).when(mPhone).getContext();
         doReturn(0).when(mPhone).getPhoneId();
@@ -142,6 +160,9 @@
         // Copy an OTA file to the test directory to similate the OTA mechanism
         simulateOtaEmergencyNumberDb(mPhone);
 
+        AssetManager am = new AssetManager.Builder().build();
+        doReturn(am).when(mMockContext).getAssets();
+
         processAllMessages();
         logd("EmergencyNumberTrackerTest -Setup!");
     }
@@ -158,10 +179,10 @@
         mEmergencyNumberTrackerMock2 = null;
         mEmergencyNumberListTestSample.clear();
         mEmergencyNumberListTestSample = null;
-        if (mOtaPracelFileDescriptor != null) {
+        if (mOtaParcelFileDescriptor != null) {
             try {
-                mOtaPracelFileDescriptor.close();
-                mOtaPracelFileDescriptor = null;
+                mOtaParcelFileDescriptor.close();
+                mOtaParcelFileDescriptor = null;
             } catch (IOException e) {
                 logd("Failed to close emergency number db file folder for testing " + e.toString());
             }
@@ -182,6 +203,14 @@
             EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
             EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
         mEmergencyNumberListTestSample.add(emergencyNumberForTest);
+
+        emergencyNumberForTest = new EmergencyNumber(
+                CONFIG_EMERGENCY_DUPLICATE_NUMBER, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        mEmergencyNumberListTestSample.add(emergencyNumberForTest);
     }
 
     private void sendEmergencyNumberListFromRadio() {
@@ -219,11 +248,11 @@
         File file = new File(Environment.getExternalStorageDirectory(), LOCAL_DOWNLOAD_DIRECTORY
                 + "/" + EMERGENCY_NUMBER_DB_OTA_FILE);
         try {
-            mOtaPracelFileDescriptor = ParcelFileDescriptor.open(
+            mOtaParcelFileDescriptor = ParcelFileDescriptor.open(
                     file, ParcelFileDescriptor.MODE_READ_ONLY);
             emergencyNumberTrackerMock.obtainMessage(
                 EmergencyNumberTracker.EVENT_OVERRIDE_OTA_EMERGENCY_NUMBER_DB_FILE_PATH,
-                    mOtaPracelFileDescriptor).sendToTarget();
+                    mOtaParcelFileDescriptor).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());
@@ -268,6 +297,11 @@
         }
     }
 
+    private boolean hasDbEmergencyNumbers(List<EmergencyNumber> subList,
+            List<EmergencyNumber> list) {
+        return list.containsAll(subList);
+    }
+
     private boolean hasDbEmergencyNumber(EmergencyNumber number, List<EmergencyNumber> list) {
         return list.contains(number);
     }
@@ -298,27 +332,22 @@
     @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(
+        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
                 eq(SUB_ID_PHONE_1));
-        doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubControllerMock).getSlotIndex(
+        doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubscriptionManagerService).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(
+        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
                 eq(SUB_ID_PHONE_1));
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
+        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubscriptionManagerService).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));
+        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubscriptionManagerService).getSlotIndex(
+                anyInt());
         assertTrue(mEmergencyNumberTrackerMock.isSimAbsent());
     }
 
@@ -330,7 +359,42 @@
     }
 
     @Test
-    public void testUpdateEmergencyCountryIso() throws Exception {
+    public void testRegistrationForCountryChangeIntent() throws Exception {
+        EmergencyNumberTracker localEmergencyNumberTracker;
+        Context spyContext = spy(mContext);
+        doReturn(spyContext).when(mPhone).getContext();
+        ArgumentCaptor<IntentFilter> intentCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+
+        localEmergencyNumberTracker = new EmergencyNumberTracker(mPhone, mSimulatedCommands);
+        verify(spyContext, times(1)).registerReceiver(any(), intentCaptor.capture());
+        IntentFilter ifilter = intentCaptor.getValue();
+        assertTrue(ifilter.hasAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED));
+    }
+
+    @Test
+    public void testUpdateEmergencyCountryIso_whenStatePowerOff() throws Exception {
+        testUpdateEmergencyCountryIso(ServiceState.STATE_POWER_OFF);
+    }
+
+    @Test
+    public void testUpdateEmergencyCountryIso_whenStateInService() throws Exception {
+        testUpdateEmergencyCountryIso(ServiceState.STATE_IN_SERVICE);
+    }
+
+    @Test
+    public void testUpdateEmergencyCountryIso_whenStateOos() throws Exception {
+        testUpdateEmergencyCountryIso(ServiceState.STATE_OUT_OF_SERVICE);
+    }
+
+    @Test
+    public void testUpdateEmergencyCountryIso_whenStateEmergencyOnly() throws Exception {
+        testUpdateEmergencyCountryIso(ServiceState.STATE_EMERGENCY_ONLY);
+    }
+
+    private void testUpdateEmergencyCountryIso(int ss) throws Exception {
+        doReturn(mLocaleTracker).when(mSST).getLocaleTracker();
+        doReturn("us").when(mLocaleTracker).getLastKnownCountryIso();
+
         sendEmergencyNumberPrefix(mEmergencyNumberTrackerMock);
 
         mEmergencyNumberTrackerMock.updateEmergencyNumberDatabaseCountryChange("us");
@@ -338,10 +402,14 @@
         assertTrue(mEmergencyNumberTrackerMock.getEmergencyCountryIso().equals("us"));
         assertTrue(mEmergencyNumberTrackerMock.getLastKnownEmergencyCountryIso().equals("us"));
 
+        doReturn(ss).when(mServiceState).getState();
         mEmergencyNumberTrackerMock.updateEmergencyNumberDatabaseCountryChange("");
         processAllMessages();
         assertTrue(mEmergencyNumberTrackerMock.getEmergencyCountryIso().equals(""));
         assertTrue(mEmergencyNumberTrackerMock.getLastKnownEmergencyCountryIso().equals("us"));
+
+        //make sure we look up cached location whenever current iso is null
+        verify(mLocaleTracker).getLastKnownCountryIso();
     }
 
     @Test
@@ -367,18 +435,11 @@
 
     @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));
+        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubscriptionManagerService).getSlotIndex(
+                anyInt());
         assertTrue(mEmergencyNumberTrackerMock.isSimAbsent());
 
         sendEmptyEmergencyNumberListFromRadio(mEmergencyNumberTrackerMock);
@@ -388,7 +449,7 @@
         processAllMessages();
 
         replaceInstance(ShortNumberInfo.class, "INSTANCE", null, mShortNumberInfo);
-        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, true);
+        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER);
 
         //verify that we fall back to shortnumber xml when there are no SIMs
         verify(mShortNumberInfo).isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, "JP");
@@ -405,26 +466,21 @@
     }
 
     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));
+            doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
+                    eq(SUB_ID_PHONE_1));
+            doReturn(INVALID_SLOT_INDEX_VALID).when(mSubscriptionManagerService).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));
+            doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
+                    eq(SUB_ID_PHONE_1));
+            doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubscriptionManagerService).getSlotIndex(
+                    eq(SUB_ID_PHONE_2));
         }
         assertFalse(mEmergencyNumberTrackerMock.isSimAbsent());
 
@@ -436,7 +492,7 @@
         processAllMessages();
 
         replaceInstance(ShortNumberInfo.class, "INSTANCE", null, mShortNumberInfo);
-        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, true);
+        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER);
 
         //verify we do not use ShortNumber xml
         verify(mShortNumberInfo, never()).isEmergencyNumber(anyString(), anyString());
@@ -476,38 +532,236 @@
     }
 
     /**
-     * In 1.3 or less HAL. we should not use database number.
-     */
-    @Test
-    public void testUsingEmergencyNumberDatabaseWheneverHal_1_3() {
-        doReturn(new HalVersion(1, 3)).when(mPhone).getHalVersion();
-
-        sendEmergencyNumberPrefix(mEmergencyNumberTrackerMock);
-        mEmergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("us");
-        processAllMessages();
-
-        boolean hasDatabaseNumber = false;
-        for (EmergencyNumber number : mEmergencyNumberTrackerMock.getEmergencyNumberList()) {
-            if (number.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE)) {
-                hasDatabaseNumber = true;
-                break;
-            }
-        }
-        assertFalse(hasDatabaseNumber);
-    }
-
-    /**
      * In 1.4 or above HAL, we should use database number.
      */
     @Test
     public void testUsingEmergencyNumberDatabaseWheneverHal_1_4() {
-        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
+        doReturn(mMockContext).when(mPhone).getContext();
+        doReturn(mContext.getAssets()).when(mMockContext).getAssets();
+        doReturn(mResources).when(mMockContext).getResources();
+        doReturn(true).when(mResources).getBoolean(
+                com.android.internal.R.bool.ignore_emergency_number_routing_from_db);
 
-        sendEmergencyNumberPrefix(mEmergencyNumberTrackerMock);
-        mEmergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("us");
+        EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker(
+                mPhone, mSimulatedCommands);
+        emergencyNumberTrackerMock.sendMessage(
+                emergencyNumberTrackerMock.obtainMessage(
+                        1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */,
+                        new AsyncResult(null, mEmergencyNumberListTestSample, null)));
+        sendEmergencyNumberPrefix(emergencyNumberTrackerMock);
+        emergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("us");
         processAllMessages();
+        /* case 1: check DB number exist or not */
         assertTrue(hasDbEmergencyNumber(CONFIG_EMERGENCY_NUMBER,
-                mEmergencyNumberTrackerMock.getEmergencyNumberList()));
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        /* case 2: since ignore_emergency_routing_from_db is true. check for all DB numbers with
+        routing value as unknown by ignoring DB value */
+        List<EmergencyNumber> completeEmergencyNumberList = new ArrayList<>();
+        EmergencyNumber emergencyNumber = new EmergencyNumber(
+                "888", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        completeEmergencyNumberList.add(emergencyNumber);
+
+        emergencyNumber = new EmergencyNumber(
+                "54321", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        completeEmergencyNumberList.add(emergencyNumber);
+
+        emergencyNumber = new EmergencyNumber(
+                "654321", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        completeEmergencyNumberList.add(emergencyNumber);
+
+        emergencyNumber = new EmergencyNumber(
+                "7654321", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        completeEmergencyNumberList.add(emergencyNumber);
+
+        assertTrue(hasDbEmergencyNumbers(completeEmergencyNumberList,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        /* case 3: check the routing type of merged duplicate numbers
+            between DB number and radio list. */
+        EmergencyNumber duplicateEmergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_DUPLICATE_NUMBER, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        assertTrue(hasDbEmergencyNumber(duplicateEmergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+    }
+
+    @Test
+    public void testUsingEmergencyNumberDatabaseWithRouting() {
+        doReturn(mMockContext).when(mPhone).getContext();
+        doReturn(mContext.getAssets()).when(mMockContext).getAssets();
+        doReturn(mResources).when(mMockContext).getResources();
+        doReturn("05").when(mCellIdentity).getMncString();
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.ignore_emergency_number_routing_from_db);
+
+        EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker(
+                mPhone, mSimulatedCommands);
+        emergencyNumberTrackerMock.sendMessage(
+                emergencyNumberTrackerMock.obtainMessage(
+                        1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */,
+                        new AsyncResult(null, mEmergencyNumberListTestSample, null)));
+        sendEmergencyNumberPrefix(emergencyNumberTrackerMock);
+        emergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("us");
+        processAllMessages();
+
+        // case 1: check DB number with normal routing true and for mnc 05
+        EmergencyNumber emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "05", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        // case 2: check DB number with normal routing true in multiple mnc 05, 45, 47
+        emergencyNumber = new EmergencyNumber(
+                "888", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "05", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        doReturn("47").when(mCellIdentity).getMncString();
+        emergencyNumber = new EmergencyNumber(
+                "888", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "47", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                        CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                            EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        /* case 3: check DB number with normal routing false and for mnc 05,
+            but current cell identity is 04 */
+        doReturn("04").when(mCellIdentity).getMncString();
+        emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        // case 4: check DB number with normal routing false
+        emergencyNumber = new EmergencyNumber(
+                "654321", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        // case 5: check DB number with normal routing true & empty mnc
+        emergencyNumber = new EmergencyNumber(
+                "7654321", CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        /* case 6: check DB number with normal routing true & empty mnc. But same number exist
+            in radio list. In merge DB routing should be used */
+        emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_DUPLICATE_NUMBER, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE
+                | EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+    }
+
+    @Test
+    public void testUsingEmergencyNumberDatabaseWithRoutingInOOS() {
+        doReturn(mMockContext).when(mPhone).getContext();
+        doReturn(mContext.getAssets()).when(mMockContext).getAssets();
+        doReturn(mResources).when(mMockContext).getResources();
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.ignore_emergency_number_routing_from_db);
+
+        EmergencyNumberTracker emergencyNumberTrackerMock = new EmergencyNumberTracker(
+                mPhone, mSimulatedCommands);
+        emergencyNumberTrackerMock.sendMessage(
+                emergencyNumberTrackerMock.obtainMessage(
+                        1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */,
+                        new AsyncResult(null, mEmergencyNumberListTestSample, null)));
+        sendEmergencyNumberPrefix(emergencyNumberTrackerMock);
+        emergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("us");
+        processAllMessages();
+
+        // Check routing when cellidentity is null, which is oos
+        doReturn(null).when(mPhone).getCurrentCellIdentity();
+        EmergencyNumber emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        // Check routing when cellidentity is 04, which is not part of normal routing mncs
+        doReturn(mCellIdentity).when(mPhone).getCurrentCellIdentity();
+        doReturn("04").when(mCellIdentity).getMncString();
+        emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
+
+        // Check routing when cellidentity is 05, which is part of normal routing mncs
+        doReturn("05").when(mCellIdentity).getMncString();
+        emergencyNumber = new EmergencyNumber(
+                CONFIG_EMERGENCY_NUMBER_ADDRESS, CONFIG_EMERGENCY_NUMBER_COUNTRY,
+                    "05", CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES,
+                            CONFIG_EMERGENCY_NUMBER_SERVICE_URNS,
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                                            EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        assertTrue(hasDbEmergencyNumber(emergencyNumber,
+                emergencyNumberTrackerMock.getEmergencyNumberList()));
     }
 
     /**
@@ -515,9 +769,6 @@
      */
     @Test
     public void testOtaEmergencyNumberDatabase() {
-        // Set up the Hal version as 1.4 to apply emergency number database
-        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
-
         sendEmergencyNumberPrefix(mEmergencyNumberTrackerMock);
         mEmergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("");
         processAllMessages();
@@ -578,4 +829,42 @@
 
         assertEquals(resultToVerify, resultFromRadio);
     }
+
+    @Test
+    public void testOverridingEmergencyNumberPrefixCarrierConfig() throws Exception {
+        // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+        doReturn(mMockContext).when(mPhone).getContext();
+        doReturn(Context.CARRIER_CONFIG_SERVICE)
+                .when(mMockContext)
+                .getSystemService(CarrierConfigManager.class);
+        doReturn(mCarrierConfigManagerMock)
+                .when(mMockContext)
+                .getSystemService(eq(Context.CARRIER_CONFIG_SERVICE));
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+        EmergencyNumberTracker localEmergencyNumberTracker =
+                new EmergencyNumberTracker(mPhone, mSimulatedCommands);
+        verify(mCarrierConfigManagerMock)
+                .registerCarrierConfigChangeListener(any(), listenerArgumentCaptor.capture());
+        CarrierConfigManager.CarrierConfigChangeListener carrierConfigChangeListener =
+                listenerArgumentCaptor.getAllValues().get(0);
+
+        assertFalse(localEmergencyNumberTracker.isEmergencyNumber("*272911"));
+
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putStringArray(
+                CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY,
+                new String[] {"*272"});
+        doReturn(bundle)
+                .when(mCarrierConfigManagerMock)
+                .getConfigForSubId(eq(SUB_ID_PHONE_1), any());
+        carrierConfigChangeListener.onCarrierConfigChanged(
+                mPhone.getPhoneId(),
+                mPhone.getSubId(),
+                TelephonyManager.UNKNOWN_CARRIER_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID);
+        processAllMessages();
+
+        assertTrue(localEmergencyNumberTracker.isEmergencyNumber("*272911"));
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
new file mode 100644
index 0000000..2a8e4e2
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -0,0 +1,1615 @@
+/*
+ * 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.emergency;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS_PS;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN;
+import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.DisconnectCause;
+import android.telephony.EmergencyRegResult;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.data.PhoneSwitcher;
+
+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;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+
+/**
+ * Unit tests for EmergencyStateTracker
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class EmergencyStateTrackerTest extends TelephonyTest {
+    private static final String TEST_CALL_ID = "TC@TEST1";
+    private static final String TEST_CALL_ID_2 = "TC@TEST2";
+    private static final String TEST_SMS_ID = "1111";
+    private static final String TEST_SMS_ID_2 = "2222";
+    private static final long TEST_ECM_EXIT_TIMEOUT_MS = 500;
+    private static final EmergencyRegResult E_REG_RESULT = new EmergencyRegResult(
+            EUTRAN, REGISTRATION_STATE_HOME, DOMAIN_CS_PS, true, true, 0, 1, "001", "01", "US");
+
+    @Mock EmergencyStateTracker.PhoneFactoryProxy mPhoneFactoryProxy;
+    @Mock EmergencyStateTracker.PhoneSwitcherProxy mPhoneSwitcherProxy;
+    @Mock EmergencyStateTracker.TelephonyManagerProxy mTelephonyManagerProxy;
+    @Mock PhoneSwitcher mPhoneSwitcher;
+    @Mock RadioOnHelper mRadioOnHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void getInstance_notInitializedTillMake() throws IllegalStateException {
+        assertThrows(IllegalStateException.class, () -> {
+            EmergencyStateTracker.getInstance();
+        });
+
+        EmergencyStateTracker.make(mContext, true);
+
+        assertNotNull(EmergencyStateTracker.getInstance());
+    }
+
+    @Test
+    @SmallTest
+    public void getInstance_returnsSameInstance() {
+        EmergencyStateTracker.make(mContext, true);
+        EmergencyStateTracker instance1 = EmergencyStateTracker.getInstance();
+        EmergencyStateTracker instance2 = EmergencyStateTracker.getInstance();
+
+        assertSame(instance1, instance2);
+    }
+
+    /**
+     * Test that the EmergencyStateTracker turns on radio, performs a DDS switch and sets emergency
+     * mode switch when we are not roaming and the carrier only supports SUPL over the data plane.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_radioOff_turnOnRadioSwitchDdsAndSetEmergencyMode() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones and set radio off
+        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
+                false /* isRadioOn */);
+        setConfigForDdsSwitch(testPhone, null,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY, "150");
+        // Spy is used to capture consumer in delayDialForDdsSwitch
+        EmergencyStateTracker spyEst = spy(emergencyStateTracker);
+        CompletableFuture<Integer> unused = spyEst.startEmergencyCall(testPhone, TEST_CALL_ID,
+                false);
+
+        // startEmergencyCall should trigger radio on
+        ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor
+                .forClass(RadioOnStateListener.Callback.class);
+        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone),
+                eq(false), eq(0));
+        // isOkToCall() should return true once radio is on
+        assertFalse(callback.getValue()
+                .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
+        when(mSST.isRadioOn()).thenReturn(true);
+        assertTrue(callback.getValue()
+                .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false));
+        // Once radio on is complete, trigger delay dial
+        callback.getValue().onComplete(null, true);
+        ArgumentCaptor<Consumer<Boolean>> completeConsumer = ArgumentCaptor
+                .forClass(Consumer.class);
+        verify(spyEst).switchDdsDelayed(eq(testPhone), completeConsumer.capture());
+        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(testPhone.getPhoneId()),
+                eq(150) /* extensionTime */, any());
+        // After dds switch completes successfully, set emergency mode
+        completeConsumer.getValue().accept(true);
+        verify(testPhone).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any());
+    }
+
+    /**
+     * Test that if startEmergencyCall fails to turn on radio, then it's future completes with
+     * DisconnectCause.POWER_OFF.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_radioOnFails_returnsDisconnectCausePowerOff() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones and set radio off
+        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
+                false /* isRadioOn */);
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // startEmergencyCall should trigger radio on
+        ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor
+                .forClass(RadioOnStateListener.Callback.class);
+        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone),
+                eq(false), eq(0));
+        // Verify future completes with DisconnectCause.POWER_OFF if radio not ready
+        CompletableFuture<Void> unused = future.thenAccept((result) -> {
+            assertEquals((Integer) result, (Integer) DisconnectCause.POWER_OFF);
+        });
+        callback.getValue().onComplete(null, false /* isRadioReady */);
+    }
+
+    /**
+     * Test that the EmergencyStateTracker does not perform a DDS switch when the carrier supports
+     * control-plane fallback. Radio is set to on so RadioOnHelper not triggered.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_cpFallback_noDdsSwitch() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones and set radio on
+        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
+                true /* isRadioOn */);
+        setConfigForDdsSwitch(testPhone, null,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK, "0");
+
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Radio already on so shouldn't trigger this
+        verify(mRadioOnHelper, never()).triggerRadioOnAndListen(any(), anyBoolean(), any(),
+                anyBoolean(), eq(0));
+        // Carrier supports control-plane fallback, so no DDS switch
+        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+    }
+
+    /**
+     * Test that the EmergencyStateTracker does not perform a DDS switch if the non-DDS supports
+     * SUPL.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_supportsSuplOnNonDds_noDdsSwitch() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                false /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
+                true /* isRadioOn */);
+        setConfigForDdsSwitch(testPhone, null,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY, "0");
+
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // non-DDS supports SUPL, so no DDS switch
+        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+    }
+
+    /**
+     * Test that the EmergencyStateTracker does not perform a DDS switch when the carrier does not
+     * support control-plane fallback while roaming.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_roaming_noDdsSwitch() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(true /* isRoaming */,
+                true /* isRadioOn */);
+        setConfigForDdsSwitch(testPhone, null,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY, "0");
+
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Is roaming, so no DDS switch
+        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
+    }
+
+    /**
+     * Test that the EmergencyStateTracker does perform a DDS switch even though the carrier
+     * supports control-plane fallback and the roaming partner is configured to look like a home
+     * network.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_roamingCarrierConfig_switchDds() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
+                true /* isRadioOn */);
+        // Setup voice roaming scenario
+        String testRoamingOperator = "001001";
+        testPhone.getServiceState().setOperatorName("TestTel", "TestTel", testRoamingOperator);
+        String[] roamingPlmns = new String[] { testRoamingOperator };
+        setConfigForDdsSwitch(testPhone, roamingPlmns,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK, "0");
+
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Verify DDS switch
+        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /* phoneId */,
+                eq(0) /* extensionTime */, any());
+    }
+
+    /**
+     * Test that the EmergencyStateTracker does perform a DDS switch even though the carrier
+     * supports control-plane fallback if we are roaming and the roaming partner is configured to
+     * use data plane only SUPL.
+     */
+    @Test
+    @SmallTest
+    public void startEmergencyCall_roamingCarrierConfigWhileRoaming_switchDds() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(true /* isRoaming */,
+                true /* isRadioOn */);
+        // Setup voice roaming scenario
+        String testRoamingOperator = "001001";
+        testPhone.getServiceState().setOperatorName("TestTel", "TestTel", testRoamingOperator);
+        String[] roamingPlmns = new String[] { testRoamingOperator };
+        setConfigForDdsSwitch(testPhone, roamingPlmns,
+                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK, "0");
+
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Verify DDS switch
+        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /* phoneId */,
+                eq(0) /* extensionTime */, any());
+    }
+
+    /**
+     * Test that once EmergencyStateTracker handler receives set emergency mode done message it sets
+     * IsInEmergencyCall to true, sets LastEmergencyRegResult and completes future with
+     * DisconnectCause.NOT_DISCONNECTED.
+     */
+    @Test
+    @SmallTest
+    public void setEmergencyModeDone_notifiesListenersAndCompletesFuture() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(true /* isRoaming */,
+                true /* isRadioOn */);
+        setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT);
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        // Verify future completes with DisconnectCause.NOT_DISCONNECTED
+        CompletableFuture<Void> unused = future.thenAccept((result) -> {
+            assertEquals((Integer) result, (Integer) DisconnectCause.NOT_DISCONNECTED);
+        });
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        assertTrue(emergencyStateTracker.getEmergencyRegResult().equals(E_REG_RESULT));
+        verify(testPhone).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+    }
+
+    /**
+     * Test that once EmergencyStateTracker handler receives message to exit emergency mode, it sets
+     * IsInEmergencyCall to false.
+     */
+    @Test
+    @SmallTest
+    public void exitEmergencyModeDone_isInEmergencyCallFalse() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                true /* isSuplDdsSwitchRequiredForEmergencyCall */);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(true /* isRoaming */,
+                true /* isRadioOn */);
+        setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(testPhone);
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(testPhone).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(testPhone).exitEmergencyMode(any(Message.class));
+    }
+
+    /**
+     * Test that onEmergencyCallDomainUpdated updates the domain correctly so ECBM PS domain is
+     * detected.
+     */
+    @Test
+    @SmallTest
+    public void onEmergencyCallDomainUpdated_PsDomain() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        // set domain
+        emergencyStateTracker.onEmergencyCallDomainUpdated(PhoneConstants.PHONE_TYPE_IMS,
+                TEST_CALL_ID);
+        // End call to enter ECM
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        // Make sure CS ECBM is true
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInCdmaEcm());
+        assertTrue(emergencyStateTracker.isInImsEcm());
+    }
+
+    /**
+     * Test that onEmergencyCallDomainUpdated updates the domain correctly so ECBM CS domain is
+     * detected.
+     */
+    @Test
+    @SmallTest
+    public void onEmergencyCallDomainUpdated_CsDomain() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        // set domain
+        emergencyStateTracker.onEmergencyCallDomainUpdated(PhoneConstants.PHONE_TYPE_CDMA,
+                TEST_CALL_ID);
+        // End call to enter ECM
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        // Make sure IMS ECBM is true
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertTrue(emergencyStateTracker.isInCdmaEcm());
+        assertFalse(emergencyStateTracker.isInImsEcm());
+    }
+
+    /**
+     * Ensure that if for some reason we enter ECBM for CS domain and the Phone type is GSM,
+     * isInCdmaEcm returns false.
+     */
+    @Test
+    @SmallTest
+    public void onEmergencyCallDomainUpdated_CsDomain_Gsm() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // For some reason the Phone is reporting GSM instead of CDMA.
+        doReturn(PhoneConstants.PHONE_TYPE_GSM).when(testPhone).getPhoneType();
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        // set domain
+        emergencyStateTracker.onEmergencyCallDomainUpdated(PhoneConstants.PHONE_TYPE_CDMA,
+                TEST_CALL_ID);
+        // End call to enter ECM
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInCdmaEcm());
+        assertFalse(emergencyStateTracker.isInImsEcm());
+    }
+
+    /**
+     * Test that onEmergencyTransportChanged sets the new emergency mode.
+     */
+    @Test
+    @SmallTest
+    public void onEmergencyTransportChanged_setEmergencyMode() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phones
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true );
+        // Call startEmergencyCall() to set testPhone
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+
+        emergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_CALL, MODE_EMERGENCY_WWAN);
+
+        verify(testPhone).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any());
+    }
+
+    /**
+     * Test that after endCall() is called, EmergencyStateTracker will enter ECM if the call was
+     * ACTIVE and send related intents.
+     */
+    @Test
+    @SmallTest
+    public void endCall_callWasActive_enterEcm() {
+        // Setup EmergencyStateTracker
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // Start emergency call then enter ECM
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        // Set ecm as supported
+        setEcmSupportedConfig(testPhone, true);
+
+        assertFalse(emergencyStateTracker.isInEcm());
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEcm());
+        // Verify intents are sent that ECM is entered
+        ArgumentCaptor<Intent> ecmStateIntent = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).sendStickyBroadcastAsUser(ecmStateIntent.capture(), eq(UserHandle.ALL));
+        assertTrue(ecmStateIntent.getValue()
+                .getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, true));
+        // Verify emergency callback mode set on modem
+        verify(testPhone).setEmergencyMode(eq(MODE_EMERGENCY_CALLBACK), any());
+    }
+
+    /**
+     * Test that after endCall() is called, EmergencyStateTracker will not enter ECM if the call was
+     * not ACTIVE.
+     */
+    @Test
+    @SmallTest
+    public void endCall_callNotActive_noEcm() {
+        // Setup EmergencyStateTracker
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // Start emergency call then enter ECM
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        // Call does not reach ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.IDLE, TEST_CALL_ID);
+        // Set ecm as supported
+        setEcmSupportedConfig(testPhone, /* ecmSupported= */ true);
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertFalse(emergencyStateTracker.isInEcm());
+    }
+
+    /**
+     * Test that once endCall() is called and we enter ECM, then we exit ECM after the specified
+     * timeout.
+     */
+    @Test
+    @SmallTest
+    public void endCall_entersEcm_thenExitsEcmAfterTimeout() {
+        // Setup EmergencyStateTracker
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(testPhone);
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        // Set ecm as supported
+        setEcmSupportedConfig(testPhone, /* ecmSupported= */ true);
+
+        processAllMessages();
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEcm());
+
+        processAllFutureMessages();
+
+        // Verify exitEmergencyMode() is called after timeout
+        verify(testPhone).exitEmergencyMode(any(Message.class));
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+    }
+
+    /**
+     * Test that after exitEmergencyCallbackMode() is called, the correct intents are sent and
+     * emergency mode is exited on the modem.
+     */
+    @Test
+    @SmallTest
+    public void exitEmergencyCallbackMode_sendsCorrectIntentsAndExitsEmergencyMode() {
+        // Setup EmergencyStateTracker
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        // Create test Phone
+        Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(testPhone);
+        // Start emergency call then enter ECM
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+                TEST_CALL_ID, false);
+        processAllMessages();
+        // Set call to ACTIVE
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        emergencyStateTracker.onEmergencyCallDomainUpdated(
+                PhoneConstants.PHONE_TYPE_IMS, TEST_CALL_ID);
+        // Set ecm as supported
+        setEcmSupportedConfig(testPhone, /* ecmSupported= */ true);
+        // End call to enter ECM
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        // verify ecbm states are correct
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertTrue(emergencyStateTracker.isInImsEcm());
+        assertFalse(emergencyStateTracker.isInCdmaEcm());
+
+        emergencyStateTracker.exitEmergencyCallbackMode();
+        processAllFutureMessages();
+
+        // Ensure ECBM states are all correctly false after we exit.
+        assertFalse(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInImsEcm());
+        assertFalse(emergencyStateTracker.isInCdmaEcm());
+        // Intents sent for ECM: one for entering ECM and another for exiting
+        ArgumentCaptor<Intent> ecmStateIntent = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext, times(2))
+                .sendStickyBroadcastAsUser(ecmStateIntent.capture(), eq(UserHandle.ALL));
+        List<Intent> capturedIntents = ecmStateIntent.getAllValues();
+        assertTrue(capturedIntents.get(0)
+                .getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
+        assertFalse(capturedIntents.get(1)
+                .getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
+        // Verify exitEmergencyMode() is called only once
+        verify(testPhone).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnEmergencyTransportChangedUsingDifferentThread() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(() -> {
+            emergencyStateTracker.onEmergencyTransportChanged(
+                    EmergencyStateTracker.EMERGENCY_TYPE_CALL, MODE_EMERGENCY_WWAN);
+        });
+        processAllMessages();
+
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallWithTestEmergencyNumber() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, true);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+        verify(phone0, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallDuringActiveCall() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        // First active call
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Second starting call
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID_2, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallInEcm() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setEcmSupportedConfig(phone0, true);
+
+        // First active call
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEcm());
+
+        // Second emergency call started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID_2, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallUsingDifferenPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+
+        // First emergency call
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        // Second emergency call
+        Phone phone1 = getPhone(1);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(phone1,
+                TEST_CALL_ID_2, false);
+
+        // Returns DisconnectCause#ERROR_UNSPECIFIED immediately.
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.ERROR_UNSPECIFIED));
+    }
+
+    @Test
+    @SmallTest
+    public void testEndCallInEcm() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setEcmSupportedConfig(phone0, true);
+
+        // First active call
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        // Second emergency call started.
+        future = emergencyStateTracker.startEmergencyCall(phone0, TEST_CALL_ID_2, false);
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_CALL, MODE_EMERGENCY_WLAN);
+        emergencyStateTracker.endCall(TEST_CALL_ID_2);
+        processAllMessages();
+
+        // At this time, ECM is still running so still in ECM.
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WLAN), any(Message.class));
+        verify(phone0, times(2)).setEmergencyMode(eq(MODE_EMERGENCY_CALLBACK), any(Message.class));
+        verify(phone0, never()).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySms() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        assertTrue(emergencyStateTracker.getEmergencyRegResult().equals(E_REG_RESULT));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testEndSms() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        assertTrue(emergencyStateTracker.getEmergencyRegResult().equals(E_REG_RESULT));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+
+        verify(phone0).exitEmergencyMode(any(Message.class));
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsWithTransportChange() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_SMS, MODE_EMERGENCY_WLAN);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.getEmergencyRegResult().equals(E_REG_RESULT));
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WLAN), any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsWithTestEmergencyNumber() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, true);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+        verify(phone0, never()).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsWhileSmsBeingSent() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID_2, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsWhileEmergencyModeBeingSet() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID_2, false);
+
+        // Returns DisconnectCause#ERROR_UNSPECIFIED immediately.
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.ERROR_UNSPECIFIED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsWhileEcmInProgress() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setEcmSupportedConfig(phone0, true);
+        // Emergency call is ended and the emergency callback is entered.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        assertFalse(future.isDone());
+
+        // Completes the emergency mode setting - MODE_EMERGENCY_CALLBACK
+        processAllMessages();
+
+        verify(phone0, times(2)).setEmergencyMode(anyInt(), any(Message.class));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsUsingDifferentPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ false,
+                /* isRadioOn= */ true);
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+
+        Phone phone1 = getPhone(1);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone1,
+                TEST_SMS_ID_2, false);
+
+        // Returns DisconnectCause#ERROR_UNSPECIFIED immediately.
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.ERROR_UNSPECIFIED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallActiveAndSmsOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallInProgressAndSmsOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        // Emergency call is in progress.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), msgCaptor.capture());
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        assertFalse(future.isDone());
+
+        Message msg = msgCaptor.getValue();
+        AsyncResult.forMessage(msg, E_REG_RESULT, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsActiveAndCallOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        // Emergency SMS is in active.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        // Emergency call is being started.
+        future = emergencyStateTracker.startEmergencyCall(phone0, TEST_CALL_ID, false);
+        processAllMessages();
+
+        verify(phone0).exitEmergencyMode(any(Message.class));
+        verify(phone0, times(2)).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsInProgressAndCallOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        // Emergency SMS is in progress.
+        CompletableFuture<Integer> smsFuture = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        ArgumentCaptor<Message> smsCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), smsCaptor.capture());
+
+        // Emergency call is being started.
+        CompletableFuture<Integer> callFuture = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+
+        assertFalse(smsFuture.isDone());
+        assertFalse(callFuture.isDone());
+
+        // Response message for setEmergencyMode by SMS.
+        Message msg = smsCaptor.getValue();
+        AsyncResult.forMessage(msg, E_REG_RESULT, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Exit emergency mode and set the emergency mode again by the call when the exit result
+        // is received for obtaining the latest EmergencyRegResult.
+        verify(phone0).exitEmergencyMode(any(Message.class));
+        ArgumentCaptor<Message> callCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(phone0, times(2)).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), callCaptor.capture());
+
+        // Response message for setEmergencyMode by call.
+        msg = callCaptor.getAllValues().get(1);
+        AsyncResult.forMessage(msg, E_REG_RESULT, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Expect: DisconnectCause#NOT_DISCONNECTED
+        assertEquals(smsFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(callFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencyCallAndSmsOnDifferentPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started using the different phone.
+        Phone phone1 = getPhone(1);
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone1,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#ERROR_UNSPECIFIED immediately.
+        assertEquals(future.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.ERROR_UNSPECIFIED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsActiveAndCallOnDifferentPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        // Emergency SMS is in active.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        // Emergency call is being started using the different phone.
+        Phone phone1 = getPhone(1);
+        setUpAsyncResultForSetEmergencyMode(phone1, E_REG_RESULT);
+        future = emergencyStateTracker.startEmergencyCall(phone1, TEST_CALL_ID, false);
+        processAllMessages();
+
+        verify(phone0).exitEmergencyMode(any(Message.class));
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+        verify(phone1).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartEmergencySmsInProgressAndCallOnDifferentPhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        // Emergency SMS is in progress.
+        CompletableFuture<Integer> smsFuture = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        ArgumentCaptor<Message> smsCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), smsCaptor.capture());
+
+        // Emergency call is being started using the different phone.
+        Phone phone1 = getPhone(1);
+        CompletableFuture<Integer> callFuture = emergencyStateTracker.startEmergencyCall(phone1,
+                TEST_CALL_ID, false);
+
+        assertFalse(smsFuture.isDone());
+        assertFalse(callFuture.isDone());
+
+        // Response message for setEmergencyMode by SMS.
+        Message msg = smsCaptor.getValue();
+        AsyncResult.forMessage(msg, E_REG_RESULT, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Exit emergency mode and set the emergency mode again by the call when the exit result
+        // is received for obtaining the latest EmergencyRegResult.
+        verify(phone0).exitEmergencyMode(any(Message.class));
+        ArgumentCaptor<Message> callCaptor = ArgumentCaptor.forClass(Message.class);
+        verify(phone1).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), callCaptor.capture());
+
+        // Response message for setEmergencyMode by call.
+        msg = callCaptor.getValue();
+        AsyncResult.forMessage(msg, E_REG_RESULT, null);
+        msg.sendToTarget();
+        processAllMessages();
+
+        // Expect: DisconnectCause#OUTGOING_EMERGENCY_CALL_PLACED
+        assertEquals(smsFuture.getNow(DisconnectCause.NOT_DISCONNECTED),
+                Integer.valueOf(DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED));
+        // Expect: DisconnectCause#NOT_DISCONNECTED.
+        assertEquals(callFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+    }
+
+    @Test
+    @SmallTest
+    public void testExitEmergencyModeCallAndSmsOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        setEcmSupportedConfig(phone0, false);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+        processAllMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testExitEmergencyModeSmsAndCallOnSamePhone() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        setEcmSupportedConfig(phone0, false);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testExitEmergencyModeCallAndSmsOnSamePhoneWhenEcmSupported() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        setEcmSupportedConfig(phone0, true);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+        processAllMessages();
+
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_CALLBACK), any(Message.class));
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        // ECM timeout.
+        processAllFutureMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testExitEmergencyModeCallAndSmsOnSamePhoneWhenEcmSupportedAndModeChanged() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        setEcmSupportedConfig(phone0, true);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        emergencyStateTracker.onEmergencyTransportChanged(
+                EmergencyStateTracker.EMERGENCY_TYPE_SMS, MODE_EMERGENCY_WWAN);
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+        processAllMessages();
+
+        // Enter emergency callback mode and emergency mode changed by SMS end.
+        verify(phone0, times(2)).setEmergencyMode(eq(MODE_EMERGENCY_CALLBACK), any(Message.class));
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        // ECM timeout.
+        processAllFutureMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).exitEmergencyMode(any(Message.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testExitEmergencyModeSmsAndCallOnSamePhoneWhenEcmSupported() {
+        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+                /* isRadioOn= */ true);
+        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
+        setUpAsyncResultForExitEmergencyMode(phone0);
+        setEcmSupportedConfig(phone0, true);
+        // Emergency call is in active.
+        CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(phone0,
+                TEST_CALL_ID, false);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
+
+        emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+
+        // Emergency SMS is being started.
+        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
+                TEST_SMS_ID, false);
+
+        // Returns DisconnectCause#NOT_DISCONNECTED immediately.
+        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
+                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
+
+        emergencyStateTracker.endSms(TEST_SMS_ID, getTestEmergencyNumber());
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+
+        emergencyStateTracker.endCall(TEST_CALL_ID);
+        processAllMessages();
+
+        assertTrue(emergencyStateTracker.isInEmergencyMode());
+        assertTrue(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+
+        // ECM timeout.
+        processAllFutureMessages();
+
+        assertFalse(emergencyStateTracker.isInEmergencyMode());
+        assertFalse(emergencyStateTracker.isInEcm());
+        assertFalse(emergencyStateTracker.isInEmergencyCall());
+        verify(phone0).exitEmergencyMode(any(Message.class));
+    }
+
+    private EmergencyStateTracker setupEmergencyStateTracker(
+            boolean isSuplDdsSwitchRequiredForEmergencyCall) {
+        doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher();
+        doNothing().when(mPhoneSwitcher).overrideDefaultDataForEmergency(
+                anyInt(), anyInt(), any());
+        return new EmergencyStateTracker(mContext, mTestableLooper.getLooper(),
+                isSuplDdsSwitchRequiredForEmergencyCall, mPhoneFactoryProxy, mPhoneSwitcherProxy,
+                mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS);
+    }
+
+    private Phone setupTestPhoneForEmergencyCall(boolean isRoaming, boolean isRadioOn) {
+        Phone testPhone0 = makeTestPhone(0 /* phoneId */, ServiceState.STATE_IN_SERVICE,
+                false /* isEmergencyOnly */);
+        Phone testPhone1 = makeTestPhone(1 /* phoneId */, ServiceState.STATE_OUT_OF_SERVICE,
+                false /* isEmergencyOnly */);
+        List<Phone> phones = new ArrayList<>(2);
+        phones.add(testPhone0);
+        phones.add(testPhone1);
+        doReturn(isRadioOn).when(testPhone0).isRadioOn();
+        doReturn(isRadioOn).when(testPhone1).isRadioOn();
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
+        doReturn(2).when(mTelephonyManagerProxy).getPhoneCount();
+        when(mPhoneFactoryProxy.getPhones()).thenReturn(phones.toArray(new Phone[phones.size()]));
+        testPhone0.getServiceState().setRoaming(isRoaming);
+        return testPhone0;
+    }
+
+    private Phone getPhone(int phoneId) {
+        Phone[] phones = mPhoneFactoryProxy.getPhones();
+        return phones[phoneId];
+    }
+
+    private Phone makeTestPhone(int phoneId, int serviceState, boolean isEmergencyOnly) {
+        GsmCdmaPhone phone = mock(GsmCdmaPhone.class);
+        ServiceState testServiceState = new ServiceState();
+        testServiceState.setState(serviceState);
+        testServiceState.setEmergencyOnly(isEmergencyOnly);
+        when(phone.getContext()).thenReturn(mContext);
+        when(phone.getServiceState()).thenReturn(testServiceState);
+        when(phone.getPhoneId()).thenReturn(phoneId);
+        when(phone.getSubId()).thenReturn(0);
+        when(phone.getServiceStateTracker()).thenReturn(mSST);
+        when(phone.getUnitTestMode()).thenReturn(true);
+        // Initialize the phone as a CDMA phone for now for ease of testing ECBM.
+        // Tests can individually override this to GSM if required for the test.
+        doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(phone).getPhoneType();
+        doNothing().when(phone).notifyEmergencyCallRegistrants(anyBoolean());
+        return phone;
+    }
+
+    private void setEcmSupportedConfig(Phone phone, boolean ecmSupported) {
+        CarrierConfigManager cfgManager = (CarrierConfigManager) mContext
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        cfgManager.getConfigForSubId(phone.getSubId()).putBoolean(
+                CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL,
+                ecmSupported);
+    }
+
+    private void setConfigForDdsSwitch(Phone phone, String[] roaminPlmns,
+            int suplEmergencyModeType, String esExtensionSec) {
+        CarrierConfigManager cfgManager = (CarrierConfigManager) mContext
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        cfgManager.getConfigForSubId(phone.getSubId()).putStringArray(
+                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
+                roaminPlmns);
+        cfgManager.getConfigForSubId(phone.getSubId()).putInt(
+                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+                suplEmergencyModeType);
+        cfgManager.getConfigForSubId(phone.getSubId())
+                .putString(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, esExtensionSec);
+    }
+
+    private void setUpAsyncResultForSetEmergencyMode(Phone phone, EmergencyRegResult regResult) {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Message msg = (Message) args[1];
+            AsyncResult.forMessage(msg, regResult, null);
+            msg.sendToTarget();
+            return null;
+        }).when(phone).setEmergencyMode(anyInt(), any(Message.class));
+    }
+
+    private void setUpAsyncResultForExitEmergencyMode(Phone phone) {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Message msg = (Message) args[0];
+            AsyncResult.forMessage(msg, null, null);
+            msg.sendToTarget();
+            return null;
+        }).when(phone).exitEmergencyMode(any(Message.class));
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java
new file mode 100644
index 0000000..2c5a873
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.emergency;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+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.os.AsyncResult;
+import android.os.Handler;
+import android.telephony.ServiceState;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+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;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests the RadioOnStateListener, which listens to one Phone and waits until its service state
+ * changes to accepting emergency calls or in service. If it can not find a tower to camp onto for
+ * emergency calls, then it will fail after a timeout period.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RadioOnStateListenerTest extends TelephonyTest {
+
+    private static final long TIMEOUT_MS = 1000;
+
+    @Mock Phone mMockPhone;
+    @Mock RadioOnStateListener.Callback mCallback;
+    @Mock CommandsInterface mMockCi;
+    RadioOnStateListener mListener;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+        mListener = new RadioOnStateListener();
+        doReturn(mSST).when(mMockPhone).getServiceStateTracker();
+        mMockPhone.mCi = mMockCi;
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mListener.setTimeBetweenRetriesMillis(5000);
+        mListener.setMaxNumRetries(5);
+        mListener.getHandler().removeCallbacksAndMessages(null);
+        // Wait for the queue to clear...
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS /* ms timeout */);
+        mListener = null;
+        super.tearDown();
+    }
+
+    /**
+     * Ensure that we successfully register for the ServiceState changed messages in Telephony.
+     */
+    @Test
+    public void testRegisterForCallback() {
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        verify(mMockPhone).unregisterForServiceStateChanged(any(Handler.class));
+        verify(mSatelliteController).unregisterForSatelliteModemStateChanged(anyInt(), any());
+        verify(mMockPhone).registerForServiceStateChanged(any(Handler.class),
+                eq(RadioOnStateListener.MSG_SERVICE_STATE_CHANGED), isNull());
+        verify(mSatelliteController, never()).registerForSatelliteModemStateChanged(
+                anyInt(), any());
+
+        verify(mMockCi).registerForOffOrNotAvailable(any(Handler.class),
+                eq(RadioOnStateListener.MSG_RADIO_OFF_OR_NOT_AVAILABLE), isNull());
+    }
+
+    /**
+     * Ensure that we successfully register for the satellite modem state changed messages.
+     */
+    @Test
+    public void testRegisterForSatelliteCallback() {
+        doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        verify(mSatelliteController).unregisterForSatelliteModemStateChanged(anyInt(), any());
+        verify(mSatelliteController).registerForSatelliteModemStateChanged(anyInt(), any());
+    }
+
+    /**
+     * {@link RadioOnStateListener.Callback#isOkToCall(Phone, int, boolean)} returns true after
+     * service state changes, so we are expecting
+     * {@link RadioOnStateListener.Callback#onComplete(RadioOnStateListener, boolean)} to
+     * return true.
+     */
+    @Test
+    public void testPhoneChangeState_OkToCallTrue() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_IN_SERVICE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(true);
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        mListener.getHandler().obtainMessage(RadioOnStateListener.MSG_SERVICE_STATE_CHANGED,
+                new AsyncResult(null, state, null)).sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+
+    /**
+     * {@link RadioOnStateListener.Callback#isOkToCall(Phone, int, boolean)} returns true after
+     * satellite modem state changes, so we are expecting
+     * {@link RadioOnStateListener.Callback#onComplete(RadioOnStateListener, boolean)} to
+     * return true.
+     */
+    @Test
+    public void testSatelliteChangeState_OkToCallTrue() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_IN_SERVICE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(true);
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        mListener.getHandler().obtainMessage(RadioOnStateListener.MSG_SATELLITE_ENABLED_CHANGED)
+                .sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+
+    /**
+     * We never receive a
+     * {@link RadioOnStateListener.Callback#onComplete(RadioOnStateListener, boolean)} because
+     * {@link RadioOnStateListener.Callback#isOkToCall(Phone, int, boolean)} returns false.
+     */
+    @Test
+    public void testPhoneChangeState_NoOkToCall_Timeout() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(false);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+
+        mListener.getHandler().obtainMessage(RadioOnStateListener.MSG_SERVICE_STATE_CHANGED,
+                new AsyncResult(null, state, null)).sendToTarget();
+
+        waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
+        verify(mCallback, never()).onComplete(any(RadioOnStateListener.class), anyBoolean());
+    }
+
+    /**
+     * Tests {@link RadioOnStateListener.Callback#isOkToCall(Phone, int, boolean)} returning
+     * false and hitting the max number of retries. This should result in
+     * {@link RadioOnStateListener.Callback#onComplete(RadioOnStateListener, boolean)} returning
+     * false.
+     */
+    @Test
+    public void testTimeout_RetryFailure() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_POWER_OFF);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(false);
+        mListener.setTimeBetweenRetriesMillis(0/* ms */);
+        mListener.setMaxNumRetries(2);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
+        waitForDelayedHandlerAction(mListener.getHandler(), TIMEOUT_MS /* delay */, TIMEOUT_MS);
+
+        verify(mCallback).onComplete(eq(mListener), eq(false));
+        verify(mMockPhone, times(2)).setRadioPower(eq(true), eq(false), eq(false), eq(false));
+        verify(mSatelliteController, never()).requestSatelliteEnabled(
+                anyInt(), eq(false), eq(false), any());
+    }
+
+    @Test
+    public void testTimeout_RetryFailure_ForEmergency() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_POWER_OFF);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(false);
+        mListener.setTimeBetweenRetriesMillis(0/* ms */);
+        mListener.setMaxNumRetries(2);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        mListener.waitForRadioOn(mMockPhone, mCallback, true, true, 0);
+        waitForDelayedHandlerAction(mListener.getHandler(), TIMEOUT_MS /* delay */, TIMEOUT_MS);
+
+        verify(mCallback).onComplete(eq(mListener), eq(false));
+        verify(mMockPhone, times(2)).setRadioPower(eq(true), eq(true), eq(true), eq(false));
+        verify(mSatelliteController, never()).requestSatelliteEnabled(
+                anyInt(), eq(false), eq(false), any());
+    }
+
+    @Test
+    public void testTimeout_RetryFailure_WithSatellite() {
+        doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_POWER_OFF);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean())).thenReturn(false);
+        mListener.setTimeBetweenRetriesMillis(0/* ms */);
+        mListener.setMaxNumRetries(2);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        mListener.waitForRadioOn(mMockPhone, mCallback, true, true, 0);
+        waitForDelayedHandlerAction(mListener.getHandler(), TIMEOUT_MS /* delay */, TIMEOUT_MS);
+
+        verify(mCallback).onComplete(eq(mListener), eq(false));
+        verify(mMockPhone, times(2)).setRadioPower(eq(true), eq(true), eq(true), eq(false));
+        verify(mSatelliteController, times(2)).requestSatelliteEnabled(
+                anyInt(), eq(false), eq(false), any());
+    }
+
+    @Test
+    public void testTimeout_OnTimeoutForEmergency() {
+        ServiceState state = new ServiceState();
+        state.setState(ServiceState.STATE_POWER_OFF);
+        when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
+        when(mMockPhone.getServiceState()).thenReturn(state);
+        when(mCallback.isOkToCall(eq(mMockPhone), anyInt(), anyBoolean()))
+                .thenReturn(false);
+        when(mCallback.onTimeout(eq(mMockPhone), anyInt(), anyBoolean()))
+                .thenReturn(true);
+        mListener.setTimeBetweenRetriesMillis(0 /* ms */);
+        mListener.setMaxNumRetries(1);
+
+        // Wait for the timer to expire and check state manually in onRetryTimeout
+        mListener.waitForRadioOn(mMockPhone, mCallback, true, true, 100);
+        waitForDelayedHandlerAction(mListener.getHandler(), TIMEOUT_MS /* delay */, TIMEOUT_MS);
+
+        verify(mCallback).onTimeout(eq(mMockPhone), anyInt(), anyBoolean());
+        verify(mCallback).onComplete(eq(mListener), eq(true));
+    }
+}
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..d4850c8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
@@ -17,6 +17,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -354,6 +355,29 @@
         assertEquals(mConnector.mAvailableState, mConnector.getCurrentState());
     }
 
+    @Test
+    public void testConnectedState_serviceDisconnected() throws Exception {
+        // Kick off the asynchronous command.
+        prepareEuiccApp(true /* hasPermission */, true /* requiresBindPermission */,
+                true /* hasPriority */);
+        mConnector = new EuiccConnector(mContext, mLooper.getLooper());
+        mConnector.getEid(CARD_ID, new EuiccConnector.GetEidCommandCallback() {
+            @Override public void onGetEidComplete(String eid) {}
+            @Override public void onEuiccServiceUnavailable() {}
+        });
+        mLooper.dispatchAll();
+        assertEquals(mConnector.mConnectedState, mConnector.getCurrentState());
+        // Now, pretend the remote process died.
+        mConnector.onServiceDisconnected(null /* name */);
+        mLooper.dispatchAll();
+        assertEquals(mConnector.mDisconnectedState, mConnector.getCurrentState());
+        // After binder timeout, should now drop back to available state.
+        mLooper.moveTimeForward(EuiccConnector.BIND_TIMEOUT_MILLIS);
+        mLooper.dispatchAll();
+        assertEquals(mConnector.mAvailableState, mConnector.getCurrentState());
+        assertNull(mConnector.getBinder());
+    }
+
     private void prepareEuiccApp(
             boolean hasPermission, boolean requiresBindPermission, boolean hasPriority) {
         when(mPackageManager.checkPermission(
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 85db492..fc8dfbf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -65,6 +65,8 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback;
 import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
@@ -75,7 +77,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
@@ -90,6 +91,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
 public class EuiccControllerTest extends TelephonyTest {
@@ -129,7 +131,7 @@
     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;
+    private static final int REMOVABLE_CARD_ID = 26;
 
     // Mocked classes
     private EuiccConnector mMockConnector;
@@ -320,8 +322,8 @@
                 SUBSCRIPTION, false /* complete */, null /* result */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector).getDownloadableSubscriptionMetadata(anyInt(), any(), anyBoolean(),
-                any());
+        verify(mMockConnector).getDownloadableSubscriptionMetadata(anyInt(), anyInt(), any(),
+                anyBoolean(), anyBoolean(), any());
     }
 
     @Test
@@ -612,7 +614,6 @@
         assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult);
     }
 
-    @Ignore("b/255697307")
     @Test
     @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges_multiSim()
@@ -789,6 +790,70 @@
     }
 
     @Test
+    public void testGetResolvedPortIndexForSubscriptionSwitchWithOutMEP() throws Exception {
+        setUpUiccSlotData();
+        assertEquals(TelephonyManager.DEFAULT_PORT_INDEX,
+                mController.getResolvedPortIndexForSubscriptionSwitch(CARD_ID));
+    }
+
+    @Test
+    public void testGetResolvedPortIndexForSubscriptionSwitchWithMEP() throws Exception {
+        setUpUiccSlotDataWithMEP();
+        when(mUiccSlot.getPortList()).thenReturn(new int[]{0, 1});
+        when(mUiccSlot.isPortActive(TelephonyManager.DEFAULT_PORT_INDEX)).thenReturn(false);
+        when(mUiccSlot.isPortActive(1)).thenReturn(true);
+        when(mTelephonyManager.getActiveModemCount()).thenReturn(2);
+        assertEquals(1, mController.getResolvedPortIndexForSubscriptionSwitch(CARD_ID));
+    }
+
+    @Test
+    public void testGetResolvedPortIndexForSubscriptionSwitchWithUiccSlotNull() throws Exception {
+        assertEquals(TelephonyManager.DEFAULT_PORT_INDEX,
+                mController.getResolvedPortIndexForSubscriptionSwitch(CARD_ID));
+    }
+
+    @Test
+    public void testGetResolvedPortIndexForSubscriptionSwitchWithPsimActiveAndSS()
+            throws Exception {
+        when(mUiccController.getUiccSlot(anyInt())).thenReturn(mUiccSlot);
+        when(mUiccSlot.isRemovable()).thenReturn(true);
+        when(mUiccSlot.isEuicc()).thenReturn(false);
+        when(mUiccSlot.isActive()).thenReturn(true);
+        when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
+        assertEquals(TelephonyManager.DEFAULT_PORT_INDEX,
+                mController.getResolvedPortIndexForSubscriptionSwitch(CARD_ID));
+    }
+
+    @Test
+    public void testGetResolvedPortIndexForSubscriptionSwitchWithPsimInActiveAndSS()
+            throws Exception {
+        setUpUiccSlotDataWithMEP();
+        when(mUiccSlot.getPortList()).thenReturn(new int[]{0});
+        when(mUiccSlot.isPortActive(TelephonyManager.DEFAULT_PORT_INDEX)).thenReturn(true);
+        when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
+        assertEquals(TelephonyManager.DEFAULT_PORT_INDEX,
+                mController.getResolvedPortIndexForSubscriptionSwitch(CARD_ID));
+    }
+
+    @Test
+    public void testgetResolvedPortIndexForDisableSubscriptionForNoActiveSubscription()
+            throws Exception {
+        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
+        assertEquals(-1,
+                mController.getResolvedPortIndexForDisableSubscription(
+                        CARD_ID, PACKAGE_NAME, true));
+    }
+
+    @Test
+    public void testgetResolvedPortIndexForDisableSubscriptionForActiveSubscriptions()
+            throws Exception {
+        setActiveSubscriptionInfoInMEPMode();
+        assertEquals(1,
+                mController.getResolvedPortIndexForDisableSubscription(
+                        CARD_ID, PACKAGE_NAME, false));
+    }
+
+    @Test
     public void testDeleteSubscription_noPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(false /* hasPrivileges */);
@@ -889,7 +954,6 @@
                 anyBoolean(), any(), anyBoolean());
     }
 
-    @Ignore("b/255697307")
     @Test
     @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_emptySubscription_success() throws Exception {
@@ -1230,12 +1294,171 @@
                 SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE));
     }
 
+    @Test
+    @EnableCompatChanges({EuiccManager.INACTIVE_PORT_AVAILABILITY_CHECK})
+    public void testIsSimPortAvailable_invalidCase() {
+        setUiccCardInfos(false, true, true);
+        // assert non euicc card id
+        assertFalse(mController.isSimPortAvailable(REMOVABLE_CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // assert invalid port index
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 5 /* portIndex */, TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    @EnableCompatChanges({EuiccManager.INACTIVE_PORT_AVAILABILITY_CHECK})
+    public void testIsSimPortAvailable_port_active() throws Exception {
+        setUiccCardInfos(false, true, true);
+
+        // port has empty iccid
+        assertTrue(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // Set port is active, has valid iccid(may be boot profile) and UiccProfile is empty
+        setUiccCardInfos(false, true, false);
+        when(mUiccController.getUiccPortForSlot(anyInt(), anyInt())).thenReturn(mUiccPort);
+        when(mUiccPort.getUiccProfile()).thenReturn(mUiccProfile);
+        when(mUiccProfile.isEmptyProfile()).thenReturn(true);
+        assertTrue(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // port is active, valid iccid, not empty profile but Phone object is null
+        when(mUiccPort.getUiccProfile()).thenReturn(mUiccProfile);
+        when(mUiccProfile.isEmptyProfile()).thenReturn(false);
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        // logicalSlotIndex of port#0 is 1, Phone object should be null
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // port is active, valid iccid, not empty profile but no carrier privileges
+        when(mUiccPort.getUiccProfile()).thenReturn(mUiccProfile);
+        when(mUiccProfile.isEmptyProfile()).thenReturn(false);
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone});
+        when(mPhone.getCarrierPrivilegesTracker()).thenReturn(null);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+        when(mPhone.getCarrierPrivilegesTracker()).thenReturn(mCarrierPrivilegesTracker);
+        when(mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForPackage(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // port is active, valid iccid, not empty profile and has carrier privileges
+        when(mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForPackage(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        assertTrue(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    @EnableCompatChanges({EuiccManager.INACTIVE_PORT_AVAILABILITY_CHECK})
+    public void testIsSimPortAvailable_port_inActive() {
+        setUiccCardInfos(false, false, true);
+        when(mUiccController.getUiccSlots()).thenReturn(new UiccSlot[]{mUiccSlot});
+        when(mUiccSlot.isRemovable()).thenReturn(true);
+
+        // Check getRemovableNonEuiccSlot null case
+        when(mUiccSlot.isEuicc()).thenReturn(true);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // Check getRemovableNonEuiccSlot isActive() false case
+        when(mUiccSlot.isEuicc()).thenReturn(false);
+        when(mUiccSlot.isActive()).thenReturn(false);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // assert false,multisim is not enabled
+        when(mUiccSlot.isEuicc()).thenReturn(false);
+        when(mUiccSlot.isActive()).thenReturn(true);
+        when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManager.isMultiSimEnabled()).thenReturn(false);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // assert false, caller does not have carrier privileges
+        setHasWriteEmbeddedPermission(false);
+        when(mTelephonyManager.isMultiSimEnabled()).thenReturn(true);
+        when(mUiccSlot.getPortList()).thenReturn(new int[] {0});
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt())).thenReturn(
+                new SubscriptionInfo.Builder().build());
+        when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // assert true, caller does not have carrier privileges but has write_embedded permission
+        setHasWriteEmbeddedPermission(true);
+        assertTrue(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+
+        // assert true, caller has carrier privileges
+        setHasWriteEmbeddedPermission(false);
+        when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        assertTrue(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    @DisableCompatChanges({EuiccManager.INACTIVE_PORT_AVAILABILITY_CHECK})
+    public void testIsSimPortAvailable_port_inActive_disable_compactChange() {
+        setUiccCardInfos(false, false, true);
+        when(mUiccController.getUiccSlots()).thenReturn(new UiccSlot[]{mUiccSlot});
+        when(mUiccSlot.isRemovable()).thenReturn(true);
+        when(mUiccSlot.isEuicc()).thenReturn(false);
+        when(mUiccSlot.isActive()).thenReturn(true);
+
+        when(mTelephonyManager.isMultiSimEnabled()).thenReturn(true);
+        when(mUiccSlot.getPortList()).thenReturn(new int[] {0});
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt())).thenReturn(
+                new SubscriptionInfo.Builder().build());
+        when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(TEST_PACKAGE_NAME))
+                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        setHasWriteEmbeddedPermission(true);
+
+        // Even though all conditions are true, isSimPortAvailable should return false as
+        // compact change is disabled
+        assertFalse(mController.isSimPortAvailable(CARD_ID, 0, TEST_PACKAGE_NAME));
+    }
+
+
+    private void setUiccCardInfos(boolean isMepSupported, boolean isPortActive,
+            boolean isEmptyPort) {
+        List<UiccPortInfo> euiccPortInfoList;
+        if (isMepSupported) {
+            euiccPortInfoList = Arrays.asList(
+                    new UiccPortInfo(isEmptyPort ? "" : ICC_ID /* iccId */, 0 /* portIdx */,
+                            isPortActive ? 1 : -1 /* logicalSlotIdx */,
+                            isPortActive /* isActive */),
+                    new UiccPortInfo(isEmptyPort ? "" : ICC_ID /* iccId */, 1 /* portIdx */,
+                            -1 /* logicalSlotIdx */,
+                            isPortActive /* isActive */));
+        } else {
+            euiccPortInfoList = Collections.singletonList(
+                    new UiccPortInfo(isEmptyPort ? "" : ICC_ID /* iccId */, 0 /* portIdx */,
+                            isPortActive ? 1 : -1 /* logicalSlotIdx */,
+                            isPortActive /* isActive */)
+                    );
+        }
+
+        UiccCardInfo cardInfo1 = new UiccCardInfo(true, CARD_ID, "", 0,
+                false /* isRemovable */,
+                isMepSupported /* isMultipleEnabledProfileSupported */,
+                euiccPortInfoList);
+        UiccCardInfo cardInfo2 = new UiccCardInfo(false /* isEuicc */,
+                REMOVABLE_CARD_ID /* cardId */,
+                "", 0, true /* isRemovable */,
+                false /* isMultipleEnabledProfileSupported */,
+                Collections.singletonList(
+                        new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
+                                0 /* logicalSlotIdx */, true /* isActive */)));
+        ArrayList<UiccCardInfo> cardInfos = new ArrayList<>();
+        cardInfos.add(cardInfo1);
+        cardInfos.add(cardInfo2);
+        when(mTelephonyManager.getUiccCardsInfo()).thenReturn(cardInfos);
+    }
+
     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 setUpUiccSlotDataWithMEP() {
+        when(mUiccController.getUiccSlot(anyInt())).thenReturn(mUiccSlot);
+        when(mUiccSlot.isMultipleEnabledProfileSupported()).thenReturn(true);
+    }
+
     private void setGetEidPermissions(
             boolean hasPhoneStatePrivileged, boolean hasCarrierPrivileges) throws Exception {
         doReturn(hasPhoneStatePrivileged
@@ -1263,6 +1486,7 @@
             throws Exception {
         SubscriptionInfo.Builder builder = new SubscriptionInfo.Builder()
                 .setSimSlotIndex(0)
+                .setPortIndex(mTelephonyManager.DEFAULT_PORT_INDEX)
                 .setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER_ID)
                 .setEmbedded(true);
         if (hasPrivileges) {
@@ -1300,11 +1524,13 @@
                 .setNativeAccessRules(hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null)
                 .setEmbedded(true)
                 .setCardId(CARD_ID)
+                .setPortIndex(mTelephonyManager.DEFAULT_PORT_INDEX)
                 .build();
         SubscriptionInfo subInfo2 = new SubscriptionInfo.Builder()
                 .setNativeAccessRules(hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null)
                 .setEmbedded(true)
                 .setCardId(2)
+                .setPortIndex(TelephonyManager.DEFAULT_PORT_INDEX)
                 .build();
         when(mSubscriptionManager.canManageSubscription(subInfo1, PACKAGE_NAME)).thenReturn(
                 hasPrivileges);
@@ -1314,6 +1540,26 @@
         when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
     }
 
+    private void setActiveSubscriptionInfoInMEPMode()
+            throws Exception {
+        SubscriptionInfo subInfo1 = new SubscriptionInfo.Builder()
+                .setEmbedded(true)
+                .setCardId(CARD_ID)
+                .setPortIndex(TelephonyManager.DEFAULT_PORT_INDEX)
+                .build();
+        SubscriptionInfo subInfo2 = new SubscriptionInfo.Builder()
+                .setEmbedded(true)
+                .setCardId(CARD_ID)
+                .setPortIndex(1)
+                .build();
+        when(mSubscriptionManager.canManageSubscription(subInfo1, PACKAGE_NAME)).thenReturn(
+                false);
+        when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
+                true);
+        ArrayList<SubscriptionInfo> subInfos = new ArrayList<>(Arrays.asList(subInfo1, subInfo2));
+        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
+    }
+
     private void prepareOperationSubscription(boolean hasPrivileges) throws Exception {
         SubscriptionInfo subInfo = new SubscriptionInfo.Builder()
                 .setId(SUBSCRIPTION_ID)
@@ -1404,7 +1650,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Exception {
                 EuiccConnector.GetMetadataCommandCallback cb = invocation
-                        .getArgument(3 /* resultCallback */);
+                        .getArgument(5 /* resultCallback */);
                 if (complete) {
                     cb.onGetMetadataComplete(CARD_ID, result);
                 } else {
@@ -1412,8 +1658,8 @@
                 }
                 return null;
             }
-        }).when(mMockConnector).getDownloadableSubscriptionMetadata(anyInt(), any(), anyBoolean(),
-                any());
+        }).when(mMockConnector).getDownloadableSubscriptionMetadata(anyInt(), anyInt(), any(),
+                anyBoolean(), anyBoolean(), any());
     }
 
     private void callGetDownloadableSubscriptionMetadata(DownloadableSubscription subscription,
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..c261afe 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -36,6 +36,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.BroadcastOptions;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -55,9 +56,9 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
+import com.android.ims.ImsManager;
 import com.android.internal.telephony.FakeSmsContentProvider;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.InboundSmsTracker;
@@ -192,9 +193,9 @@
                 InboundSmsHandler.SOURCE_NOT_INJECTED);
         doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
                 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(),
-                anyInt(), anyBoolean(),
-                anyBoolean(), nullable(String.class), nullable(String.class),
-                nullable(String.class), anyBoolean(), anyInt(), anyInt());
+                        anyInt(), anyBoolean(),
+                        anyBoolean(), nullable(String.class), nullable(String.class),
+                        nullable(String.class), anyBoolean(), anyInt(), anyInt());
 
         createInboundSmsTrackerMultiSim();
 
@@ -203,12 +204,11 @@
                 Telephony.Sms.CONTENT_URI.getAuthority(), mContentProvider);
 
         mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(mContext,
-                mSmsStorageMonitor, mPhone);
+                mSmsStorageMonitor, mPhone, mTestableLooper.getLooper());
         mSmsFilters = new ArrayList<>();
         mSmsFilters.add(mSmsFilter);
         mSmsFilters.add(mSmsFilter2);
         mGsmInboundSmsHandler.setSmsFiltersForTesting(mSmsFilters);
-        monitorTestableLooper(new TestableLooper(mGsmInboundSmsHandler.getHandler().getLooper()));
 
         doReturn(mGsmInboundSmsHandler).when(mPhone).getInboundSmsHandler(false);
         doReturn(mCdmaInboundSmsHandler).when(mPhone).getInboundSmsHandler(true);
@@ -278,8 +278,8 @@
         assertEquals("WaitingState", getCurrentState().getName());
         if (allowBgActivityStarts) {
             Bundle broadcastOptions = mContextFixture.getLastBroadcastOptions();
-            assertTrue(broadcastOptions
-                    .getBoolean("android:broadcast.allowBackgroundActivityStarts"));
+            BroadcastOptions brOptions = new BroadcastOptions(broadcastOptions);
+            assertTrue(brOptions.allowsBackgroundActivityStarts());
         }
 
         mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
@@ -310,7 +310,6 @@
         processAllMessages();
     }
 
-    @FlakyTest
     @Test
     @MediumTest
     public void testNewSms() {
@@ -330,7 +329,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testNewSmsFromBlockedNumber_noBroadcastsSent() {
@@ -348,7 +346,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testNewSmsWithUserLocked_notificationShown() {
@@ -375,7 +372,6 @@
                 any(Notification.class));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testNewSmsFromBlockedNumberWithUserLocked_noNotificationShown() {
@@ -405,7 +401,6 @@
                 any(Notification.class));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testNewSms_filterInvoked_noBroadcastsSent() {
@@ -431,7 +426,6 @@
                 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testNewSms_filterChaining_noBroadcastsSent() {
@@ -483,7 +477,6 @@
         assertEquals("IdleState", getCurrentState().getName());
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testClass0Sms() {
@@ -515,7 +508,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testBroadcastSms() {
@@ -556,7 +548,6 @@
         verifySmsFiltersInvoked(times(2));
     }
 
-    @FlakyTest
     @Test
     @MediumTest
     public void testInjectSms() {
@@ -617,7 +608,6 @@
                 InboundSmsHandler.SOURCE_NOT_INJECTED);
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultiPartSmsWithIncompleteWAP() {
@@ -678,12 +668,13 @@
         assertEquals("IdleState", getCurrentState().getName());
         // verify there are three segments in the db and only one of them is not marked as deleted.
         assertEquals(3, mContentProvider.getNumRows());
-        assertEquals(1, mContentProvider.query(sRawUri, null, "deleted=0", null, null).getCount());
 
+        Cursor c = mContentProvider.query(sRawUri, null, "deleted=0", null, null);
+        assertEquals(1, c.getCount());
         verifySmsFiltersInvoked(times(1));
+        c.close();
     }
 
-    @FlakyTest
     @Test
     @MediumTest
     public void testMultiPartSms() {
@@ -757,7 +748,6 @@
         assertEquals("IdleState", getCurrentState().getName());
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultiPartIncompleteSms() {
@@ -820,9 +810,9 @@
         // State machine should go back to idle
         assertEquals("IdleState", getCurrentState().getName());
         verifySmsFiltersInvoked(never());
+        c.close();
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultiPartSmsWithInvalidSeqNumber() {
@@ -882,7 +872,6 @@
         verifySmsFiltersInvoked(never());
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultipartSmsFromBlockedNumber_noBroadcastsSent() {
@@ -921,7 +910,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultipartSmsFromBlockedEmail_noBroadcastsSent() {
@@ -977,7 +965,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testMultipartSms_filterInvoked_noBroadcastsSent() {
@@ -1027,7 +1014,6 @@
                 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testBroadcastUndeliveredUserLocked() throws Exception {
@@ -1085,7 +1071,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testBroadcastUndeliveredUserUnlocked() throws Exception {
@@ -1123,7 +1108,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testBroadcastUndeliveredDeleted() throws Exception {
@@ -1164,7 +1148,6 @@
         verifySmsFiltersInvoked(never());
     }
 
-    @FlakyTest
     @Test
     @MediumTest
     public void testBroadcastUndeliveredMultiPart() throws Exception {
@@ -1180,7 +1163,7 @@
         //return InboundSmsTracker objects corresponding to the 2 parts
         doReturn(mInboundSmsTrackerPart1).doReturn(mInboundSmsTrackerPart2).
                 when(mTelephonyComponentFactory).makeInboundSmsTracker(any(Context.class),
-                any(Cursor.class), anyBoolean());
+                        any(Cursor.class), anyBoolean());
 
         SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
         // wait for ScanRawTableThread
@@ -1191,7 +1174,6 @@
         verifySmsFiltersInvoked(times(1));
     }
 
-    @FlakyTest // temporarily disabled, see b/182498318
     @Test
     @MediumTest
     public void testBroadcastUndeliveredMultiSim() throws Exception {
@@ -1251,4 +1233,12 @@
         assertEquals("IdleState", getCurrentState().getName());
 
     }
+
+    @Test
+    public void testSetImsManager() {
+        ImsManager imsManager = Mockito.mock(ImsManager.class);
+        transitionFromStartupToIdle();
+        assertTrue(mGsmInboundSmsHandler.setImsManager(imsManager));
+    }
 }
+
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 c0444f1..1c1ca0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
@@ -333,4 +333,3 @@
         doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
     }
 }
-
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 23aa083..8374daa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -66,7 +66,6 @@
 import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.SMSDispatcher;
 import com.android.internal.telephony.SmsDispatchersController;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.TelephonyTestUtils;
 import com.android.internal.telephony.TestApplication;
@@ -231,7 +230,8 @@
         restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton);
         restoreInstance(ActivityManager.class, "IActivityManagerSingleton", null);
         Context realContext = TestApplication.getAppContext();
-        realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT));
+        realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT),
+                Context.RECEIVER_EXPORTED);
     }
 
     @Test
@@ -376,6 +376,7 @@
 
     @Test
     @SmallTest
+    @Ignore("b/256282780")
     public void testSendSmsByCarrierApp() throws Exception {
         mockCarrierApp();
         mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK,
@@ -383,7 +384,9 @@
         registerTestIntentReceiver();
 
         PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0,
-                new Intent(TEST_INTENT), PendingIntent.FLAG_MUTABLE);
+                new Intent(TEST_INTENT)
+                        .setPackage(TestApplication.getAppContext().getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
         mReceivedTestIntent = false;
 
         mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms",
@@ -438,9 +441,13 @@
 
         ArrayList<PendingIntent> sentIntents = new ArrayList<>();
         PendingIntent sentIntent1 = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0,
-                new Intent(TEST_INTENT), PendingIntent.FLAG_MUTABLE);
+                new Intent(TEST_INTENT)
+                        .setPackage(TestApplication.getAppContext().getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
         PendingIntent sentIntent2 = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0,
-                new Intent(TEST_INTENT), PendingIntent.FLAG_MUTABLE);
+                new Intent(TEST_INTENT)
+                        .setPackage(TestApplication.getAppContext().getPackageName()),
+                PendingIntent.FLAG_MUTABLE);
         sentIntents.add(sentIntent1);
         sentIntents.add(sentIntent2);
 
@@ -450,6 +457,7 @@
 
     @Test
     @SmallTest
+    @Ignore("b/256282780")
     public void testSendMultipartSmsByCarrierApp() throws Exception {
         mockCarrierApp();
         mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK,
@@ -510,7 +518,11 @@
 
     @Test
     public void testSendTextWithMessageRef() throws Exception {
-        int messageRef = mGsmSmsDispatcher.nextMessageRef() + 1;
+        int messageRef = mGsmSmsDispatcher.nextMessageRef();
+        if (mGsmSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += 1;
+        }
+
         mGsmSmsDispatcher.sendText("111", "222" /*scAddr*/, TAG,
                 null, null, null, null, false, -1, false, -1, false, 0L);
 
@@ -518,7 +530,7 @@
         verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor.capture(),
                 any(Message.class));
         byte[] pdu = IccUtils.hexStringToBytes(pduCaptor.getValue());
-        assertEquals(pdu[1], messageRef);
+        assertEquals(messageRef, pdu[1]);
     }
 
     @Test
@@ -527,7 +539,11 @@
         parts.add("segment1");
         parts.add("segment2");
         parts.add("segment3");
-        int messageRef = mGsmSmsDispatcher.nextMessageRef() + parts.size();
+
+        int messageRef = mGsmSmsDispatcher.nextMessageRef();
+        if (mGsmSmsDispatcher.isMessageRefIncrementViaTelephony()) {
+            messageRef += parts.size();
+        }
         mGsmSmsDispatcher.sendMultipartText("6501002000" /*destAddr*/, "222" /*scAddr*/, parts,
                 null, null, null, null, false, -1, false, -1, 0L);
         waitForMs(150);
@@ -539,7 +555,7 @@
         verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor.capture(),
                 any(Message.class));
         byte[] pdu = IccUtils.hexStringToBytes(pduCaptor.getValue());
-        assertEquals(pdu[1], messageRef);
+        assertEquals(messageRef, pdu[1]);
     }
 
     @Test
@@ -549,15 +565,16 @@
         doReturn(mIsimUiccRecords).when(mPhone).getIccRecords();
         Message msg = mGsmSmsDispatcher.obtainMessage(17);
         mPhone.getIccRecords().setSmssTpmrValue(-1, msg);
-        SubscriptionController.getInstance().updateMessageRef(mPhone.getSubId(), -1);
+        mSubscriptionManagerService.setLastUsedTPMessageReference(mPhone.getSubId(), -1);
+
         mGsmSmsDispatcher.sendText("111", "222" /*scAddr*/, TAG,
                 null, null, null, null, false, -1, false, -1, false, 0L);
 
-        ArgumentCaptor<String> pduCaptor1 = ArgumentCaptor.forClass(String.class);
-        verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor1.capture(),
+        ArgumentCaptor<String> pduCaptor = ArgumentCaptor.forClass(String.class);
+        verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor.capture(),
                 any(Message.class));
-        byte[] pdu1 = IccUtils.hexStringToBytes(pduCaptor1.getValue());
-        assertEquals(pdu1[1], 0);
+        byte[] pdu = IccUtils.hexStringToBytes(pduCaptor.getValue());
+        assertEquals(0, pdu[1]);
     }
 
     @Test
@@ -566,15 +583,14 @@
                 mSimulatedCommands);
         doReturn(mIsimUiccRecords).when(mPhone).getIccRecords();
         Message msg = mGsmSmsDispatcher.obtainMessage(17);
-
-        mPhone.getIccRecords().setSmssTpmrValue(255, null);
+        mPhone.getIccRecords().setSmssTpmrValue(255, msg);
         mGsmSmsDispatcher.sendText("111", "222" /*scAddr*/, TAG,
                 null, null, null, null, false, -1, false, -1, false, 0L);
 
-        ArgumentCaptor<String> pduCaptor2 = ArgumentCaptor.forClass(String.class);
-        verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor2.capture(),
+        ArgumentCaptor<String> pduCaptor = ArgumentCaptor.forClass(String.class);
+        verify(mSimulatedCommandsVerifier).sendSMS(anyString(), pduCaptor.capture(),
                 any(Message.class));
-        byte[] pdu2 = IccUtils.hexStringToBytes(pduCaptor2.getValue());
-        assertEquals(pdu2[1], 0);
+        byte[] pdu = IccUtils.hexStringToBytes(pduCaptor.getValue());
+        assertEquals(0, pdu[1]);
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadHandlerTest.java
new file mode 100644
index 0000000..c6041c8
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadHandlerTest.java
@@ -0,0 +1,403 @@
+/*
+ * 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.gsm;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Message;
+import android.telephony.ims.stub.ImsSmsImplBase;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.InboundSmsHandler;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.uicc.IccIoResult;
+import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.util.HexDump;
+
+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 UsimDataDownloadHandlerTest extends TelephonyTest {
+    // Mocked classes
+    private CommandsInterface mMockCi;
+    protected GsmCdmaPhone mMockPhone;
+    private ImsManager mMockImsManager;
+    private Resources mMockResources;
+
+    private UsimDataDownloadHandler mUsimDataDownloadHandler;
+    private Phone mPhoneObj;
+    private Phone[] mPhoneslist;
+    private int mPhoneId;
+    private int mSlotId = 0;
+    private int mToken = 0;
+    private int mSmsSource = 1;
+    private byte[] mTpdu;
+    private byte[] mSmsAckPdu;
+    //Envelope is created as per TS.131.111 for SMS-PP data downwnload operation
+    private String mEnvelope = "D11502028281060591896745F306068199201269231300";
+    //SMS TPDU for Class2 according to TS.123.040
+    private String mPdu = "07914151551512f221110A81785634121000000666B2996C2603";
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        mMockCi = Mockito.mock(CommandsInterface.class);
+        mMockPhone = Mockito.mock(GsmCdmaPhone.class);
+        mMockImsManager = Mockito.mock(ImsManager.class);
+        mMockResources = Mockito.mock(Resources.class);
+
+        mPhoneslist = new Phone[] {mMockPhone};
+        mTpdu = HexDump.hexStringToByteArray(mPdu);
+
+        //Use reflection to mock
+        replaceInstance(PhoneFactory.class, "sPhones", null, mPhoneslist);
+        replaceInstance(PhoneFactory.class, "sPhone", null, mMockPhone);
+
+        mPhoneObj = PhoneFactory.getPhone(mSlotId);
+        assertNotNull(mPhoneObj);
+        mPhoneId = mPhoneObj.getPhoneId();
+        doReturn(mSmsStats).when(mPhoneObj).getSmsStats();
+
+        //new UsimDataDownloadHandlerThread(TAG).start();
+        //waitUntilReady();
+        mUsimDataDownloadHandler = new UsimDataDownloadHandler(mMockCi, mPhoneId);
+        mUsimDataDownloadHandler.setImsManager(mMockImsManager);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mUsimDataDownloadHandler = null;
+        mPhoneslist = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void sendEnvelopeForException() throws Exception {
+        setSmsPPSimConfig(false);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    AsyncResult.forMessage(response, null, new CommandException(
+                                CommandException.Error.OPERATION_NOT_ALLOWED));
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(false,
+                CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR, null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
+    }
+
+    @Test
+    public void sendEnvelopeDataDownloadSuccess() throws Exception {
+        setSmsPPSimConfig(true);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+        mSmsAckPdu = createSmsAckPdu(true, mEnvelope, sms);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    IccIoResult iir = new IccIoResult(0x90, 0x00,
+                            IccUtils.hexStringToBytes(mEnvelope));
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_OK, mSmsAckPdu);
+
+        setSmsPPSimConfig(false);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeIncomingGsmSmsWithPdu(true,
+                IccUtils.bytesToHexString(mSmsAckPdu), null);
+    }
+
+    @Test
+    public void sendEnvelopeDataDownloadFailed() throws Exception {
+        setSmsPPSimConfig(false);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    IccIoResult iir = new IccIoResult(0x93, 0x00,
+                            IccUtils.hexStringToBytes(mEnvelope));
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(false,
+                CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY, null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
+    }
+
+    @Test
+    public void sendEnvelopeForSw1_62() throws Exception {
+        setSmsPPSimConfig(false);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+        mSmsAckPdu = createSmsAckPdu(false, mEnvelope, sms);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    IccIoResult iir = new IccIoResult(0x62, 0x63,
+                            IccUtils.hexStringToBytes(mEnvelope));
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeIncomingGsmSmsWithPdu(false,
+                IccUtils.bytesToHexString(mSmsAckPdu), null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_OK, mSmsAckPdu);
+    }
+
+    @Test
+    public void smsCompleteForException() throws Exception {
+        setSmsPPSimConfig(false);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(3);
+                    AsyncResult.forMessage(response, null, new CommandException(
+                                CommandException.Error.OPERATION_NOT_ALLOWED));
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .writeSmsToSim(anyInt(), anyString(), anyString(), any(Message.class));
+
+        int[] responseInfo = {mSmsSource, mTpdu[9], mToken};
+        Message msg = mUsimDataDownloadHandler.obtainMessage(3 /* EVENT_WRITE_SMS_COMPLETE */,
+                responseInfo);
+        AsyncResult.forMessage(msg, null, new CommandException(
+                                CommandException.Error.OPERATION_NOT_ALLOWED));
+        mUsimDataDownloadHandler.handleMessage(msg);
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(false,
+                CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR, null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.handleMessage(msg);
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
+    }
+
+    @Test
+    public void smsComplete() throws Exception {
+        setSmsPPSimConfig(true);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(3);
+                    IccIoResult iir = new IccIoResult(0x90, 0x00,
+                            IccUtils.hexStringToBytes(mEnvelope));
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .writeSmsToSim(anyInt(), anyString(), anyString(), any(Message.class));
+
+        int[] responseInfo = {mSmsSource, mTpdu[9], mToken};
+        Message msg = mUsimDataDownloadHandler.obtainMessage(3 /* EVENT_WRITE_SMS_COMPLETE */,
+                responseInfo);
+        AsyncResult.forMessage(msg, null, null);
+        mUsimDataDownloadHandler.handleMessage(msg);
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9], ImsSmsImplBase.DELIVER_STATUS_OK);
+
+        setSmsPPSimConfig(false);
+        mUsimDataDownloadHandler.handleMessage(msg);
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(true, 0, null);
+    }
+
+    @Test
+    public void failureEnvelopeResponse() throws Exception {
+        setSmsPPSimConfig(false);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    IccIoResult iir = new IccIoResult(0x62, 0x63,
+                            IccUtils.hexStringToBytes(null)); //ForNullResponseBytes
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(false,
+                CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR, null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9],
+                ImsSmsImplBase.DELIVER_STATUS_ERROR_GENERIC);
+    }
+
+    @Test
+    public void successEnvelopeResponse() throws Exception {
+        setSmsPPSimConfig(false);
+        com.android.internal.telephony.gsm.SmsMessage sms =
+                com.android.internal.telephony.gsm.SmsMessage.createFromPdu(mTpdu);
+
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(1);
+                    IccIoResult iir = new IccIoResult(0x90, 0x00,
+                            IccUtils.hexStringToBytes(null)); //ForNullResponseBytes
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mMockCi)
+                .sendEnvelopeWithStatus(anyString(), any(Message.class));
+
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        verify(mMockCi).acknowledgeLastIncomingGsmSms(true, 0, null);
+
+        setSmsPPSimConfig(true);
+        mUsimDataDownloadHandler.startDataDownload(sms,
+                 InboundSmsHandler.SOURCE_INJECTED_FROM_IMS, mToken);
+        processAllMessages();
+        //mTpdu[9] holds messageReference value
+        verify(mMockImsManager).acknowledgeSms(mToken, mTpdu[9], ImsSmsImplBase.DELIVER_STATUS_OK);
+    }
+
+    //To set "config_smppsim_response_via_ims" for testing purpose
+    private void setSmsPPSimConfig(boolean config) {
+        mUsimDataDownloadHandler.setResourcesForTest(mMockResources);
+        doReturn(config).when(mMockResources).getBoolean(
+                com.android.internal.R.bool.config_smppsim_response_via_ims);
+    }
+
+    private byte[] createSmsAckPdu(boolean success, String envelope, SmsMessage smsMessage) {
+        byte[] responseBytes = IccUtils.hexStringToBytes(envelope);
+        int dcs = 0x00;
+        int pid = smsMessage.getProtocolIdentifier();
+        byte[] smsAckPdu;
+        int index = 0;
+        if (success) {
+            smsAckPdu = new byte[responseBytes.length + 5];
+            smsAckPdu[index++] = 0x00;
+            smsAckPdu[index++] = 0x07;
+        } else {
+            smsAckPdu = new byte[responseBytes.length + 6];
+            smsAckPdu[index++] = 0x00;
+            smsAckPdu[index++] = (byte)
+                    CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR;
+            smsAckPdu[index++] = 0x07;
+        }
+
+        smsAckPdu[index++] = (byte) pid;
+        smsAckPdu[index++] = (byte) dcs;
+
+        if (((dcs & 0x8C) == 0x00) || ((dcs & 0xF4) == 0xF0)) {
+            int septetCount = responseBytes.length * 8 / 7;
+            smsAckPdu[index++] = (byte) septetCount;
+        } else {
+            smsAckPdu[index++] = (byte) responseBytes.length;
+        }
+
+        System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length);
+        return smsAckPdu;
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsEnablementTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsEnablementTrackerTest.java
new file mode 100644
index 0000000..c6f45d9
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsEnablementTrackerTest.java
@@ -0,0 +1,812 @@
+/*
+ * 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 com.android.internal.telephony.ims.ImsEnablementTracker.COMMAND_DISABLE_MSG;
+import static com.android.internal.telephony.ims.ImsEnablementTracker.COMMAND_ENABLE_MSG;
+import static com.android.internal.telephony.ims.ImsEnablementTracker.COMMAND_RESETTING_DONE;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.telephony.ims.aidl.IImsServiceController;
+import android.test.suitebuilder.annotation.SmallTest;
+
+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.Mock;
+
+/**
+ * Unit tests for ImsEnablementTracker
+ */
+@RunWith(AndroidJUnit4.class)
+public class ImsEnablementTrackerTest extends ImsTestBase {
+
+    // default timeout values(millisecond) for handler working
+    private static final int DEFAULT_TIMEOUT = 100;
+
+    // default delay values(millisecond) for handler working
+    private static final int DEFAULT_DELAY = 150;
+
+    private static final int SLOT_1 = 0;
+    private static final int SUB_1 = 11;
+
+    private static final int SLOT_2 = 1;
+    private static final int SUB_2 = 22;
+    private static final long TEST_REQUEST_THROTTLE_TIME_MS = 3000L;
+
+    // Mocked classes
+    @Mock
+    IImsServiceController mMockServiceControllerBinder;
+
+    private TestableImsEnablementTracker mTracker;
+    private Handler mHandler;
+
+    private static long sLastImsOperationTimeMs = 0L;
+
+    private static class TestableImsEnablementTracker extends ImsEnablementTracker {
+        private ImsEnablementTrackerTest mOwner;
+
+        TestableImsEnablementTracker(Looper looper, IImsServiceController controller, int state,
+                int numSlots, ImsEnablementTrackerTest owner) {
+            super(looper, controller, state, numSlots);
+            mOwner = owner;
+        }
+
+        @Override
+        protected long getLastOperationTimeMillis() {
+            return ImsEnablementTrackerTest.sLastImsOperationTimeMs;
+        }
+    }
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        // Make sure the handler is empty before finishing the test.
+        waitForHandlerAction(mHandler, TEST_REQUEST_THROTTLE_TIME_MS);
+
+        mTracker = null;
+        super.tearDown();
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInDefaultState() throws RemoteException {
+        // Verify that when the enable command is received in the Default state and enableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DEFAULT, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+         // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInDefaultState() throws RemoteException {
+        // Verify that when the disable command is received in the Default state and disableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DEFAULT, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandInDefaultState() throws RemoteException {
+        // Verify that when reset command is received in the Default state, it should be ignored.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DEFAULT, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).resetIms(eq(SLOT_1), eq(SUB_1));
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInEnabledState() throws RemoteException {
+        // Verify that received the enable command is not handle in the Enabled state,
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLED, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder, never()).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInEnabledState() throws RemoteException {
+        // Verify that when the disable command is received in the Enabled state and disableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLED, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandInEnabledState() throws RemoteException {
+        // Verify that when the reset command is received in the Enabled state and disableIms
+        // and enableIms are called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLED, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        verify(mMockServiceControllerBinder).resetIms(eq(SLOT_1), eq(SUB_1));
+
+        waitForHandlerActionDelayed(mHandler, TEST_REQUEST_THROTTLE_TIME_MS,
+                TEST_REQUEST_THROTTLE_TIME_MS + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInDisabledState() throws RemoteException {
+        // Verify that when disable command is received in the Disabled state, it should be ignored.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLED, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verifyZeroInteractions(mMockServiceControllerBinder);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInDisabledState() throws RemoteException {
+        // Verify that when the enable command is received in the Disabled state and enableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLED, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandWithoutTimeoutInDisableState() throws RemoteException {
+        // Verify that when the enable command is received in the Disabled state. After throttle
+        // time expired, the enableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLED, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandInDisabledState() throws RemoteException {
+        // Verify that the reset command is received in the Disabled state and it`s not handled.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLED, 1, 0);
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        verify(mMockServiceControllerBinder).resetIms(eq(SLOT_1), eq(SUB_1));
+
+        // The disableIms was called. So set the last operation time to current.
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInDisablingState() throws RemoteException {
+        // Verify that when enable command is received in the Disabling state, it should be ignored.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verifyZeroInteractions(mMockServiceControllerBinder);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisablingMessageInDisablingState() throws RemoteException {
+        // Verify that when the internal disable message is received in the Disabling state and
+        // disableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).disableIms(anyInt(), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandInDisablingState() throws RemoteException {
+        // Verify when the reset command is received in the Disabling state the disableIms and
+        // enableIms are called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).resetIms(eq(SLOT_1), eq(SUB_1));
+
+        // The disableIms was called. So set the last operation time to current.
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnablingMessageInEnablingState() throws RemoteException {
+        // Verify that when the internal enable message is received in the Enabling state and
+        // enableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).enableIms(anyInt(), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInEnablingState() throws RemoteException {
+        // Verify that when the disable command is received in the Enabling state and
+        // clear pending message and disableIms is not called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandWithEnablingState() throws RemoteException {
+        // Verify that when reset command is received in the Enabling state, it should be ignored.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).resetIms(eq(SLOT_1), eq(SUB_1));
+
+        // The disableIms was called. So set the last operation time to current.
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInResettingState() throws RemoteException {
+        // Verify that when the enable command is received in the Resetting state and
+        // enableIms is not called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verifyZeroInteractions(mMockServiceControllerBinder);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_RESETTING));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInResettingState() throws RemoteException {
+        // Verify that when the disable command is received in the Resetting state and
+        // disableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verifyZeroInteractions(mMockServiceControllerBinder);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_RESETTING));
+    }
+
+    @SmallTest
+    @Test
+    public void testResettingMessageInResettingState() throws RemoteException {
+        // Verify that when the internal reset message is received in the Resetting state and
+        // disableIms and enableIms are called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+
+        // Wait for the throttle time.
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).resetIms(anyInt(), anyInt());
+
+        // Set the last operation time to current to verify the message with delay.
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), anyInt());
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableEnableMessageInResettingState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // Simulation.
+        // In Resetting state, disableIms() called before doing resetIms().
+        // After doing resetIms(), during the throttle time(before doing disableIms()),
+        // enableIms() called. Finally skip disableIms() and do enableIms().
+        mHandler.removeMessages(COMMAND_RESETTING_DONE);
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_RESETTING_DONE, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).resetIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableDisableMessageInResettingState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // Simulation.
+        // In Resetting state, enableIms() called before doing resetIms().
+        // After doing resetIms(), during the throttle time(before doing enableIms()),
+        // disableIms() called. Finally skip enableIms() and do disableIms().
+        mHandler.removeMessages(COMMAND_RESETTING_DONE);
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_RESETTING_DONE, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).resetIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, times(1)).disableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testRepeatEnableMessageInResettingState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // Simulation.
+        // In Resetting state, enableIms(), disableIms() are called repeatedly.
+        // After doing resetIms(), latest enableIms() should perform.
+        mHandler.removeMessages(COMMAND_RESETTING_DONE);
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_RESETTING_DONE, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).resetIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testRepeatDisableMessageInResettingState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_RESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // Simulation.
+        // In Resetting state, enableIms(), disableIms() are called repeatedly.
+        // After doing resetIms(), latest disableIms() should perform.
+        mHandler.removeMessages(COMMAND_RESETTING_DONE);
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_RESETTING_DONE, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_ENABLE_MSG, SLOT_1, SUB_1));
+        mHandler.sendMessage(mHandler.obtainMessage(COMMAND_DISABLE_MSG, SLOT_1, SUB_1));
+
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).resetIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, times(1)).disableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testConsecutiveCommandInEnabledState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLED, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+
+        // Set the last operation time to current to verify the message with delay.
+        sLastImsOperationTimeMs = System.currentTimeMillis();
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLING));
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLING));
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).disableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).resetIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testConsecutiveCommandInDisabledState() throws RemoteException {
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DISABLED, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // Set the last operation time to current to verify the message with delay.
+        sLastImsOperationTimeMs = System.currentTimeMillis();
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLING));
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_RESETTING));
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testSubIdChangeToInvalidAndEnableCommand() throws RemoteException {
+        // Verify that when the enable command is received in the Default state and enableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_ENABLED, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        mTracker.subIdChangedToInvalid(SLOT_1);
+        waitForHandler(mHandler);
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DEFAULT));
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandWithDifferentSlotId() throws RemoteException {
+        // Verify that when the enable command is received in the Default state and enableIms
+        // is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_DEFAULT, 2,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        Handler handlerForSlot2 = mTracker.getHandler(SLOT_2);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+        waitForHandler(handlerForSlot2);
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandler(mHandler);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+        assertTrue(mTracker.isState(SLOT_2, mTracker.STATE_IMS_DEFAULT));
+
+        mTracker.enableIms(SLOT_2, SUB_2);
+        waitForHandler(handlerForSlot2);
+
+        verify(mMockServiceControllerBinder).enableIms(eq(SLOT_2), eq(SUB_2));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+        assertTrue(mTracker.isState(SLOT_2, mTracker.STATE_IMS_ENABLED));
+
+        mTracker.setNumOfSlots(1);
+        sLastImsOperationTimeMs = System.currentTimeMillis();
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder).disableIms(eq(SLOT_1), eq(SUB_1));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+
+        mTracker.setNumOfSlots(2);
+        sLastImsOperationTimeMs = System.currentTimeMillis();
+        mTracker.disableIms(SLOT_2, SUB_2);
+        waitForHandler(handlerForSlot2);
+
+        verify(mMockServiceControllerBinder).disableIms(eq(SLOT_2), eq(SUB_2));
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+        assertTrue(mTracker.isState(SLOT_2, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testEnableCommandInPostResettingState() throws RemoteException {
+        // Verify that when the enable/disable commands are received in the PostResetting state
+        // and final enableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_POSTRESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // to confirm the slotId, subId for COMMAND_POST_RESETTING_DONE
+        mHandler.removeMessages(mTracker.COMMAND_POST_RESETTING_DONE);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(mTracker.COMMAND_POST_RESETTING_DONE,
+                SLOT_1, SUB_1), mTracker.getRemainThrottleTime());
+
+        mTracker.enableIms(SLOT_1, SUB_1);
+        mTracker.disableIms(SLOT_1, SUB_1);
+        mTracker.enableIms(SLOT_1, SUB_1);
+        mTracker.disableIms(SLOT_1, SUB_1);
+        mTracker.enableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisableCommandInPostResettingState() throws RemoteException {
+        // Verify that when the enable/disable commands are received in the PostResetting state
+        // and final disableIms is called.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_POSTRESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // to confirm the slotId, subId for COMMAND_POST_RESETTING_DONE
+        mHandler.removeMessages(mTracker.COMMAND_POST_RESETTING_DONE);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(mTracker.COMMAND_POST_RESETTING_DONE,
+                SLOT_1, SUB_1), mTracker.getRemainThrottleTime());
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        mTracker.enableIms(SLOT_1, SUB_1);
+        mTracker.disableIms(SLOT_1, SUB_1);
+        mTracker.enableIms(SLOT_1, SUB_1);
+        mTracker.disableIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).disableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).enableIms(eq(SLOT_1), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_DISABLED));
+    }
+
+    @SmallTest
+    @Test
+    public void testResetCommandInPostResettingState() throws RemoteException {
+        // Verify that when the enable/disable/reset commands are received in the PostResetting
+        // state and final enableIms is called without calling resetIms again.
+        mTracker = createTracker(mMockServiceControllerBinder, mTracker.STATE_IMS_POSTRESETTING, 1,
+                System.currentTimeMillis());
+        mHandler = mTracker.getHandler(SLOT_1);
+        // Wait for a while for the state machine to be ready.
+        waitForHandler(mHandler);
+
+        // to confirm the slotId, subId for COMMAND_POST_RESETTING_DONE
+        mHandler.removeMessages(mTracker.COMMAND_POST_RESETTING_DONE);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(mTracker.COMMAND_POST_RESETTING_DONE,
+                SLOT_1, SUB_1), mTracker.getRemainThrottleTime());
+
+        mTracker.disableIms(SLOT_1, SUB_1);
+        mTracker.enableIms(SLOT_1, SUB_1);
+        mTracker.resetIms(SLOT_1, SUB_1);
+        waitForHandlerActionDelayed(mHandler, mTracker.getRemainThrottleTime(),
+                mTracker.getRemainThrottleTime() + DEFAULT_DELAY);
+
+        verify(mMockServiceControllerBinder, times(1)).enableIms(eq(SLOT_1), eq(SUB_1));
+        verify(mMockServiceControllerBinder, never()).disableIms(eq(SLOT_1), anyInt());
+        verify(mMockServiceControllerBinder, never()).resetIms(eq(SLOT_1), anyInt());
+        assertTrue(mTracker.isState(SLOT_1, mTracker.STATE_IMS_ENABLED));
+    }
+
+    private TestableImsEnablementTracker createTracker(IImsServiceController binder, int state,
+            int numSlots, long initLastOperationTime) {
+        sLastImsOperationTimeMs = initLastOperationTime;
+        TestableImsEnablementTracker tracker = new TestableImsEnablementTracker(
+                Looper.getMainLooper(), binder, state, numSlots, this);
+        return tracker;
+    }
+
+    private void waitForHandler(Handler h) {
+        waitForHandlerActionDelayed(h, DEFAULT_TIMEOUT, DEFAULT_DELAY);
+    }
+}
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..abc231a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
@@ -956,7 +956,7 @@
         carrierFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(1, ImsFeature.FEATURE_RCS));
         // Assume that there is a CarrierConfig change that kicks off query to carrier service.
         sendCarrierConfigChanged(1, 1);
-        setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 2);
+        setupDynamicQueryFeaturesMultiSim(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 2);
         verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
                         any(SparseIntArray.class));
         deviceFeatureSet = convertToHashSet(deviceFeatures, 0);
@@ -2021,6 +2021,7 @@
      */
     private void startBindCarrierConfigAlreadySet() {
         mTestImsResolver.initialize();
+        processAllMessages();
         ArgumentCaptor<BroadcastReceiver> receiversCaptor =
                 ArgumentCaptor.forClass(BroadcastReceiver.class);
         verify(mMockContext, times(3)).registerReceiver(receiversCaptor.capture(), any());
@@ -2042,6 +2043,7 @@
      */
     private void startBindNoCarrierConfig(int numSlots) {
         mTestImsResolver.initialize();
+        processAllMessages();
         ArgumentCaptor<BroadcastReceiver> receiversCaptor =
                 ArgumentCaptor.forClass(BroadcastReceiver.class);
         verify(mMockContext, times(3)).registerReceiver(receiversCaptor.capture(), any());
@@ -2068,6 +2070,15 @@
         processAllMessages();
     }
 
+    private void setupDynamicQueryFeaturesMultiSim(ComponentName name,
+            HashSet<ImsFeatureConfiguration.FeatureSlotPair> features, int times) {
+        processAllFutureMessages();
+        // ensure that startQuery was called
+        verify(mMockQueryManager, times(times)).startQuery(eq(name), any(String.class));
+        mDynamicQueryListener.onComplete(name, features);
+        processAllMessages();
+    }
+
     private void setupDynamicQueryFeaturesFailure(ComponentName name, int times) {
         processAllMessages();
         // ensure that startQuery was called
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java
index b80c6b0..4a3ceaa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java
@@ -140,6 +140,8 @@
         SparseIntArray slotIdToSubIdMap = new SparseIntArray();
         slotIdToSubIdMap.put(SLOT_0, SUB_1);
         ServiceConnection conn = bindAndConnectService(slotIdToSubIdMap);
+        long delay = mTestImsServiceController.getRebindDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         // add the MMTelFeature
         verify(mMockServiceControllerBinder).createMMTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
@@ -149,6 +151,8 @@
         validateMmTelFeatureContainerExists(SLOT_0);
         // Remove the feature
         conn.onBindingDied(mTestComponentName);
+        delay = REBIND_RETRY.getStartDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         verify(mMmTelCompatAdapterSpy).onFeatureRemoved();
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL));
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 113829f..adfc4a3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
@@ -634,6 +634,8 @@
 
         conn.onServiceDisconnected(mTestComponentName);
 
+        long delay = mTestImsServiceController.getRebindDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
@@ -660,6 +662,8 @@
 
         conn.onServiceDisconnected(mTestComponentName);
 
+        long delay = mTestImsServiceController.getRebindDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
@@ -762,6 +766,8 @@
 
         conn.onBindingDied(null /*null*/);
 
+        long delay = REBIND_RETRY.getStartDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         verify(mMockContext).unbindService(eq(conn));
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
@@ -787,6 +793,8 @@
         slotIdToSubIdMap.put(SLOT_0, SUB_2);
         bindAndNullServiceError(testFeatures, slotIdToSubIdMap.clone());
 
+        long delay = mTestImsServiceController.getRebindDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         verify(mMockCallbacks, never()).imsServiceFeatureCreated(anyInt(), anyInt(),
                 eq(mTestImsServiceController));
         verify(mMockCallbacks).imsServiceBindPermanentError(eq(mTestComponentName));
@@ -1304,7 +1312,7 @@
 
         conn.onBindingDied(null /*null*/);
 
-        long delay = mTestImsServiceController.getRebindDelay();
+        long delay = REBIND_RETRY.getStartDelay();
         waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         // The service should autobind after rebind event occurs
         verify(mMockContext, times(2)).bindService(any(), any(), anyInt());
@@ -1330,7 +1338,7 @@
         // null binding should be ignored in this case.
         conn.onNullBinding(null);
 
-        long delay = mTestImsServiceController.getRebindDelay();
+        long delay = REBIND_RETRY.getStartDelay();
         waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         // The service should autobind after rebind event occurs
         verify(mMockContext, times(2)).bindService(any(), any(), anyInt());
@@ -1398,10 +1406,11 @@
         slotIdToSubIdMap.put(SLOT_0, SUB_2);
         ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
         conn.onBindingDied(null /*null*/);
+
+        long delay = REBIND_RETRY.getStartDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap.clone());
 
-        long delay = mTestImsServiceController.getRebindDelay();
-        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         // Should only see two binds, not three from the auto rebind that occurs.
         verify(mMockContext, times(2)).bindService(any(), any(), anyInt());
     }
@@ -1481,6 +1490,9 @@
         IImsServiceController.Stub controllerStub = mock(IImsServiceController.Stub.class);
         when(controllerStub.queryLocalInterface(any())).thenReturn(mMockServiceControllerBinder);
         connection.onServiceConnected(mTestComponentName, controllerStub);
+
+        long delay = mTestImsServiceController.getRebindDelay();
+        waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
         return connection;
     }
 
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..c6b0fa1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
@@ -21,6 +21,8 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
 import android.testing.TestableLooper;
 
 import androidx.test.InstrumentationRegistry;
@@ -29,6 +31,7 @@
 
 import org.mockito.MockitoAnnotations;
 
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -38,6 +41,22 @@
  * Helper class to load Mockito Resources into a test.
  */
 public class ImsTestBase {
+    private static final Field MESSAGE_QUEUE_FIELD;
+    private static final Field MESSAGE_WHEN_FIELD;
+    private static final Field MESSAGE_NEXT_FIELD;
+
+    static {
+        try {
+            MESSAGE_QUEUE_FIELD = MessageQueue.class.getDeclaredField("mMessages");
+            MESSAGE_QUEUE_FIELD.setAccessible(true);
+            MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
+            MESSAGE_WHEN_FIELD.setAccessible(true);
+            MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
+            MESSAGE_NEXT_FIELD.setAccessible(true);
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException("Failed to initialize TelephonyTest", e);
+        }
+    }
 
     protected Context mContext;
     protected List<TestableLooper> mTestableLoopers = new ArrayList<>();
@@ -112,6 +131,52 @@
     }
 
     /**
+     * @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
@@ -123,4 +188,28 @@
         }
         return true;
     }
+
+    /**
+     * Effectively moves time forward by reducing the time of all messages
+     * for all monitored TestableLoopers
+     * @param milliSeconds number of milliseconds to move time forward by
+     */
+    public void moveTimeForward(long milliSeconds) {
+        for (TestableLooper looper : mTestableLoopers) {
+            MessageQueue queue = looper.getLooper().getQueue();
+            try {
+                Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
+                while (msg != null) {
+                    long updatedWhen = msg.getWhen() - milliSeconds;
+                    if (updatedWhen < 0) {
+                        updatedWhen = 0;
+                    }
+                    MESSAGE_WHEN_FIELD.set(msg, updatedWhen);
+                    msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
+                }
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException("Access failed in TelephonyTest", e);
+            }
+        }
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallInfoTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallInfoTrackerTest.java
new file mode 100644
index 0000000..e3fc6d3
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallInfoTrackerTest.java
@@ -0,0 +1,436 @@
+/*
+ * 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.imsphone;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+
+import static junit.framework.Assert.assertNotNull;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+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.telephony.ServiceState;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.Call;
+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.ArgumentCaptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ImsCallInfoTrackerTest extends TelephonyTest {
+
+    private ImsCallInfoTracker mImsCallInfoTracker;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+
+        mImsCallInfoTracker = new ImsCallInfoTracker(mImsPhone);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDialingNormalCall() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.DIALING, false);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        ImsCallInfo info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.DIALING, info.getCallState());
+        assertFalse(info.isIncoming());
+        assertFalse(info.isEmergencyCall());
+        assertEquals(EUTRAN, info.getCallRadioTech());
+        assertFalse(info.isHeldByRemote());
+    }
+
+    @Test
+    public void testDialingEmergencyCall() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.DIALING, true);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        ImsCallInfo info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.DIALING, info.getCallState());
+        assertFalse(info.isIncoming());
+        assertTrue(info.isEmergencyCall());
+        assertEquals(EUTRAN, info.getCallRadioTech());
+        assertFalse(info.isHeldByRemote());
+    }
+
+    @Test
+    public void testIncomingCall() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.INCOMING, false);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        ImsCallInfo info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.INCOMING, info.getCallState());
+        assertTrue(info.isIncoming());
+        assertFalse(info.isEmergencyCall());
+        assertEquals(EUTRAN, info.getCallRadioTech());
+        assertFalse(info.isHeldByRemote());
+
+        // Answer the call
+        doReturn(Call.State.ACTIVE).when(c).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c);
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.ACTIVE, info.getCallState());
+
+        // Hold the call
+        doReturn(Call.State.HOLDING).when(c).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c);
+
+        verify(mImsPhone, times(3)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.HOLDING, info.getCallState());
+
+        // Disconnect the call
+        doReturn(Call.State.DISCONNECTING).when(c).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c);
+
+        verify(mImsPhone, times(4)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.DISCONNECTING, info.getCallState());
+
+        // Call disconnected
+        doReturn(Call.State.DISCONNECTED).when(c).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c);
+
+        verify(mImsPhone, times(5)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.IDLE, info.getCallState());
+    }
+
+    @Test
+    public void testMultiCalls() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c1 = getConnection(Call.State.INCOMING, false);
+        mImsCallInfoTracker.addImsCallStatus(c1);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        doReturn(Call.State.ACTIVE).when(c1).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c1);
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        // 1st call
+        ImsCallInfo info1 = imsCallInfos.get(0);
+
+        assertNotNull(info1);
+        assertEquals(1, info1.getIndex());
+        assertEquals(Call.State.ACTIVE, info1.getCallState());
+
+        // Add 2nd WAITING call
+        ImsPhoneConnection c2 = getConnection(Call.State.WAITING, false);
+        mImsCallInfoTracker.addImsCallStatus(c2);
+
+        verify(mImsPhone, times(3)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(2, imsCallInfos.size());
+
+        // 1st call
+        info1 = imsCallInfos.get(0);
+
+        assertNotNull(info1);
+        assertEquals(1, info1.getIndex());
+        assertEquals(Call.State.ACTIVE, info1.getCallState());
+
+        // 2nd call
+        ImsCallInfo info2 = imsCallInfos.get(1);
+
+        assertNotNull(info2);
+        assertEquals(2, info2.getIndex());
+        assertEquals(Call.State.WAITING, info2.getCallState());
+        assertTrue(info2.isIncoming());
+
+        // Disconnect 1st call
+        doReturn(Call.State.DISCONNECTED).when(c1).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c1);
+
+        verify(mImsPhone, times(4)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(2, imsCallInfos.size());
+
+        // 1st call
+        info1 = imsCallInfos.get(0);
+
+        assertNotNull(info1);
+        assertEquals(1, info1.getIndex());
+        assertEquals(Call.State.IDLE, info1.getCallState());
+
+        // 2nd call
+        info2 = imsCallInfos.get(1);
+
+        assertNotNull(info2);
+        assertEquals(2, info2.getIndex());
+        assertEquals(Call.State.WAITING, info2.getCallState());
+
+        // Answer WAITING call
+        doReturn(Call.State.ACTIVE).when(c2).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c2);
+
+        verify(mImsPhone, times(5)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        // 2nd call
+        info2 = imsCallInfos.get(0);
+
+        assertNotNull(info2);
+        assertEquals(2, info2.getIndex());
+        assertEquals(Call.State.ACTIVE, info2.getCallState());
+    }
+
+    @Test
+    public void testHeldByRemote() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.INCOMING, false);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        doReturn(Call.State.ACTIVE).when(c).getState();
+        mImsCallInfoTracker.updateImsCallStatus(c);
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(captor.capture(), any());
+
+        // Hold received
+        mImsCallInfoTracker.updateImsCallStatus(c, true, false);
+
+        verify(mImsPhone, times(3)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertEquals(1, imsCallInfos.size());
+
+        ImsCallInfo info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.ACTIVE, info.getCallState());
+        assertTrue(info.isHeldByRemote());
+
+        // Resume received
+        mImsCallInfoTracker.updateImsCallStatus(c, false, true);
+
+        verify(mImsPhone, times(4)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertEquals(1, imsCallInfos.size());
+
+        info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.ACTIVE, info.getCallState());
+        assertFalse(info.isHeldByRemote());
+    }
+
+    @Test
+    public void testSortImsCallInfo() throws Exception {
+        List<ImsCallInfo> imsCallInfos = new ArrayList<>();
+        imsCallInfos.add(new ImsCallInfo(2));
+        imsCallInfos.add(new ImsCallInfo(1));
+
+        assertEquals(2, imsCallInfos.get(0).getIndex());
+        assertEquals(1, imsCallInfos.get(1).getIndex());
+
+        ImsCallInfoTracker.sort(imsCallInfos);
+
+        assertEquals(1, imsCallInfos.get(0).getIndex());
+        assertEquals(2, imsCallInfos.get(1).getIndex());
+    }
+
+    @Test
+    public void testSrvccCompleted() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.DIALING, false);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        mImsCallInfoTracker.notifySrvccCompleted();
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(0, imsCallInfos.size());
+    }
+
+    @Test
+    public void testClearAllOrphanedConnections() throws Exception {
+        ArgumentCaptor<List<ImsCallInfo>> captor = ArgumentCaptor.forClass(List.class);
+
+        ImsPhoneConnection c = getConnection(Call.State.DIALING, false);
+        mImsCallInfoTracker.addImsCallStatus(c);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(captor.capture(), any());
+
+        List<ImsCallInfo> imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        mImsCallInfoTracker.clearAllOrphanedConnections();
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(captor.capture(), any());
+
+        imsCallInfos = captor.getValue();
+
+        assertNotNull(imsCallInfos);
+        assertEquals(1, imsCallInfos.size());
+
+        ImsCallInfo info = imsCallInfos.get(0);
+
+        assertNotNull(info);
+        assertEquals(1, info.getIndex());
+        assertEquals(Call.State.IDLE, info.getCallState());
+    }
+
+    private ImsPhoneConnection getConnection(Call.State state, boolean isEmergency) {
+        ImsPhoneConnection c = mock(ImsPhoneConnection.class);
+        doReturn(isEmergency).when(c).isEmergencyCall();
+        doReturn(state).when(c).getState();
+        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(c).getCallRadioTech();
+        switch (state) {
+            case INCOMING:
+            case WAITING:
+                doReturn(true).when(c).isIncoming();
+                break;
+            default:
+                doReturn(false).when(c).isIncoming();
+        }
+
+        return c;
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java
new file mode 100644
index 0000000..7d6557d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2023 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.imsphone;
+
+import static android.telephony.CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA;
+import static android.telephony.CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA;
+import static android.telephony.CarrierConfigManager.Ims.KEY_NR_SA_DISABLE_POLICY_INT;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_NONE;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED;
+import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.telephony.CarrierConfigManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.ArraySet;
+
+import com.android.internal.telephony.Call;
+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.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+import java.util.Set;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public final class ImsNrSaModeHandlerTest extends TelephonyTest{
+    @Captor ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener>
+            mCarrierConfigChangeListenerCaptor;
+    @Captor ArgumentCaptor<Handler> mPreciseCallStateHandlerCaptor;
+
+    private ImsNrSaModeHandler mTestImsNrSaModeHandler;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+    private Handler mPreciseCallStateHandler;
+
+    @Mock private ImsPhoneCall mForegroundCall;
+    @Mock private ImsPhoneCall mBackgroundCall;
+    private Call.State mActiveState = ImsPhoneCall.State.ACTIVE;
+    private Call.State mIdleState = ImsPhoneCall.State.IDLE;
+
+    private int mAnyInt = 0;
+    private final Set<String> mFeatureTags =
+            new ArraySet<String>(Arrays.asList(ImsNrSaModeHandler.MMTEL_FEATURE_TAG));
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+
+        mTestImsNrSaModeHandler = new ImsNrSaModeHandler(mImsPhone, mTestableLooper.getLooper());
+
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(
+                any(), mCarrierConfigChangeListenerCaptor.capture());
+
+        mCarrierConfigChangeListener = mCarrierConfigChangeListenerCaptor.getValue();
+
+        doReturn(mAnyInt).when(mImsPhone).getSubId();
+        doReturn(mContextFixture.getCarrierConfigBundle()).when(mCarrierConfigManager)
+                .getConfigForSubId(anyInt(), any());
+        doReturn(mPhone).when(mImsPhone).getDefaultPhone();
+
+        doReturn(mForegroundCall).when(mImsPhone).getForegroundCall();
+        doReturn(mBackgroundCall).when(mImsPhone).getBackgroundCall();
+
+        doReturn(mActiveState).when(mForegroundCall).getState();
+        doReturn(mActiveState).when(mBackgroundCall).getState();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTestImsNrSaModeHandler = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testTearDown() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(
+                mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
+        mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setNrSaDisabledForWfc(true);
+
+        mTestImsNrSaModeHandler.tearDown();
+
+        verify(mCarrierConfigManager).unregisterCarrierConfigChangeListener(any());
+        verify(mImsPhone).unregisterForPreciseCallStateChanged(mPreciseCallStateHandler);
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnImsRegisteredWithSaDisablePolicyNone() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_NONE);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+    }
+
+    @Test
+    public void testOnImsRegisteredWithSaDisablePolicyWfcEstablished() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(any(), anyInt(), any());
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnImsRegisteredWithSaDisablePolicyWfcEstablishedWithVonrDisabled() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT,
+                NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(any(), anyInt(), any());
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+        mSimulatedCommands.setVonrEnabled(true);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+        processAllMessages();
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+        mSimulatedCommands.setVonrEnabled(false);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+        processAllMessages();
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+        mSimulatedCommands.setVonrEnabled(false);
+
+        mFeatureTags.remove(ImsNrSaModeHandler.MMTEL_FEATURE_TAG);
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+        processAllMessages();
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+        mSimulatedCommands.setVonrEnabled(false);
+
+        mFeatureTags.add(ImsNrSaModeHandler.MMTEL_FEATURE_TAG);
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+        processAllMessages();
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnImsRegisteredWithSaDisablePolicyVowifiRegistered() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnImsUnregisteredDoNothingIfNotVowifiRegNoti() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_NONE);
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+    }
+
+    @Test
+    public void testOnImsUnregisteredWithSaDisablePolicyVowifiRegistered() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_IWLAN);
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_NONE);
+
+        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnPreciseCallStateChangedWithSaDisablePolicyWfcEstablished() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(
+                mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
+        mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+
+        assertTrue(mTestImsNrSaModeHandler.isImsCallOngoing());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+
+        doReturn(mActiveState).when(mForegroundCall).getState();
+        doReturn(mActiveState).when(mBackgroundCall).getState();
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+
+        assertTrue(mTestImsNrSaModeHandler.isImsCallOngoing());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setImsCallStatus(false);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+
+        doReturn(mIdleState).when(mForegroundCall).getState();
+        doReturn(mIdleState).when(mBackgroundCall).getState();
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+
+        assertFalse(mTestImsNrSaModeHandler.isImsCallOngoing());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setImsCallStatus(true);
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+
+        assertFalse(mTestImsNrSaModeHandler.isImsCallOngoing());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testUnregisterForPreciseCallStateChangeIfNeeded() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(
+                mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
+        mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
+
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        verify(mImsPhone).unregisterForPreciseCallStateChanged(mPreciseCallStateHandler);
+    }
+
+    @Test
+    public void testNrSaModeIsNotHandledWhenNotSupported() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_NSA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mSimulatedCommands.setN1ModeEnabled(false, null);
+        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
+
+        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+    }
+}
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..c4bb864 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
@@ -27,6 +28,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -258,6 +261,51 @@
 
     @Test
     @SmallTest
+    public void testGetCallSessionId() {
+        doReturn(mImsCall).when(mConnection1).getImsCall();
+        ImsCallSession imsForegroundCallSession = mock(ImsCallSession.class);
+        doReturn(imsForegroundCallSession).when(mImsCall).getSession();
+        doReturn("1").when(imsForegroundCallSession).getCallId();
+        mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
+        assertEquals("1", mImsCallUT.getCallSessionId());
+        doReturn(null).when(mImsCall).getSession();
+        assertNull(mImsCallUT.getCallSessionId());
+        doReturn(null).when(mConnection1).getImsCall();
+        assertNull(mImsCallUT.getCallSessionId());
+        mImsCallUT.detach(mConnection1);
+        assertNull(mImsCallUT.getCallSessionId());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetServiceType() {
+        doReturn(mImsCall).when(mConnection1).getImsCall();
+        mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
+        doReturn(false).when(mConnection1).isEmergencyCall();
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NORMAL, mImsCallUT.getServiceType());
+        doReturn(true).when(mConnection1).isEmergencyCall();
+        assertEquals(ImsCallProfile.SERVICE_TYPE_EMERGENCY, mImsCallUT.getServiceType());
+        mImsCallUT.detach(mConnection1);
+        assertEquals(ImsCallProfile.SERVICE_TYPE_NONE, mImsCallUT.getServiceType());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetCallType() {
+        doReturn(mImsCall).when(mConnection1).getImsCall();
+        mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
+        doReturn(false).when(mImsCall).isVideoCall();
+        assertEquals(ImsCallProfile.CALL_TYPE_VOICE, mImsCallUT.getCallType());
+        doReturn(true).when(mImsCall).isVideoCall();
+        assertEquals(ImsCallProfile.CALL_TYPE_VT, mImsCallUT.getCallType());
+        doReturn(null).when(mConnection1).getImsCall();
+        assertEquals(ImsCallProfile.CALL_TYPE_NONE, mImsCallUT.getCallType());
+        mImsCallUT.detach(mConnection1);
+        assertEquals(ImsCallProfile.CALL_TYPE_NONE, mImsCallUT.getCallType());
+    }
+
+    @Test
+    @SmallTest
     public void testSetMute() {
         doReturn(mImsCall).when(mConnection1).getImsCall();
         mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
@@ -269,4 +317,24 @@
             fail("Exception unexpected");
         }
     }
+
+    @Test
+    public void testMaybeClearRemotelyHeldStatus() {
+        mImsCallUT.attach(mConnection1, Call.State.ACTIVE);
+        when(mConnection1.isHeldByRemote()).thenReturn(true);
+        mImsCallUT.maybeClearRemotelyHeldStatus();
+        verify(mConnection1, times(1)).setRemotelyUnheld();
+
+        mImsCallUT.attach(mConnection2, Call.State.ACTIVE);
+        when(mConnection2.isHeldByRemote()).thenReturn(true);
+        mImsCallUT.maybeClearRemotelyHeldStatus();
+        verify(mConnection1, times(2)).setRemotelyUnheld();
+        verify(mConnection2, times(1)).setRemotelyUnheld();
+
+        when(mConnection1.isHeldByRemote()).thenReturn(false);
+        when(mConnection2.isHeldByRemote()).thenReturn(false);
+        mImsCallUT.maybeClearRemotelyHeldStatus();
+        verify(mConnection1, times(2)).setRemotelyUnheld();
+        verify(mConnection2, times(1)).setRemotelyUnheld();
+    }
 }
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 4f1bdac..d0a2094 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -21,6 +21,23 @@
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
+import static android.telephony.CarrierConfigManager.ImsVoice.ALERTING_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.BASIC_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.MIDCALL_SRVCC_SUPPORT;
+import static android.telephony.CarrierConfigManager.ImsVoice.PREALERTING_SRVCC_SUPPORT;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ACTIVE;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_ALERTING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING;
+import static android.telephony.PreciseCallState.PRECISE_CALL_STATE_INCOMING_SETUP;
+import static android.telephony.TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED;
+import static android.telephony.TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED;
+import static android.telephony.TelephonyManager.SRVCC_STATE_HANDOVER_FAILED;
+import static android.telephony.TelephonyManager.SRVCC_STATE_HANDOVER_STARTED;
+import static android.telephony.emergency.EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE;
+import static android.telephony.ims.ImsStreamMediaProfile.DIRECTION_INACTIVE;
+import static android.telephony.ims.ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
+import static android.telephony.ims.feature.MmTelFeature.IMS_TRAFFIC_DIRECTION_INCOMING;
+import static android.telephony.ims.feature.MmTelFeature.IMS_TRAFFIC_DIRECTION_OUTGOING;
 
 import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
 
@@ -53,22 +70,24 @@
 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;
 import android.net.NetworkStats.Entry;
+import android.net.Uri;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.os.Bundle;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.telecom.VideoProfile;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsCallSession;
 import android.telephony.ims.ImsConferenceState;
@@ -76,6 +95,9 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.RtpHeaderExtensionType;
+import android.telephony.ims.SrvccCall;
+import android.telephony.ims.aidl.IImsTrafficSessionCallback;
+import android.telephony.ims.aidl.ISrvccStartedCallback;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -91,16 +113,21 @@
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsException;
 import com.android.ims.ImsManager;
+import com.android.ims.internal.ConferenceParticipant;
 import com.android.ims.internal.IImsCallSession;
 import com.android.internal.telephony.Call;
 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.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.SrvccConnection;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.d2d.RtpTransport;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -109,9 +136,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
 
@@ -125,6 +155,7 @@
     private ImsCall.Listener mImsCallListener;
     private ImsCall mImsCall;
     private ImsCall mSecondImsCall;
+    private ISrvccStartedCallback mSrvccStartedCallback;
     private BroadcastReceiver mBroadcastReceiver;
     private Bundle mBundle = new Bundle();
     private static final int SUB_0 = 0;
@@ -140,6 +171,9 @@
     private ImsPhoneConnection mImsPhoneConnection;
     private INetworkStatsProviderCallback mVtDataUsageProviderCb;
     private ImsPhoneCallTracker.ConnectorFactory mConnectorFactory;
+    private CommandsInterface mMockCi;
+    private DomainSelectionResolver mDomainSelectionResolver;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private final Executor mExecutor = Runnable::run;
 
@@ -200,11 +234,16 @@
         mSecondImsCall = spy(new ImsCall(mContext, mImsCallProfile));
         mImsPhoneConnectionListener = mock(ImsPhoneConnection.Listener.class);
         mImsPhoneConnection = mock(ImsPhoneConnection.class);
+        mMockCi = mock(CommandsInterface.class);
         imsCallMocking(mImsCall);
         imsCallMocking(mSecondImsCall);
         doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
         doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt());
         mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
+        mDomainSelectionResolver = mock(DomainSelectionResolver.class);
+
+        doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1).build())
+                .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         doAnswer(invocation -> {
             mMmTelListener = (MmTelFeature.Listener) invocation.getArguments()[0];
@@ -240,7 +279,16 @@
             return mMockConnector;
         }).when(mConnectorFactory).create(any(), anyInt(), anyString(), any(), any());
 
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+
+        // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mCTUT = new ImsPhoneCallTracker(mImsPhone, mConnectorFactory, Runnable::run);
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
         mCTUT.setDataEnabled(true);
 
         final ArgumentCaptor<VtDataUsageProvider> vtDataUsageProviderCaptor =
@@ -347,16 +395,11 @@
     @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();
@@ -372,7 +415,6 @@
     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);
 
@@ -399,7 +441,6 @@
         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
@@ -419,7 +460,6 @@
     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);
 
@@ -440,7 +480,6 @@
         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
@@ -464,7 +503,6 @@
     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);
 
@@ -532,7 +570,7 @@
         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
         assertFalse(mCTUT.mRingingCall.isRinging());
         // mock a MT call
-        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
         verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any());
         verify(mImsPhone, times(1)).notifyIncomingRing();
         assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
@@ -684,7 +722,7 @@
             ex.printStackTrace();
             Assert.fail("unexpected exception thrown" + ex.getMessage());
         }
-        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
 
         verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any());
         verify(mImsPhone, times(2)).notifyIncomingRing();
@@ -722,7 +760,7 @@
             ex.printStackTrace();
             Assert.fail("unexpected exception thrown" + ex.getMessage());
         }
-        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
 
         verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any());
         verify(mImsPhone, times(2)).notifyIncomingRing();
@@ -914,7 +952,7 @@
         try {
             doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
                     any(ImsCall.Listener.class));
-            mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+            mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
             mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
         } catch (Exception ex) {
             ex.printStackTrace();
@@ -1387,6 +1425,43 @@
 
     @Test
     @SmallTest
+    public void testAutoRejectedCauses() {
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_CALL_ON_OTHER_SUB, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_E911_CALL, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_CALL_SETUP, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_MAX_CALL_LIMIT_REACHED, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_CALL_TRANSFER, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_CONFERENCE_CALL, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_HANDOVER, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_REJECT_ONGOING_CALL_UPGRADE, 0),
+                Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_BAD_REQUEST, 0), Call.State.INCOMING));
+        assertEquals(DisconnectCause.INCOMING_AUTO_REJECTED, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_BAD_REQUEST, 0), Call.State.WAITING));
+        assertEquals(DisconnectCause.SERVER_ERROR, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_BAD_REQUEST, 0), Call.State.DIALING));
+        assertEquals(DisconnectCause.SERVER_ERROR, mCTUT.getDisconnectCauseFromReasonInfo(
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_BAD_REQUEST, 0), Call.State.ALERTING));
+    }
+
+    @Test
+    @SmallTest
     public void testImsAlternateEmergencyDisconnect() {
         assertEquals(DisconnectCause.IMS_SIP_ALTERNATE_EMERGENCY_CALL,
                 mCTUT.getDisconnectCauseFromReasonInfo(
@@ -1429,6 +1504,45 @@
         verify(mImsPhone, never()).startOnHoldTone(nullable(Connection.class));
     }
 
+    @Test
+    @SmallTest
+    public void testSendAnbrQuery() throws Exception {
+        logd("ImsPhoneCallTracker testSendAnbrQuery");
+
+        replaceInstance(Phone.class, "mCi", mPhone, mMockCi);
+        //establish a MT call
+        testImsMTCallAccept();
+
+        ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection();
+        ImsCall imsCall = connection.getImsCall();
+        imsCall.getImsCallSessionListenerProxy().callSessionSendAnbrQuery(1, 1, 24400);
+
+        verify(mMockCi, times(1)).sendAnbrQuery(eq(1), eq(1), eq(24400), any());
+
+        // Disconnecting and then Disconnected
+        mCTUT.hangup(connection);
+        mImsCallListener.onCallTerminated(imsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED, 0));
+    }
+
+    @Test
+    @SmallTest
+    public void testTriggerNotifyAnbr() throws Exception {
+        logd("ImsPhoneCallTracker testTriggerNotifyAnbr");
+
+        testImsMTCallAccept();
+        ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection();
+        ImsCall imsCall = connection.getImsCall();
+
+        mCTUT.triggerNotifyAnbr(1, 1, 24400);
+        verify(mImsCall, times(1)).callSessionNotifyAnbr(eq(1), eq(1), eq(24400));
+
+        // Disconnecting and then Disconnected
+        mCTUT.hangup(connection);
+        mImsCallListener.onCallTerminated(imsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED, 0));
+    }
+
     /**
      * Verifies that a remote hold tone is played when the call is remotely held and the media
      * direction is inactive (i.e. the audio stream is not playing, so we should play the tone).
@@ -1579,7 +1693,9 @@
             }
         });
         ImsCall call = connection.getImsCall();
-        call.getListener().onCallMerged(call, null, false);
+        call.getListener().onCallTerminated(
+                call, new ImsReasonInfo(
+                        ImsReasonInfo.CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE, 0));
         assertTrue(result[0]);
     }
 
@@ -1689,7 +1805,7 @@
         assertTrue(mCTUT.mForegroundCall.isRingbackTonePlaying());
 
         // Move the connection to the handover state.
-        mCTUT.notifySrvccState(Call.SrvccState.COMPLETED);
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
 
         assertFalse(mCTUT.mForegroundCall.isRingbackTonePlaying());
     }
@@ -1720,7 +1836,7 @@
         }
 
         // Move the connection to the handover state.
-        mCTUT.notifySrvccState(Call.SrvccState.COMPLETED);
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
         // Ensure we are no longer tracking hold.
         assertFalse(mCTUT.isHoldOrSwapInProgress());
     }
@@ -1732,7 +1848,7 @@
         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
         assertFalse(mCTUT.mRingingCall.isRinging());
         // mock a MT call
-        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
         verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any());
         verify(mImsPhone, times(1)).notifyIncomingRing();
         assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
@@ -1743,7 +1859,7 @@
         connection.addListener(mImsPhoneConnectionListener);
 
         // Move the connection to the handover state.
-        mCTUT.notifySrvccState(Call.SrvccState.COMPLETED);
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
         assertEquals(1, mCTUT.mHandoverCall.getConnections().size());
 
         // No need to go through all the rigamarole of the mocked termination we normally do; we
@@ -1770,7 +1886,7 @@
         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
         assertFalse(mCTUT.mRingingCall.isRinging());
         // mock a MT call
-        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
+        mMmTelListener.onIncomingCall(mock(IImsCallSession.class), null, Bundle.EMPTY);
         verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any());
         verify(mImsPhone, times(1)).notifyIncomingRing();
         assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
@@ -1781,7 +1897,7 @@
         connection.addListener(mImsPhoneConnectionListener);
 
         // Move the connection to the handover state.
-        mCTUT.notifySrvccState(Call.SrvccState.COMPLETED);
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
         assertEquals(1, mCTUT.mHandoverCall.getConnections().size());
 
         // Make sure the tracker states it's idle.
@@ -1797,7 +1913,6 @@
     @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);
@@ -1828,7 +1943,6 @@
     @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);
@@ -1858,7 +1972,6 @@
     @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;
@@ -1892,7 +2005,7 @@
         startOutgoingCall();
 
         // Move the connection to the handover state.
-        mCTUT.notifySrvccState(Call.SrvccState.COMPLETED);
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
 
         try {
             // When trigger CallSessionUpdated after Srvcc completes, checking no exception.
@@ -1926,11 +2039,611 @@
         ImsPhoneConnection connection2 = placeCall();
     }
 
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoNotSupported() throws Exception {
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection activeMO = getImsPhoneConnection(Call.State.ACTIVE, "1234", false);
+        ImsPhoneConnection heldMT = getImsPhoneConnection(Call.State.HOLDING, "5678", true);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(activeMO);
+        connections.add(heldMT);
+
+        ImsCallProfile activeProfile = getImsCallProfileForSrvccSync("activeCall", activeMO, false);
+        ImsCallProfile heldProfile = getImsCallProfileForSrvccSync("heldCall", heldMT, false);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+
+        // active call
+        SrvccCall srvccProfile = new SrvccCall(
+                "activeCall", PRECISE_CALL_STATE_ACTIVE, activeProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {});
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+    }
+
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoBasicSrvcc() throws Exception {
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection activeMO = getImsPhoneConnection(Call.State.ACTIVE, "1234", false);
+        ImsPhoneConnection heldMT = getImsPhoneConnection(Call.State.HOLDING, "5678", true);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(activeMO);
+        connections.add(heldMT);
+
+        ImsCallProfile activeProfile = getImsCallProfileForSrvccSync("activeCall", activeMO, false);
+        ImsCallProfile heldProfile = getImsCallProfileForSrvccSync("heldCall", heldMT, false);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        // active call
+        SrvccCall srvccProfile = new SrvccCall(
+                "activeCall", PRECISE_CALL_STATE_ACTIVE, activeProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.ACTIVE);
+        assertEquals("1234", srvccConnections[0].getNumber());
+    }
+
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoMoAlerting() throws Exception {
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection alertingMO = getImsPhoneConnection(Call.State.ALERTING, "1234", false);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(alertingMO);
+
+        ImsCallProfile alertingProfile = getImsCallProfileForSrvccSync("alertingCall", null, true);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        // alerting call, with local ringback tone
+        SrvccCall srvccProfile = new SrvccCall(
+                "alertingCall", PRECISE_CALL_STATE_ALERTING, alertingProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+
+        bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                        ALERTING_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.ALERTING);
+        assertTrue(srvccConnections[0].getRingbackToneType() == SrvccConnection.TONE_LOCAL);
+
+        profiles.clear();
+
+        // alerting call, with network ringback tone
+        alertingProfile = getImsCallProfileForSrvccSync("alertingCall", null, false);
+
+        srvccProfile = new SrvccCall(
+                "alertingCall", PRECISE_CALL_STATE_ALERTING, alertingProfile);
+        profiles.add(srvccProfile);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.ALERTING);
+        assertTrue(srvccConnections[0].getRingbackToneType() == SrvccConnection.TONE_NETWORK);
+    }
+
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoMtAlerting() throws Exception {
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection alertingMT = getImsPhoneConnection(Call.State.INCOMING, "1234", false);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(alertingMT);
+
+        ImsCallProfile incomingProfile =
+                getImsCallProfileForSrvccSync("incomingCall", alertingMT, false);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        SrvccCall srvccProfile = new SrvccCall(
+                "incomingCall", PRECISE_CALL_STATE_INCOMING, incomingProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+
+        bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        ALERTING_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.INCOMING);
+    }
+
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoMtPreAlerting() throws Exception {
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        ImsCallProfile incomingProfile = getImsCallProfileForSrvccSync("incomingCall", null, false);
+
+        SrvccCall srvccProfile = new SrvccCall(
+                "incomingCallSetup", PRECISE_CALL_STATE_INCOMING_SETUP, incomingProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                        ALERTING_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+
+        bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                        ALERTING_SRVCC_SUPPORT,
+                        PREALERTING_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.INCOMING);
+        assertTrue(srvccConnections[0].getSubState() == SrvccConnection.SUBSTATE_PREALERTING);
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifySrvccStateStarted() throws Exception {
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        mSrvccStartedCallback = null;
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                mSrvccStartedCallback = (ISrvccStartedCallback) invocation.getArguments()[0];
+                return null;
+            }
+        }).when(mImsManager).notifySrvccStarted(any(ISrvccStartedCallback.class));
+
+        verify(mImsManager, times(0)).notifySrvccStarted(any());
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_STARTED);
+        verify(mImsManager, times(1)).notifySrvccStarted(any());
+        assertNotNull(mSrvccStartedCallback);
+
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection activeMO = getImsPhoneConnection(Call.State.ACTIVE, "1234", false);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(activeMO);
+
+        ImsCallProfile activeProfile = getImsCallProfileForSrvccSync("activeCall", activeMO, false);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        // active call
+        SrvccCall srvccProfile = new SrvccCall(
+                "activeCall", PRECISE_CALL_STATE_ACTIVE, activeProfile);
+        profiles.add(srvccProfile);
+
+        mSrvccStartedCallback.onSrvccCallNotified(profiles);
+        SrvccConnection[] srvccConnections = mSimulatedCommands.getSrvccConnections();
+
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.ACTIVE);
+        assertEquals("1234", srvccConnections[0].getNumber());
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifySrvccStateFailed() throws Exception {
+        verify(mImsManager, times(0)).notifySrvccFailed();
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_FAILED);
+        verify(mImsManager, times(1)).notifySrvccFailed();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifySrvccStateCanceled() throws Exception {
+        verify(mImsManager, times(0)).notifySrvccCanceled();
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_CANCELED);
+        verify(mImsManager, times(1)).notifySrvccCanceled();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifySrvccStateCompleted() throws Exception {
+        verify(mImsManager, times(0)).notifySrvccCompleted();
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
+        verify(mImsManager, times(1)).notifySrvccCompleted();
+    }
+
+    @Test
+    @SmallTest
+    public void testConvertToSrvccConnectionInfoConferenceCall() throws Exception {
+        // setup ImsPhoneCallTracker's mConnections
+        ImsPhoneConnection activeMO = getImsPhoneConnection(Call.State.ACTIVE, "1234", false);
+
+        ArrayList<ImsPhoneConnection> connections = new ArrayList<ImsPhoneConnection>();
+        replaceInstance(ImsPhoneCallTracker.class, "mConnections", mCTUT, connections);
+        connections.add(activeMO);
+
+        List<ConferenceParticipant> participants = new ArrayList<ConferenceParticipant>();
+        participants.add(new ConferenceParticipant(Uri.parse("tel:1234"), "", null,
+                  android.telecom.Connection.STATE_ACTIVE,
+                  android.telecom.Call.Details.DIRECTION_INCOMING));
+        participants.add(new ConferenceParticipant(Uri.parse("tel:5678"), "", null,
+                  android.telecom.Connection.STATE_ACTIVE,
+                  android.telecom.Call.Details.DIRECTION_OUTGOING));
+
+        ImsCallProfile activeProfile = getImsCallProfileForSrvccSync("activeCall",
+                activeMO, false, participants);
+
+        // setup the response of notifySrvccStarted
+        List<SrvccCall> profiles = new ArrayList<>();
+
+        SrvccConnection[] srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNull(srvccConnections);
+
+        // active call
+        SrvccCall srvccProfile = new SrvccCall(
+                "activeCall", PRECISE_CALL_STATE_ACTIVE, activeProfile);
+        profiles.add(srvccProfile);
+
+        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 1);
+        assertTrue(srvccConnections[0].getState() == Call.State.ACTIVE);
+        assertFalse(srvccConnections[0].isMultiParty());
+        assertEquals("1234", srvccConnections[0].getNumber());
+
+        bundle = mContextFixture.getCarrierConfigBundle();
+        bundle.putIntArray(
+                CarrierConfigManager.ImsVoice.KEY_SRVCC_TYPE_INT_ARRAY,
+                new int[] {
+                        BASIC_SRVCC_SUPPORT,
+                        MIDCALL_SRVCC_SUPPORT
+                });
+        mCTUT.updateCarrierConfigCache(bundle);
+
+        srvccConnections = mCTUT.convertToSrvccConnectionInfo(profiles);
+        assertNotNull(srvccConnections);
+        assertTrue(srvccConnections.length == 2);
+
+        assertTrue(srvccConnections[0].getState() == Call.State.ACTIVE);
+        assertTrue(srvccConnections[0].isMultiParty());
+        assertTrue(srvccConnections[0].isIncoming());
+        assertEquals("1234", srvccConnections[0].getNumber());
+
+        assertTrue(srvccConnections[1].getState() == Call.State.ACTIVE);
+        assertTrue(srvccConnections[1].isMultiParty());
+        assertFalse(srvccConnections[1].isIncoming());
+        assertEquals("5678", srvccConnections[1].getNumber());
+    }
+
+    /**
+     * Verifies that the expected access network tech and IMS features are notified
+     * to ImsPhone when capabilities are changed.
+     */
+    @Test
+    @SmallTest
+    public void testUpdateImsRegistrationInfo() {
+        // LTE is registered.
+        doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(
+                mImsManager).getRegistrationTech();
+
+        // enable Voice and Video
+        MmTelFeature.MmTelCapabilities caps = new MmTelFeature.MmTelCapabilities();
+        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+        mCapabilityCallback.onCapabilitiesStatusChanged(caps);
+        processAllMessages();
+
+        verify(mImsPhone, times(1)).updateImsRegistrationInfo(
+                eq(CommandsInterface.IMS_MMTEL_CAPABILITY_VOICE
+                        | CommandsInterface.IMS_MMTEL_CAPABILITY_VIDEO));
+
+        // enable SMS
+        caps = new MmTelFeature.MmTelCapabilities();
+        caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS);
+        mCapabilityCallback.onCapabilitiesStatusChanged(caps);
+        processAllMessages();
+
+        verify(mImsPhone, times(1)).updateImsRegistrationInfo(
+                eq(CommandsInterface.IMS_MMTEL_CAPABILITY_SMS));
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectionAlternateServiceStartFailed() {
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        startOutgoingCall();
+        ImsPhoneConnection c = mCTUT.mForegroundCall.getFirstConnection();
+        mImsCallProfile.setEmergencyServiceCategories(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+        mImsCallListener.onCallStartFailed(mSecondImsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL, -1));
+        processAllMessages();
+        EmergencyNumber emergencyNumber = c.getEmergencyNumberInfo();
+        assertNotNull(emergencyNumber);
+        assertEquals(EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                emergencyNumber.getEmergencyServiceCategoryBitmask());
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectionAlternateServiceStartFailedNullPendingMO() {
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        startOutgoingCall();
+        ImsPhoneConnection c = mCTUT.mForegroundCall.getFirstConnection();
+        mImsCallListener.onCallProgressing(mSecondImsCall);
+        processAllMessages();
+        mImsCallProfile.setEmergencyServiceCategories(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+        mImsCallListener.onCallStartFailed(mSecondImsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
+                        ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY));
+        processAllMessages();
+        EmergencyNumber emergencyNumber = c.getEmergencyNumberInfo();
+        assertNotNull(emergencyNumber);
+        assertEquals(EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                emergencyNumber.getEmergencyServiceCategoryBitmask());
+    }
+
+    @Test
+    @SmallTest
+    public void testDomainSelectionAlternateServiceTerminated() {
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        startOutgoingCall();
+        ImsPhoneConnection c = mCTUT.mForegroundCall.getFirstConnection();
+        mImsCallProfile.setEmergencyServiceCategories(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+        mImsCallListener.onCallTerminated(mSecondImsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL, -1));
+        processAllMessages();
+        EmergencyNumber emergencyNumber = c.getEmergencyNumberInfo();
+        assertNotNull(emergencyNumber);
+        assertEquals(EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+                emergencyNumber.getEmergencyServiceCategoryBitmask());
+    }
+
+    @Test
+    public void testUpdateImsCallStatusIncoming() throws Exception {
+        // Incoming call
+        ImsPhoneConnection connection = setupRingingConnection();
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        // Disconnect the call
+        mImsCallListener.onCallTerminated(connection.getImsCall(),
+                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0));
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(any(), any());
+    }
+
+    @Test
+    public void testUpdateImsCallStatus() throws Exception {
+        // Dialing
+        ImsPhoneConnection connection = placeCall();
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        // Alerting
+        ImsCall imsCall = connection.getImsCall();
+        imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(),
+                new ImsStreamMediaProfile());
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(any(), any());
+
+        // Active
+        imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(),
+                new ImsCallProfile());
+
+        verify(mImsPhone, times(3)).updateImsCallStatus(any(), any());
+
+        // Held by remote
+        mCTUT.onCallHoldReceived(imsCall);
+
+        verify(mImsPhone, times(4)).updateImsCallStatus(any(), any());
+
+        // Resumed by remote
+        mImsCallListener.onCallResumeReceived(imsCall);
+
+        verify(mImsPhone, times(5)).updateImsCallStatus(any(), any());
+
+        // Disconnecting and then Disconnected
+        mCTUT.hangup(connection);
+        mImsCallListener.onCallTerminated(imsCall,
+                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED, 0));
+
+        verify(mImsPhone, times(7)).updateImsCallStatus(any(), any());
+    }
+
+    @Test
+    public void testUpdateImsCallStatusSrvccCompleted() throws Exception {
+        // Incoming call
+        setupRingingConnection();
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        // no interaction when SRVCC has started, failed, or canceled.
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_STARTED);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_FAILED);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_CANCELED);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+
+        // interaction when SRVCC has completed
+        mCTUT.notifySrvccState(SRVCC_STATE_HANDOVER_COMPLETED);
+
+        verify(mImsPhone, times(2)).updateImsCallStatus(any(), any());
+    }
+
+    @Test
+    public void testClearAllOrphanedConnectionInfo() throws Exception {
+        verify(mImsPhone, times(0)).updateImsCallStatus(any(), any());
+
+        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
+
+        verify(mImsPhone, times(1)).updateImsCallStatus(any(), any());
+    }
+
+    /** Verifies that the request from ImsService is passed to ImsPhone as expected. */
+    @Test
+    @SmallTest
+    public void testStartAndStopImsTrafficSession() {
+        IImsTrafficSessionCallback binder = Mockito.mock(IImsTrafficSessionCallback.class);
+        mMmTelListener.onStartImsTrafficSession(1, MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY,
+                AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                IMS_TRAFFIC_DIRECTION_OUTGOING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(1),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY),
+                eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+
+        mMmTelListener.onStopImsTrafficSession(1);
+        verify(mImsPhone, times(1)).stopImsTraffic(eq(1), any());
+
+        mMmTelListener.onStartImsTrafficSession(2, MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY_SMS,
+                AccessNetworkConstants.AccessNetworkType.IWLAN,
+                IMS_TRAFFIC_DIRECTION_OUTGOING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(2),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_EMERGENCY_SMS),
+                eq(AccessNetworkConstants.AccessNetworkType.IWLAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+
+        mMmTelListener.onStartImsTrafficSession(3, MmTelFeature.IMS_TRAFFIC_TYPE_VOICE,
+                AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                IMS_TRAFFIC_DIRECTION_INCOMING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(3),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_VOICE),
+                eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                eq(IMS_TRAFFIC_DIRECTION_INCOMING), any());
+
+        mMmTelListener.onStartImsTrafficSession(4, MmTelFeature.IMS_TRAFFIC_TYPE_VIDEO,
+                AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                IMS_TRAFFIC_DIRECTION_OUTGOING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(4),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_VIDEO),
+                eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+
+        mMmTelListener.onStartImsTrafficSession(5, MmTelFeature.IMS_TRAFFIC_TYPE_SMS,
+                AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                IMS_TRAFFIC_DIRECTION_OUTGOING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(5),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_SMS),
+                eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+
+        mMmTelListener.onStartImsTrafficSession(6, MmTelFeature.IMS_TRAFFIC_TYPE_REGISTRATION,
+                AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                IMS_TRAFFIC_DIRECTION_OUTGOING, binder);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(6),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_REGISTRATION),
+                eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+
+        mMmTelListener.onModifyImsTrafficSession(6,
+                AccessNetworkConstants.AccessNetworkType.IWLAN);
+        verify(mImsPhone, times(1)).startImsTraffic(eq(6),
+                eq(MmTelFeature.IMS_TRAFFIC_TYPE_REGISTRATION),
+                eq(AccessNetworkConstants.AccessNetworkType.IWLAN),
+                eq(IMS_TRAFFIC_DIRECTION_OUTGOING), any());
+    }
+
     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);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mPhone.getPhoneId(), mPhone.getSubId(),
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
     }
 
@@ -2001,5 +2714,45 @@
         }
         return connection;
     }
+
+    private ImsPhoneConnection getImsPhoneConnection(Call.State state,
+            String number, boolean isIncoming) {
+        ImsPhoneCall call = mock(ImsPhoneCall.class);
+        doReturn(state).when(call).getState();
+
+        ImsPhoneConnection c = mock(ImsPhoneConnection.class);
+        doReturn(state).when(c).getState();
+        doReturn(isIncoming).when(c).isIncoming();
+        doReturn(call).when(c).getCall();
+        doReturn(number).when(c).getAddress();
+
+        return c;
+    }
+
+    private ImsCallProfile getImsCallProfileForSrvccSync(String callId,
+            ImsPhoneConnection c, boolean localTone) {
+        return getImsCallProfileForSrvccSync(callId, c, localTone, null);
+    }
+
+    private ImsCallProfile getImsCallProfileForSrvccSync(String callId,
+            ImsPhoneConnection c, boolean localTone, List<ConferenceParticipant> participants) {
+        ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(0,
+                localTone ? DIRECTION_INACTIVE : DIRECTION_SEND_RECEIVE, 0, 0, 0);
+        ImsCallProfile profile = new ImsCallProfile(0, 0, null, mediaProfile);
+
+        if (c != null) {
+            ImsCallSession session = mock(ImsCallSession.class);
+            doReturn(callId).when(session).getCallId();
+
+            ImsCall imsCall = mock(ImsCall.class);
+            doReturn(profile).when(imsCall).getCallProfile();
+            doReturn(session).when(imsCall).getCallSession();
+            doReturn(participants).when(imsCall).getConferenceParticipants();
+
+            doReturn(imsCall).when(c).getImsCall();
+        }
+
+        return profile;
+    }
 }
 
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..396466c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
@@ -58,6 +58,7 @@
 import com.android.internal.telephony.GsmCdmaCall;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.metrics.VoiceCallSessionStats;
 
@@ -144,7 +145,8 @@
 
         logd("Testing initial state of MO ImsPhoneConnection");
         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
-                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false, false);
+                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false, false,
+                new ImsDialArgs.Builder().build());
         assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getNumberPresentation());
         assertEquals(PhoneConstants.PRESENTATION_ALLOWED, mConnectionUT.getCnapNamePresentation());
         assertEquals("+1 (700).555-41NN,1234", mConnectionUT.getOrigDialString());
@@ -157,7 +159,7 @@
     public void testImsUpdateStateForeGround() {
         // MO Foreground Connection dailing -> active
         mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
-                mForeGroundCall, false, false);
+                mForeGroundCall, false, false, new ImsDialArgs.Builder().build());
         // initially in dialing state
         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
@@ -172,7 +174,7 @@
     public void testUpdateCodec() {
         // MO Foreground Connection dailing -> active
         mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
-                mForeGroundCall, false, false);
+                mForeGroundCall, false, false, new ImsDialArgs.Builder().build());
         doReturn(Call.State.ACTIVE).when(mForeGroundCall).getState();
         assertTrue(mConnectionUT.updateMediaCapabilities(mImsCall));
     }
@@ -195,7 +197,7 @@
     @SmallTest
     public void testImsUpdateStatePendingHold() {
         mConnectionUT = new ImsPhoneConnection(mImsPhone, "+1 (700).555-41NN1234", mImsCT,
-                mForeGroundCall, false, false);
+                mForeGroundCall, false, false, new ImsDialArgs.Builder().build());
         doReturn(true).when(mImsCall).isPendingHold();
         assertFalse(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
         verify(mForeGroundCall, times(0)).update(eq(mConnectionUT), eq(mImsCall),
@@ -240,7 +242,8 @@
     @SmallTest
     public void testPostDialWait() {
         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
-                PhoneNumberUtils.WAIT), mImsCT, mForeGroundCall, false, false);
+                PhoneNumberUtils.WAIT), mImsCT, mForeGroundCall, false, false,
+                new ImsDialArgs.Builder().build());
         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
         doAnswer(new Answer() {
             @Override
@@ -263,7 +266,8 @@
     @MediumTest
     public void testPostDialPause() {
         mConnectionUT = new ImsPhoneConnection(mImsPhone, String.format("+1 (700).555-41NN%c1234",
-                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false, false);
+                PhoneNumberUtils.PAUSE), mImsCT, mForeGroundCall, false, false,
+                new ImsDialArgs.Builder().build());
         doReturn(Call.State.DIALING).when(mForeGroundCall).getState();
         doAnswer(new Answer() {
             @Override
@@ -385,7 +389,7 @@
                 {"12345*00000", "12346", "12346"}};
         for (String[] testAddress : testAddressMappingSet) {
             mConnectionUT = new ImsPhoneConnection(mImsPhone, testAddress[0], mImsCT,
-                    mForeGroundCall, false, false);
+                    mForeGroundCall, false, false, new ImsDialArgs.Builder().build());
             mConnectionUT.setIsIncoming(true);
             mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, testAddress[1]);
             mConnectionUT.updateAddressDisplay(mImsCall);
@@ -403,7 +407,7 @@
         String updateAddress = "6789";
 
         mConnectionUT = new ImsPhoneConnection(mImsPhone, inputAddress, mImsCT, mForeGroundCall,
-                false, false);
+                false, false, new ImsDialArgs.Builder().build());
         mConnectionUT.setIsIncoming(false);
         mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, updateAddress);
         mConnectionUT.updateAddressDisplay(mImsCall);
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 3cbf8bd..d8173a2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java
@@ -29,6 +29,7 @@
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -126,6 +127,7 @@
      * Ensure that when an operation is not supported that the correct message is returned.
      */
     @Test
+    @SmallTest
     public void testOperationNotSupported() {
         mImsPhoneMmiCode = ImsPhoneMmiCode.newNetworkInitiatedUssd(null, true, mImsPhoneUT);
 
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 7750635..b74c8af 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -17,20 +17,30 @@
 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;
 import static android.telephony.CarrierConfigManager.USSD_OVER_IMS_PREFERRED;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_3G;
+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 com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
 import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_SMS;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_VIDEO;
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_VOICE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyChar;
 import static org.mockito.Matchers.anyInt;
@@ -65,6 +75,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.ims.stub.ImsUtImplBase;
@@ -84,8 +95,10 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.imsphone.ImsPhone.SS;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -108,6 +121,7 @@
     private ImsPhoneCall mBackgroundCall;
     private ImsPhoneCall mRingingCall;
     private Handler mTestHandler;
+    private DomainSelectionResolver mDomainSelectionResolver;
     Connection mConnection;
     ImsUtInterface mImsUtInterface;
 
@@ -133,6 +147,9 @@
         mTestHandler = mock(Handler.class);
         mConnection = mock(Connection.class);
         mImsUtInterface = mock(ImsUtInterface.class);
+        mDomainSelectionResolver = mock(DomainSelectionResolver.class);
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
 
         mImsCT.mForegroundCall = mForegroundCall;
         mImsCT.mBackgroundCall = mBackgroundCall;
@@ -176,6 +193,7 @@
     public void tearDown() throws Exception {
         mImsPhoneUT = null;
         mBundle = null;
+        DomainSelectionResolver.setDomainSelectionResolver(null);
         super.tearDown();
     }
 
@@ -629,6 +647,21 @@
 
     @Test
     @SmallTest
+    public void testEcbmWhenDomainSelectionEnabled() {
+        DomainSelectionResolver dsResolver = mock(DomainSelectionResolver.class);
+        doReturn(true).when(dsResolver).isDomainSelectionSupported();
+        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);
+
+        ImsEcbmStateListener imsEcbmStateListener = mImsPhoneUT.getImsEcbmStateListener();
+        imsEcbmStateListener.onECBMEntered();
+        imsEcbmStateListener.onECBMExited();
+
+        verify(mPhone, never()).setIsInEcm(anyBoolean());
+        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
+    }
+
+    @Test
+    @SmallTest
     public void testProcessDisconnectReason() throws Exception {
         // set up CarrierConfig
         mBundle.putStringArray(CarrierConfigManager.KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY,
@@ -734,7 +767,6 @@
     @Test
     @SmallTest
     public void testRoamingToAirplanModeIwlanInService() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -762,7 +794,6 @@
     @Test
     @SmallTest
     public void testRoamingToOutOfService() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -786,83 +817,6 @@
     }
 
     @Test
-    @SmallTest
-    public void testRoamingChangeForLteInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
-        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
-        doReturn(true).when(mPhone).isRadioOn();
-
-        //roaming - data registration only on LTE
-        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
-                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.STATE_IN_SERVICE, true));
-        // Inject the message synchronously instead of waiting for the thread to do it.
-        mImsPhoneUT.handleMessage(m);
-        m.recycle();
-
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), eq(true));
-
-        // not roaming - data registration on LTE
-        m = getServiceStateChangedMessage(getServiceStateDataOnly(
-                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.STATE_IN_SERVICE, false));
-        mImsPhoneUT.handleMessage(m);
-        m.recycle();
-
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), eq(false));
-    }
-
-    @Test
-    @SmallTest
-    public void testDataOnlyRoamingCellToIWlanInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
-        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
-        doReturn(true).when(mPhone).isRadioOn();
-
-        //roaming - data registration only on LTE
-        Message m = getServiceStateChangedMessage(getServiceStateDataOnly(
-                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.STATE_IN_SERVICE, true));
-        // Inject the message synchronously instead of waiting for the thread to do it.
-        mImsPhoneUT.handleMessage(m);
-        m.recycle();
-
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), eq(true));
-
-        // not roaming - data registration onto IWLAN
-        m = getServiceStateChangedMessage(getServiceStateDataOnly(
-                ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, ServiceState.STATE_IN_SERVICE, false));
-        mImsPhoneUT.handleMessage(m);
-        m.recycle();
-
-        // Verify that it hasn't been called again.
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), anyBoolean());
-    }
-
-    @Test
-    @SmallTest
-    public void testCellVoiceDataChangeToWlanInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
-        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
-        doReturn(true).when(mPhone).isRadioOn();
-
-        //roaming - voice/data registration on LTE
-        ServiceState ss = getServiceStateDataAndVoice(
-                ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.STATE_IN_SERVICE, true);
-        Message m = getServiceStateChangedMessage(ss);
-        // Inject the message synchronously instead of waiting for the thread to do it.
-        mImsPhoneUT.handleMessage(m);
-
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), eq(true));
-
-        // roaming - voice LTE, data registration onto IWLAN
-        modifyServiceStateData(ss, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
-                ServiceState.STATE_IN_SERVICE, false);
-        mImsPhoneUT.handleMessage(m);
-        m.recycle();
-
-        // Verify that it hasn't been called again.
-        verify(mImsManager, times(1)).setWfcMode(anyInt(), anyBoolean());
-    }
-
-    @Test
     public void testNonNullTrackersInImsPhone() throws Exception {
         assertNotNull(mImsPhoneUT.getEmergencyNumberTracker());
         assertNotNull(mImsPhoneUT.getServiceStateTracker());
@@ -1016,7 +970,9 @@
         doReturn(subId).when(mPhone).getSubId();
         SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
         doReturn("gb").when(subInfo).getCountryIso();
-        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);
+        doReturn(new SubscriptionInfoInternal.Builder().setId(subId).setSimSlotIndex(0)
+                .setCountryIso("gb").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(subId);
 
         // 1. Two valid phone number; 1st is set.
         Uri[] associatedUris = new Uri[] {
@@ -1025,8 +981,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539447777");
+        verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539447777");
 
         // 2. 1st invalid and 2nd valid: 2nd is set.
         associatedUris = new Uri[] {
@@ -1035,8 +990,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446666");
+        verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539446666");
 
         // 3. 1st sip-uri is not phone number and 2nd valid: 2nd is set.
         associatedUris = new Uri[] {
@@ -1046,8 +1000,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446677");
+        verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539446677");
 
         // Clean up
         mContextFixture.addCallingOrSelfPermission("");
@@ -1062,7 +1015,9 @@
         doReturn(subId).when(mPhone).getSubId();
         SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
         doReturn("gb").when(subInfo).getCountryIso();
-        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);
+        doReturn(new SubscriptionInfoInternal.Builder().setId(subId).setSimSlotIndex(0)
+                .setCountryIso("gb").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(0);
 
         // 1. No valid phone number; do not set
         Uri[] associatedUris = new Uri[] {
@@ -1071,33 +1026,367 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
+        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
 
         // 2. no URI; do not set
         associatedUris = new Uri[] {};
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
+        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
 
         // 3. null URI; do not set
         associatedUris = new Uri[] { null };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
+        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
 
         // 4. null pointer; do not set
         mImsPhoneUT.setPhoneNumberForSourceIms(null);
 
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
+        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
 
         // Clean up
         mContextFixture.addCallingOrSelfPermission("");
     }
 
+    /**
+     * Verifies that valid radio technology is passed to RIL
+     * when IMS registration state changes to registered.
+     */
+    @Test
+    @SmallTest
+    public void testUpdateImsRegistrationInfoRadioTech() {
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+
+        int[] regInfo = mSimulatedCommands.getImsRegistrationInfo();
+        assertNotNull(regInfo);
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        RegistrationManager.RegistrationCallback registrationCallback =
+                mImsPhoneUT.getImsMmTelRegistrationCallback();
+
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
+                REGISTRATION_TECH_LTE).build();
+        registrationCallback.onRegistered(attr);
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_VOICE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VOICE);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same radio technology
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_LTE).build();
+        registrationCallback.onRegistered(attr);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // radio technology changed
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_NR).build();
+        registrationCallback.onRegistered(attr);
+
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_NR
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VOICE);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same radio technology
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_NR).build();
+        registrationCallback.onRegistered(attr);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // radio technology changed
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_IWLAN).build();
+        registrationCallback.onRegistered(attr);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_IWLAN
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VOICE);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same radio technology
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_IWLAN).build();
+        registrationCallback.onRegistered(attr);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // radio technology changed
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_3G).build();
+        registrationCallback.onRegistered(attr);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_3G
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VOICE);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same radio technology
+        attr = new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_3G).build();
+        registrationCallback.onRegistered(attr);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+    }
+
+    /**
+     * Verifies that valid capabilities is passed to RIL
+     * when IMS registration state changes to registered.
+     */
+    @Test
+    @SmallTest
+    public void testUpdateImsRegistrationInfoCapabilities() {
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+
+        int[] regInfo = mSimulatedCommands.getImsRegistrationInfo();
+        assertNotNull(regInfo);
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        RegistrationManager.RegistrationCallback registrationCallback =
+                mImsPhoneUT.getImsMmTelRegistrationCallback();
+
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
+                REGISTRATION_TECH_LTE).build();
+        registrationCallback.onRegistered(attr);
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_VOICE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VOICE);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same capability
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_VOICE);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // capability changed
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_VIDEO);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_VIDEO);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same capability
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_VIDEO);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // capability changed
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_SMS);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[3] == IMS_MMTEL_CAPABILITY_SMS);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // duplicated notification with the same capability
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_SMS);
+
+        // verify that there is no change in SimulatedCommands
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+
+        // capability changed, but no capability
+        mImsPhoneUT.updateImsRegistrationInfo(IMS_MMTEL_CAPABILITY_SMS);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        // verify that there is no change in SimulatedCommands.
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[3] == 0);
+    }
+
+    /**
+     * Verifies that valid state and reason is passed to RIL
+     * when IMS registration state changes to unregistered.
+     */
+    @Test
+    @SmallTest
+    public void testUpdateImsRegistrationInfo() {
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+
+        int[] regInfo = mSimulatedCommands.getImsRegistrationInfo();
+        assertNotNull(regInfo);
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        RegistrationManager.RegistrationCallback registrationCallback =
+                mImsPhoneUT.getImsMmTelRegistrationCallback();
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
+                ImsReasonInfo.CODE_UNSPECIFIED, "");
+
+        // unregistered with fatal error
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_NR);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_NR
+                && regInfo[2] == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        // unregistered with fatal error but rat changed
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_LTE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[2] == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        // duplicated notification with the same suggested action
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_LTE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        // verify that there is no update in the SimulatedCommands
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        // unregistered with repeated error
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+                REGISTRATION_TECH_LTE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[2] == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT);
+
+        // reset the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        // duplicated notification with the same suggested action
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+                REGISTRATION_TECH_LTE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        // verify that there is no update in the SimulatedCommands
+        assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+        // unregistered with temporary error
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_NONE, REGISTRATION_TECH_LTE);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_LTE
+                && regInfo[2] == SUGGESTED_ACTION_NONE);
+
+        // verifies that reason codes except ImsReasonInfo.CODE_REGISTRATION_ERROR are discarded.
+        reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE,
+                ImsReasonInfo.CODE_UNSPECIFIED, "");
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK, REGISTRATION_TECH_NR);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+                && regInfo[1] == REGISTRATION_TECH_NR
+                && regInfo[2] == SUGGESTED_ACTION_NONE);
+
+        // change the registration info saved in the SimulatedCommands
+        mSimulatedCommands.updateImsRegistrationInfo(1, 1, 1, 1, null);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        assertTrue(regInfo[0] == 1 && regInfo[1] == 1 && regInfo[2] == 1);
+
+        // duplicated notification with the same suggested action
+        registrationCallback.onUnregistered(reasonInfo,
+                SUGGESTED_ACTION_NONE, REGISTRATION_TECH_NR);
+        regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+        // verify that there is no update in the SimulatedCommands
+        assertTrue(regInfo[0] == 1 && regInfo[1] == 1 && regInfo[2] == 1);
+    }
+
+    @Test
+    @SmallTest
+    public void testImsDialArgsBuilderFromForAlternateService() {
+        ImsPhone.ImsDialArgs dialArgs = new ImsPhone.ImsDialArgs.Builder()
+                .setIsEmergency(true)
+                .setEccCategory(2)
+                .build();
+
+        ImsPhone.ImsDialArgs copiedDialArgs =
+                ImsPhone.ImsDialArgs.Builder.from(dialArgs).build();
+
+        assertTrue(copiedDialArgs.isEmergency);
+        assertEquals(2, copiedDialArgs.eccCategory);
+    }
+
     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..93fbfdc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java
@@ -16,10 +16,16 @@
 
 package com.android.internal.telephony.imsphone;
 
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -27,8 +33,10 @@
 import android.net.Uri;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.RegistrationManager.RegistrationCallback;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.TelephonyTest;
@@ -121,11 +129,13 @@
 
         // When onRegistered is called, the registration state should be
         // REGISTRATION_STATE_REGISTERED
-        callback.onRegistered(AccessNetworkType.IWLAN);
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).build();
+        callback.onRegistered(attr);
 
         assertEquals(RegistrationManager.REGISTRATION_STATE_REGISTERED,
                 mRegistrationCallbackHelper.getImsRegistrationState());
-        verify(mMockRegistrationUpdate).handleImsRegistered(anyInt());
+        verify(mMockRegistrationUpdate).handleImsRegistered(attr);
     }
 
     @Test
@@ -158,7 +168,25 @@
         // The registration state should be REGISTRATION_STATE_NOT_REGISTERED
         assertEquals(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED,
                 mRegistrationCallbackHelper.getImsRegistrationState());
-        verify(mMockRegistrationUpdate).handleImsUnregistered(reasonInfo);
+        verify(mMockRegistrationUpdate).handleImsUnregistered(eq(reasonInfo),
+                eq(SUGGESTED_ACTION_NONE), eq(REGISTRATION_TECH_NONE));
+    }
+
+    @Test
+    @SmallTest
+    public void testImsUnRegisteredWithSuggestedAction() {
+        // Verify the RegistrationCallback should not be null
+        RegistrationCallback callback = mRegistrationCallbackHelper.getCallback();
+        assertNotNull(callback);
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 0);
+        callback.onUnregistered(reasonInfo, SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK,
+                REGISTRATION_TECH_LTE);
+
+        assertEquals(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED,
+                mRegistrationCallbackHelper.getImsRegistrationState());
+        verify(mMockRegistrationUpdate).handleImsUnregistered(eq(reasonInfo),
+                eq(SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK), eq(REGISTRATION_TECH_LTE));
     }
 
     @Test
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..d4e1b86 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
@@ -18,6 +18,7 @@
 
 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.OUTGOING_SHORT_CODE_SMS;
 import static com.android.internal.telephony.TelephonyStatsLog.SIM_SLOT_STATE;
 import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
@@ -43,6 +44,7 @@
 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.OutgoingShortCodeSms;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
@@ -102,7 +104,7 @@
         mActivePort = mock(UiccPort.class);
         mServiceStateStats = mock(ServiceStateStats.class);
         mMetricsCollector =
-                new MetricsCollector(mContext, mPersistAtomsStorage);
+                new MetricsCollector(mContext, mPersistAtomsStorage, mDeviceStateHelper);
         doReturn(mSST).when(mSecondPhone).getServiceStateTracker();
         doReturn(mServiceStateStats).when(mSST).getServiceStateStats();
     }
@@ -412,4 +414,45 @@
         assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
         // TODO(b/153196254): verify atom contents
     }
+
+    @Test
+    public void onPullAtom_outgoingShortCodeSms_empty() {
+        doReturn(new OutgoingShortCodeSms[0]).when(mPersistAtomsStorage)
+                .getOutgoingShortCodeSms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
+
+    @Test
+    public void onPullAtom_outgoingShortCodeSms_tooFrequent() {
+        doReturn(null).when(mPersistAtomsStorage).getOutgoingShortCodeSms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SKIP);
+        verify(mPersistAtomsStorage, times(1))
+                .getOutgoingShortCodeSms(eq(MIN_COOLDOWN_MILLIS));
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onPullAtom_outgoingShortCodeSms_multipleSms() {
+        OutgoingShortCodeSms outgoingShortCodeSms = new OutgoingShortCodeSms();
+        doReturn(new OutgoingShortCodeSms[] {outgoingShortCodeSms, outgoingShortCodeSms,
+                outgoingShortCodeSms, outgoingShortCodeSms})
+                .when(mPersistAtomsStorage)
+                .getOutgoingShortCodeSms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMetricsCollector.onPullAtom(OUTGOING_SHORT_CODE_SMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(4);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
index 12a5828..dc9be1c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
@@ -43,8 +43,9 @@
 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.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.UiccSlot;
 
 import org.junit.After;
@@ -82,17 +83,20 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
         SubscriptionInfo subscriptionInfo1 = mock(SubscriptionInfo.class);
         doReturn("us").when(subscriptionInfo1).getCountryIso();
-        doReturn(subscriptionInfo1).when(mSubscriptionController).getSubscriptionInfo(1);
+        doReturn(new SubscriptionInfoInternal.Builder().setId(1).setSimSlotIndex(0)
+                .setCountryIso("us").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(1);
+
         ImsManager imsManager = mContext.getSystemService(ImsManager.class);
         ImsMmTelManager imsMmTelManager1 = mock(ImsMmTelManager.class);
         doReturn(imsMmTelManager1).when(imsManager).getImsMmTelManager(1);
@@ -118,23 +122,27 @@
         doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
         doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
         doReturn(NETWORK_TYPE_BITMASK_GSM).when(mPersistAtomsStorage).getUnmeteredNetworks(0, 100);
+        doReturn(false).when(mTelephonyManager).isVoNrEnabled();
         // 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)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(2, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("16506950123")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(2, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506950123")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(2, PHONE_NUMBER_SOURCE_IMS, null, null);
         SubscriptionInfo subscriptionInfo2 = mock(SubscriptionInfo.class);
         doReturn("us").when(subscriptionInfo2).getCountryIso();
-        doReturn(subscriptionInfo2).when(mSubscriptionController).getSubscriptionInfo(2);
+        doReturn(new SubscriptionInfoInternal.Builder().setId(2).setSimSlotIndex(1)
+                .setCountryIso("us").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(2);
+
         ImsMmTelManager imsMmTelManager2 = mock(ImsMmTelManager.class);
         doReturn(imsMmTelManager2).when(imsManager).getImsMmTelManager(2);
         doReturn(true).when(imsMmTelManager2).isAdvancedCallingSettingEnabled();
@@ -182,6 +190,7 @@
                 PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                 perSimStatus1.minimumVoltageClass);
         assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus1.unmeteredNetworks);
+        assertEquals(false, perSimStatus1.vonrEnabled);
         assertEquals(101, perSimStatus2.carrierId);
         assertEquals(1, perSimStatus2.phoneNumberSourceUicc);
         assertEquals(2, perSimStatus2.phoneNumberSourceCarrier);
@@ -200,12 +209,13 @@
                 PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B,
                 perSimStatus2.minimumVoltageClass);
         assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus2.unmeteredNetworks);
+        assertEquals(false, perSimStatus2.vonrEnabled);
     }
 
     @Test
     @SmallTest
-    public void onPullAtom_perSimStatus_noSubscriptionController() throws Exception {
-        replaceInstance(SubscriptionController.class, "sInstance", null, null);
+    public void onPullAtom_perSimStatus_noSubscriptionManagerService() throws Exception {
+        replaceInstance(SubscriptionManagerService.class, "sInstance", null, null);
 
         PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
 
@@ -219,17 +229,19 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .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(new SubscriptionInfoInternal.Builder().setId(1).setSimSlotIndex(0)
+                .setCountryIso("us").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(1);
         doReturn(null).when(mContext).getSystemService(ImsManager.class);
         doReturn(1L)
                 .when(mPhone)
@@ -245,6 +257,7 @@
         doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
         doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
         doReturn(NETWORK_TYPE_BITMASK_GSM).when(mPersistAtomsStorage).getUnmeteredNetworks(0, 100);
+        doReturn(true).when(mTelephonyManager).isVoNrEnabled();
 
         PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
 
@@ -265,6 +278,7 @@
                 PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                 perSimStatus.minimumVoltageClass);
         assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
+        assertEquals(true, perSimStatus.vonrEnabled);
     }
 
     @Test
@@ -274,17 +288,19 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .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(new SubscriptionInfoInternal.Builder().setId(1).setSimSlotIndex(0)
+                .setCountryIso("us").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(1);
         ImsManager imsManager = mContext.getSystemService(ImsManager.class);
         doThrow(new IllegalArgumentException()).when(imsManager).getImsMmTelManager(1);
         doReturn(false).when(mPhone).getDataRoamingEnabled();
@@ -302,6 +318,7 @@
         doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
         doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
         doReturn(NETWORK_TYPE_BITMASK_GSM).when(mPersistAtomsStorage).getUnmeteredNetworks(0, 100);
+        doReturn(true).when(mTelephonyManager).isVoNrEnabled();
 
         PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
 
@@ -322,6 +339,7 @@
                 PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
                 perSimStatus.minimumVoltageClass);
         assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
+        assertEquals(true, perSimStatus.vonrEnabled);
     }
 
     @Test
@@ -331,17 +349,19 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
+                .when(mSubscriptionManagerService)
                 .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(new SubscriptionInfoInternal.Builder().setId(1).setSimSlotIndex(0)
+                .setCountryIso("us").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(1);
         doReturn(null).when(mContext).getSystemService(ImsManager.class);
         doReturn(1L)
                 .when(mPhone)
@@ -355,6 +375,7 @@
         doReturn(iccCard).when(mPhone).getIccCard();
         doReturn(null).when(mUiccController).getUiccSlotForPhone(0);
         doReturn(NETWORK_TYPE_BITMASK_GSM).when(mPersistAtomsStorage).getUnmeteredNetworks(0, 100);
+        doReturn(true).when(mTelephonyManager).isVoNrEnabled();
 
         PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
 
@@ -375,5 +396,6 @@
                 PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN,
                 perSimStatus.minimumVoltageClass);
         assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
+        assertEquals(true, perSimStatus.vonrEnabled);
     }
 }
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 e46b822..3307813 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -49,6 +49,7 @@
 import android.content.Context;
 import android.os.Build;
 import android.telephony.DisconnectCause;
+import android.telephony.SatelliteProtoEnums;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyProtoEnums;
@@ -68,10 +69,17 @@
 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.OutgoingShortCodeSms;
 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.SatelliteController;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
 import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
@@ -140,7 +148,7 @@
     private CellularDataServiceSwitch mServiceSwitch1Proto;
     private CellularDataServiceSwitch mServiceSwitch2Proto;
 
-    // service states for slot 0 and 1
+    // Service states for slot 0 and 1
     private CellularServiceState mServiceState1Proto;
     private CellularServiceState mServiceState2Proto;
     private CellularServiceState mServiceState3Proto;
@@ -224,6 +232,34 @@
     private SipTransportSession mSipTransportSession2;
     private SipTransportSession[] mSipTransportSession;
 
+    private OutgoingShortCodeSms mOutgoingShortCodeSms1;
+    private OutgoingShortCodeSms mOutgoingShortCodeSms2;
+    private OutgoingShortCodeSms[] mOutgoingShortCodeSms;
+
+    private SatelliteController mSatelliteController1;
+    private SatelliteController mSatelliteController2;
+    private SatelliteController[] mSatelliteControllers;
+
+    private SatelliteSession mSatelliteSession1;
+    private SatelliteSession mSatelliteSession2;
+    private SatelliteSession[] mSatelliteSessions;
+
+    private SatelliteIncomingDatagram mSatelliteIncomingDatagram1;
+    private SatelliteIncomingDatagram mSatelliteIncomingDatagram2;
+    private SatelliteIncomingDatagram[] mSatelliteIncomingDatagrams;
+
+    private SatelliteOutgoingDatagram mSatelliteOutgoingDatagram1;
+    private SatelliteOutgoingDatagram mSatelliteOutgoingDatagram2;
+    private SatelliteOutgoingDatagram[] mSatelliteOutgoingDatagrams;
+
+    private SatelliteProvision mSatelliteProvision1;
+    private SatelliteProvision mSatelliteProvision2;
+    private SatelliteProvision[] mSatelliteProvisions;
+
+    private SatelliteSosMessageRecommender mSatelliteSosMessageRecommender1;
+    private SatelliteSosMessageRecommender mSatelliteSosMessageRecommender2;
+    private SatelliteSosMessageRecommender[] mSatelliteSosMessageRecommenders;
+
     private void makeTestData() {
         // MO call with SRVCC (LTE to UMTS)
         mCall1Proto = new VoiceCallSession();
@@ -859,6 +895,158 @@
 
         mSipTransportSession =
                 new SipTransportSession[] {mSipTransportSession1, mSipTransportSession2};
+
+        mOutgoingShortCodeSms1 = new OutgoingShortCodeSms();
+        mOutgoingShortCodeSms1.category = 1;
+        mOutgoingShortCodeSms1.xmlVersion = 30;
+        mOutgoingShortCodeSms1.shortCodeSmsCount = 1;
+
+        mOutgoingShortCodeSms2 = new OutgoingShortCodeSms();
+        mOutgoingShortCodeSms2.category = 2;
+        mOutgoingShortCodeSms2.xmlVersion  = 31;
+        mOutgoingShortCodeSms2.shortCodeSmsCount = 1;
+
+        mOutgoingShortCodeSms = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1,
+                mOutgoingShortCodeSms2};
+
+        generateTestSatelliteData();
+    }
+
+    private void generateTestSatelliteData() {
+        mSatelliteController1 = new SatelliteController();
+        mSatelliteController1.countOfSatelliteServiceEnablementsSuccess = 2;
+        mSatelliteController1.countOfSatelliteServiceEnablementsFail = 0;
+        mSatelliteController1.countOfOutgoingDatagramSuccess = 8;
+        mSatelliteController1.countOfOutgoingDatagramFail = 9;
+        mSatelliteController1.countOfIncomingDatagramSuccess = 10;
+        mSatelliteController1.countOfIncomingDatagramFail = 11;
+        mSatelliteController1.countOfDatagramTypeSosSmsSuccess = 5;
+        mSatelliteController1.countOfDatagramTypeSosSmsFail = 5;
+        mSatelliteController1.countOfDatagramTypeLocationSharingSuccess = 6;
+        mSatelliteController1.countOfDatagramTypeLocationSharingFail = 6;
+        mSatelliteController1.countOfProvisionSuccess = 3;
+        mSatelliteController1.countOfProvisionFail = 4;
+        mSatelliteController1.countOfDeprovisionSuccess = 5;
+        mSatelliteController1.countOfDeprovisionFail = 6;
+        mSatelliteController1.totalServiceUptimeSec = 60 * 60 * 24 * 7;
+        mSatelliteController1.totalBatteryConsumptionPercent = 7;
+        mSatelliteController1.totalBatteryChargedTimeSec = 60 * 60 * 3 * 1;
+
+        mSatelliteController2 = new SatelliteController();
+        mSatelliteController2.countOfSatelliteServiceEnablementsSuccess = 2 + 1;
+        mSatelliteController2.countOfSatelliteServiceEnablementsFail = 0 + 1;
+        mSatelliteController2.countOfOutgoingDatagramSuccess = 8 + 1;
+        mSatelliteController2.countOfOutgoingDatagramFail = 9 + 1;
+        mSatelliteController2.countOfIncomingDatagramSuccess = 10 + 1;
+        mSatelliteController2.countOfIncomingDatagramFail = 11 + 1;
+        mSatelliteController2.countOfDatagramTypeSosSmsSuccess = 5 + 1;
+        mSatelliteController2.countOfDatagramTypeSosSmsFail = 5 + 1;
+        mSatelliteController2.countOfDatagramTypeLocationSharingSuccess = 6 + 1;
+        mSatelliteController2.countOfDatagramTypeLocationSharingFail = 6 + 1;
+        mSatelliteController2.countOfProvisionSuccess = 13;
+        mSatelliteController2.countOfProvisionFail = 14;
+        mSatelliteController2.countOfDeprovisionSuccess = 15;
+        mSatelliteController2.countOfDeprovisionFail = 16;
+        mSatelliteController2.totalServiceUptimeSec = 60 * 60 * 12;
+        mSatelliteController2.totalBatteryConsumptionPercent = 14;
+        mSatelliteController1.totalBatteryChargedTimeSec = 60 * 60 * 3;
+
+        // SatelliteController atom has one data point
+        mSatelliteControllers =
+                new SatelliteController[] {
+                        mSatelliteController1
+                };
+
+        mSatelliteSession1 = new SatelliteSession();
+        mSatelliteSession1.satelliteServiceInitializationResult =
+                SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+        mSatelliteSession1.satelliteTechnology =
+                SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_PROPRIETARY;
+        mSatelliteSession1.count = 1;
+
+        mSatelliteSession2 = new SatelliteSession();
+        mSatelliteSession2.satelliteServiceInitializationResult =
+                SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+        mSatelliteSession2.satelliteTechnology =
+                SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_NB_IOT_NTN;
+        mSatelliteSession2.count = 1;
+
+        mSatelliteSessions =
+                new SatelliteSession[] {
+                        mSatelliteSession1, mSatelliteSession2
+                };
+
+        mSatelliteIncomingDatagram1 = new SatelliteIncomingDatagram();
+        mSatelliteIncomingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+        mSatelliteIncomingDatagram1.datagramSizeBytes = 1 * 1024;
+        mSatelliteIncomingDatagram1.datagramTransferTimeMillis = 3 * 1000;
+
+        mSatelliteIncomingDatagram2 = new SatelliteIncomingDatagram();
+        mSatelliteIncomingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+        mSatelliteIncomingDatagram2.datagramSizeBytes = 512;
+        mSatelliteIncomingDatagram2.datagramTransferTimeMillis = 1 * 1000;
+
+        mSatelliteIncomingDatagrams =
+                new SatelliteIncomingDatagram[] {
+                        mSatelliteIncomingDatagram1, mSatelliteIncomingDatagram2
+                };
+
+        mSatelliteOutgoingDatagram1 = new SatelliteOutgoingDatagram();
+        mSatelliteOutgoingDatagram1.datagramType =
+                SatelliteProtoEnums.DATAGRAM_TYPE_LOCATION_SHARING;
+        mSatelliteOutgoingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+        mSatelliteOutgoingDatagram1.datagramSizeBytes = 1 * 1024;
+        mSatelliteOutgoingDatagram1.datagramTransferTimeMillis = 3 * 1000;
+
+        mSatelliteOutgoingDatagram2 = new SatelliteOutgoingDatagram();
+        mSatelliteOutgoingDatagram2.datagramType =
+                SatelliteProtoEnums.DATAGRAM_TYPE_SOS_MESSAGE;
+        mSatelliteOutgoingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+        mSatelliteOutgoingDatagram2.datagramSizeBytes = 512;
+        mSatelliteOutgoingDatagram2.datagramTransferTimeMillis = 1 * 1000;
+
+        mSatelliteOutgoingDatagrams =
+                new SatelliteOutgoingDatagram[] {
+                        mSatelliteOutgoingDatagram1, mSatelliteOutgoingDatagram2
+                };
+
+        mSatelliteProvision1 = new SatelliteProvision();
+        mSatelliteProvision1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+        mSatelliteProvision1.provisioningTimeSec = 3 * 60;
+        mSatelliteProvision1.isProvisionRequest = true;
+        mSatelliteProvision1.isCanceled = false;
+
+        mSatelliteProvision2 = new SatelliteProvision();
+        mSatelliteProvision2.resultCode = SatelliteProtoEnums.SATELLITE_SERVICE_NOT_PROVISIONED;
+        mSatelliteProvision2.provisioningTimeSec = 0;
+        mSatelliteProvision2.isProvisionRequest = false;
+        mSatelliteProvision2.isCanceled = true;
+
+        mSatelliteProvisions =
+                new SatelliteProvision[] {
+                        mSatelliteProvision1, mSatelliteProvision2
+                };
+
+        mSatelliteSosMessageRecommender1 = new SatelliteSosMessageRecommender();
+        mSatelliteSosMessageRecommender1.isDisplaySosMessageSent = true;
+        mSatelliteSosMessageRecommender1.countOfTimerStarted = 5;
+        mSatelliteSosMessageRecommender1.isImsRegistered = false;
+        mSatelliteSosMessageRecommender1.cellularServiceState =
+                TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE;
+        mSatelliteSosMessageRecommender1.count = 1;
+
+        mSatelliteSosMessageRecommender2 = new SatelliteSosMessageRecommender();
+        mSatelliteSosMessageRecommender2.isDisplaySosMessageSent = false;
+        mSatelliteSosMessageRecommender2.countOfTimerStarted = 3;
+        mSatelliteSosMessageRecommender2.isImsRegistered = true;
+        mSatelliteSosMessageRecommender2.cellularServiceState =
+                TelephonyProtoEnums.SERVICE_STATE_POWER_OFF;
+        mSatelliteSosMessageRecommender2.count = 1;
+
+        mSatelliteSosMessageRecommenders =
+                new SatelliteSosMessageRecommender[] {
+                        mSatelliteSosMessageRecommender1, mSatelliteSosMessageRecommender2
+                };
     }
 
     private static class TestablePersistAtomsStorage extends PersistAtomsStorage {
@@ -997,6 +1185,27 @@
         mSipTransportSession1 = null;
         mSipTransportSession2 = null;
         mSipTransportSession = null;
+        mOutgoingShortCodeSms1 = null;
+        mOutgoingShortCodeSms2 = null;
+        mOutgoingShortCodeSms = null;
+        mSatelliteController1 = null;
+        mSatelliteController2 = null;
+        mSatelliteControllers = null;
+        mSatelliteSession1 = null;
+        mSatelliteSession2 = null;
+        mSatelliteSessions = null;
+        mSatelliteIncomingDatagram1 = null;
+        mSatelliteIncomingDatagram2 = null;
+        mSatelliteIncomingDatagrams = null;
+        mSatelliteOutgoingDatagram1 = null;
+        mSatelliteOutgoingDatagram2 = null;
+        mSatelliteOutgoingDatagrams = null;
+        mSatelliteProvision1 = null;
+        mSatelliteProvision2 = null;
+        mSatelliteProvisions = null;
+        mSatelliteSosMessageRecommender1 = null;
+        mSatelliteSosMessageRecommender2 = null;
+        mSatelliteSosMessageRecommenders = null;
         super.tearDown();
     }
 
@@ -1226,7 +1435,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
         VoiceCallRatUsage[] voiceCallRatUsage = mPersistAtomsStorage.getVoiceCallRatUsages(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(voiceCallRatUsage);
     }
 
@@ -1244,7 +1453,7 @@
                 mPersistAtomsStorage.getAtomsProto().voiceCallSessionPullTimestampMillis;
         VoiceCallSession[] voiceCallSession = mPersistAtomsStorage.getVoiceCallSessions(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved, other fields should be unaffected
         assertProtoArrayEquals(mVoiceCallRatUsages, voiceCallRatUsage1);
         assertProtoArrayIsEmpty(voiceCallRatUsage2);
@@ -1275,7 +1484,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
         VoiceCallSession[] voiceCallSession = mPersistAtomsStorage.getVoiceCallSessions(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(voiceCallSession);
     }
 
@@ -1293,7 +1502,7 @@
                 mPersistAtomsStorage.getAtomsProto().voiceCallRatUsagePullTimestampMillis;
         VoiceCallRatUsage[] voiceCallRatUsage = mPersistAtomsStorage.getVoiceCallRatUsages(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved, other fields should be unaffected
         assertProtoArrayEquals(mVoiceCallSessions, voiceCallSession1);
         assertProtoArrayIsEmpty(voiceCallSession2);
@@ -1325,7 +1534,7 @@
                 mServiceState1Proto, mServiceSwitch1Proto);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
         CellularDataServiceSwitch[] serviceSwitches =
@@ -1348,7 +1557,7 @@
                 mServiceState2Proto, mServiceSwitch2Proto);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(0L);
         CellularDataServiceSwitch[] serviceSwitches =
@@ -1442,7 +1651,7 @@
         CellularDataServiceSwitch[] serviceSwitches =
                 mPersistAtomsStorage.getCellularDataServiceSwitches(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(serviceSwitches);
     }
 
@@ -1459,7 +1668,7 @@
         CellularDataServiceSwitch[] serviceSwitches2 =
                 mPersistAtomsStorage.getCellularDataServiceSwitches(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto, mServiceSwitch2Proto},
@@ -1487,7 +1696,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
         CellularServiceState[] serviceStates = mPersistAtomsStorage.getCellularServiceStates(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(serviceStates);
     }
 
@@ -1502,7 +1711,7 @@
         mPersistAtomsStorage.incTimeMillis(100L);
         CellularServiceState[] serviceStates2 = mPersistAtomsStorage.getCellularServiceStates(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new CellularServiceState[] {
@@ -1536,7 +1745,7 @@
         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
         assertProtoArrayEquals(new ImsRegistrationStats[] {mImsRegistrationStatsLte0}, regStats);
@@ -1552,7 +1761,7 @@
         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsWifi0));
         mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationStats[] regStats = mPersistAtomsStorage.getImsRegistrationStats(0L);
         assertProtoArrayEqualsIgnoringOrder(
@@ -1624,7 +1833,7 @@
         mPersistAtomsStorage.addImsRegistrationTermination(mImsRegistrationTerminationLte);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationTermination[] terminations =
                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
@@ -1642,7 +1851,7 @@
         mPersistAtomsStorage.addImsRegistrationTermination(mImsRegistrationTerminationWifi);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationTermination[] terminations =
                 mPersistAtomsStorage.getImsRegistrationTerminations(0L);
@@ -1707,7 +1916,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
         ImsRegistrationStats[] stats = mPersistAtomsStorage.getImsRegistrationStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(stats);
     }
 
@@ -1722,7 +1931,7 @@
         mPersistAtomsStorage.incTimeMillis(100L);
         ImsRegistrationStats[] stats2 = mPersistAtomsStorage.getImsRegistrationStats(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new ImsRegistrationStats[] {
@@ -1753,7 +1962,7 @@
         ImsRegistrationTermination[] terminations =
                 mPersistAtomsStorage.getImsRegistrationTerminations(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(terminations);
     }
 
@@ -1770,7 +1979,7 @@
         ImsRegistrationTermination[] terminations2 =
                 mPersistAtomsStorage.getImsRegistrationTerminations(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new ImsRegistrationTermination[] {
@@ -1935,7 +2144,7 @@
         ImsRegistrationFeatureTagStats[] result =
                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(result);
     }
 
@@ -1952,7 +2161,7 @@
         ImsRegistrationFeatureTagStats[] statses2 =
                 mPersistAtomsStorage.getImsRegistrationFeatureTagStats(50L);
 
-        // first results of get should have two atoms, second should be empty
+        // 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);
@@ -2002,13 +2211,13 @@
 
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
 
-        // store 11 same atoms, but only 1 atoms stored with count 11
+        // 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
+        // Store 1 different atom and count 1
         mPersistAtomsStorage
                 .addRcsClientProvisioningStats(mRcsClientProvisioningStats2Proto);
 
@@ -2017,7 +2226,7 @@
         RcsClientProvisioningStats[] result =
                 mPersistAtomsStorage.getRcsClientProvisioningStats(0L);
 
-        // first atom has count 11, the other has 1
+        // First atom has count 11, the other has 1
         assertHasStatsAndCount(result, mRcsClientProvisioningStats1Proto, 11);
         assertHasStatsAndCount(result, mRcsClientProvisioningStats2Proto, 1);
     }
@@ -2032,7 +2241,7 @@
         RcsClientProvisioningStats[] result =
                 mPersistAtomsStorage.getRcsClientProvisioningStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(result);
     }
 
@@ -2049,7 +2258,7 @@
         RcsClientProvisioningStats[] statses2 =
                 mPersistAtomsStorage.getRcsClientProvisioningStats(50L);
 
-        // first results of get should have two atoms, second should be empty
+        // 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);
@@ -2101,8 +2310,8 @@
 
         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
+        // 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 < maxCount; i++) {
             mPersistAtomsStorage
@@ -2140,7 +2349,7 @@
         RcsAcsProvisioningStats[] result =
                 mPersistAtomsStorage.getRcsAcsProvisioningStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(result);
     }
 
@@ -2157,7 +2366,7 @@
         RcsAcsProvisioningStats[] statses2 =
                 mPersistAtomsStorage.getRcsAcsProvisioningStats(DAY_IN_MILLIS - HOUR_IN_MILLIS);
 
-        // first results of get should have two atoms, second should be empty
+        // 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);
@@ -2183,7 +2392,7 @@
         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceIm);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationServiceDescStats[] outputs =
             mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
@@ -2201,7 +2410,7 @@
         mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceFt);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsRegistrationServiceDescStats[] output =
             mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
@@ -2248,7 +2457,7 @@
         ImsRegistrationServiceDescStats[] output =
             mPersistAtomsStorage.getImsRegistrationServiceDescStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(output);
     }
 
@@ -2265,7 +2474,7 @@
         ImsRegistrationServiceDescStats[] output2 =
             mPersistAtomsStorage.getImsRegistrationServiceDescStats(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new ImsRegistrationServiceDescStats[] {
@@ -2436,7 +2645,7 @@
         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsDedicatedBearerListenerEvent[] outputs =
                 mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
@@ -2454,7 +2663,7 @@
         mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent2);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsDedicatedBearerListenerEvent[] output =
                 mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
@@ -2495,7 +2704,7 @@
         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsDedicatedBearerEvent[] outputs =
             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
@@ -2513,7 +2722,7 @@
         mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent2);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         ImsDedicatedBearerEvent[] output =
             mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
@@ -2588,7 +2797,6 @@
                 mImsDedicatedBearerEvent2, newStats}, stats);
     }
 
-
     @Test
     @SmallTest
     public void addUceEventStats_emptyProto() throws Exception {
@@ -2597,7 +2805,7 @@
         mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         UceEventStats[] outputs = mPersistAtomsStorage.getUceEventStats(0L);
         assertProtoArrayEquals(
@@ -2614,7 +2822,7 @@
         mPersistAtomsStorage.addUceEventStats(mUceEventStats2);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         UceEventStats[] output = mPersistAtomsStorage.getUceEventStats(0L);
         assertProtoArrayEqualsIgnoringOrder(
@@ -2688,7 +2896,7 @@
         mPersistAtomsStorage.addPresenceNotifyEvent(mPresenceNotifyEvent2);
         mPersistAtomsStorage.incTimeMillis(100L);
 
-        // service state and service switch should be added successfully
+        // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
         PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(0L);
         assertProtoArrayEqualsIgnoringOrder(
@@ -2704,7 +2912,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
         PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(output);
     }
 
@@ -2719,7 +2927,7 @@
         mPersistAtomsStorage.incTimeMillis(100L);
         PresenceNotifyEvent[] output2 = mPersistAtomsStorage.getPresenceNotifyEvent(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // 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);
@@ -2846,7 +3054,7 @@
         SipTransportFeatureTagStats[] outputs =
                 mPersistAtomsStorage.getSipTransportFeatureTagStats(100L);
 
-        // should be denied
+        // Should be denied
         assertNull(outputs);
     }
 
@@ -2865,7 +3073,7 @@
         SipTransportFeatureTagStats[] output2 =
                 mPersistAtomsStorage.getSipTransportFeatureTagStats(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new SipTransportFeatureTagStats[] {
@@ -2988,7 +3196,7 @@
         mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
 
         SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(100L);
-        // should be denied
+        // Should be denied
         assertNull(outputs);
     }
 
@@ -3005,7 +3213,7 @@
         mPersistAtomsStorage.incTimeMillis(100L);
         SipDelegateStats[] output2 = mPersistAtomsStorage.getSipDelegateStats(50L);
 
-        // first set of results should equal to file contents, second should be empty, corresponding
+        // First set of results should equal to file contents, second should be empty, corresponding
         // pull timestamp should be updated and saved
         assertProtoArrayEqualsIgnoringOrder(
                 new SipDelegateStats[] {
@@ -3131,18 +3339,18 @@
         createEmptyTestFile();
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
 
-        // store 11 same atoms, but only 1 atoms stored with count 11
+        // 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
+        // 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
+        // First atom has count 11, the other has 1
         assertHasStats(result, mSipMessageResponse1, 11);
         assertHasStats(result, mSipMessageResponse2, 1);
     }
@@ -3200,18 +3408,18 @@
         createEmptyTestFile();
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
 
-        // store 11 same atoms, but only 1 atoms stored with count 11
+        // 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
+        // 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
+        // First atom has count 11, the other has 1
         assertHasStats(result, mSipTransportSession1, 11);
         assertHasStats(result, mSipTransportSession2, 1);
     }
@@ -3399,6 +3607,599 @@
     }
 
     @Test
+    public void addOutgoingShortCodeSms_emptyProto() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // OutgoingShortCodeSms should be added successfully, changes should be saved.
+        verifyCurrentStateSavedToFileOnce();
+        OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1};
+        assertProtoArrayEquals(expectedList,
+                mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
+    }
+
+    @Test
+    public void addOutgoingShortCodeSms_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
+        mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // OutgoingShortCodeSms should be added successfully.
+        verifyCurrentStateSavedToFileOnce();
+        OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1,
+                mOutgoingShortCodeSms2};
+        assertProtoArrayEqualsIgnoringOrder(expectedList,
+                mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
+    }
+
+    @Test
+    public void addOutgoingShortCodeSms_updateExistingEntries() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        // Add copy of mOutgoingShortCodeSms1.
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addOutgoingShortCodeSms(copyOf(mOutgoingShortCodeSms1));
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // mOutgoingShortCodeSms1's short code sms count should be increased by 1.
+        verifyCurrentStateSavedToFileOnce();
+        OutgoingShortCodeSms newOutgoingShortCodeSms1 = copyOf(mOutgoingShortCodeSms1);
+        newOutgoingShortCodeSms1.shortCodeSmsCount = 2;
+        OutgoingShortCodeSms[] expectedList = new OutgoingShortCodeSms[] {newOutgoingShortCodeSms1,
+                mOutgoingShortCodeSms2};
+        assertProtoArrayEqualsIgnoringOrder(expectedList,
+                mPersistAtomsStorage.getOutgoingShortCodeSms(0L));
+    }
+
+    @Test
+    public void addOutgoingShortCodeSms_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store mOutgoingShortCodeSms1 11 times.
+        for (int i = 0; i < 11; i++) {
+            mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms1);
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+        // Store mOutgoingShortCodeSms2 1 time.
+        mPersistAtomsStorage.addOutgoingShortCodeSms(mOutgoingShortCodeSms2);
+
+        verifyCurrentStateSavedToFileOnce();
+        OutgoingShortCodeSms[] result = mPersistAtomsStorage
+                .getOutgoingShortCodeSms(0L);
+        assertHasStatsAndCount(result, mOutgoingShortCodeSms1, 11);
+        assertHasStatsAndCount(result, mOutgoingShortCodeSms2, 1);
+    }
+
+    @Test
+    public void getOutgoingShortCodeSms_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        // Pull interval less than minimum.
+        mPersistAtomsStorage.incTimeMillis(50L);
+        OutgoingShortCodeSms[] outgoingShortCodeSmsList = mPersistAtomsStorage
+                .getOutgoingShortCodeSms(100L);
+        // Should be denied.
+        assertNull(outgoingShortCodeSmsList);
+    }
+
+    @Test
+    public void getOutgoingShortCodeSms_withSavedAtoms() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(100L);
+        OutgoingShortCodeSms[] outgoingShortCodeSmsList1 = mPersistAtomsStorage
+                .getOutgoingShortCodeSms(50L);
+        mPersistAtomsStorage.incTimeMillis(100L);
+        OutgoingShortCodeSms[] outgoingShortCodeSmsList2 = mPersistAtomsStorage
+                .getOutgoingShortCodeSms(50L);
+
+        // First set of results should be equal to file contents.
+        OutgoingShortCodeSms[] expectedOutgoingShortCodeSmsList =
+                new OutgoingShortCodeSms[] {mOutgoingShortCodeSms1, mOutgoingShortCodeSms2};
+        assertProtoArrayEqualsIgnoringOrder(expectedOutgoingShortCodeSmsList,
+                outgoingShortCodeSmsList1);
+        // Second set of results should be empty.
+        assertProtoArrayEquals(new OutgoingShortCodeSms[0], outgoingShortCodeSmsList2);
+        // Corresponding pull timestamp should be updated and saved.
+        assertEquals(START_TIME_MILLIS + 200L, mPersistAtomsStorage
+                .getAtomsProto().outgoingShortCodeSmsPullTimestampMillis);
+        InOrder inOrder = inOrder(mTestFileOutputStream);
+        assertEquals(START_TIME_MILLIS + 100L,
+                getAtomsWritten(inOrder).outgoingShortCodeSmsPullTimestampMillis);
+        assertEquals(START_TIME_MILLIS + 200L,
+                getAtomsWritten(inOrder).outgoingShortCodeSmsPullTimestampMillis);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void addSatelliteControllerStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteController[] output =
+                mPersistAtomsStorage.getSatelliteControllerStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteController[] {mSatelliteController1}, output);
+    }
+
+    @Test
+    public void addSatelliteControllerStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController1);
+        mPersistAtomsStorage.addSatelliteControllerStats(mSatelliteController2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        SatelliteController expected = new SatelliteController();
+        expected.countOfSatelliteServiceEnablementsSuccess =
+                mSatelliteController1.countOfSatelliteServiceEnablementsSuccess
+                        + mSatelliteController2.countOfSatelliteServiceEnablementsSuccess;
+        expected.countOfSatelliteServiceEnablementsFail =
+                mSatelliteController1.countOfSatelliteServiceEnablementsFail
+                        + mSatelliteController2.countOfSatelliteServiceEnablementsFail;
+        expected.countOfOutgoingDatagramSuccess =
+                mSatelliteController1.countOfOutgoingDatagramSuccess
+                        + mSatelliteController2.countOfOutgoingDatagramSuccess;
+        expected.countOfOutgoingDatagramFail =
+                mSatelliteController1.countOfOutgoingDatagramFail
+                        + mSatelliteController2.countOfOutgoingDatagramFail;
+        expected.countOfIncomingDatagramSuccess =
+                mSatelliteController1.countOfIncomingDatagramSuccess
+                        + mSatelliteController2.countOfIncomingDatagramSuccess;
+        expected.countOfIncomingDatagramFail =
+                mSatelliteController1.countOfIncomingDatagramFail
+                        + mSatelliteController2.countOfIncomingDatagramFail;
+        expected.countOfDatagramTypeSosSmsSuccess =
+                mSatelliteController1.countOfDatagramTypeSosSmsSuccess
+                        + mSatelliteController2.countOfDatagramTypeSosSmsSuccess;
+        expected.countOfDatagramTypeSosSmsFail =
+                mSatelliteController1.countOfDatagramTypeSosSmsFail
+                        + mSatelliteController2.countOfDatagramTypeSosSmsFail;
+        expected.countOfDatagramTypeLocationSharingSuccess =
+                mSatelliteController1.countOfDatagramTypeLocationSharingSuccess
+                        + mSatelliteController2.countOfDatagramTypeLocationSharingSuccess;
+        expected.countOfDatagramTypeLocationSharingFail =
+                mSatelliteController1.countOfDatagramTypeLocationSharingFail
+                        + mSatelliteController2.countOfDatagramTypeLocationSharingFail;
+        expected.countOfProvisionSuccess =
+                mSatelliteController1.countOfProvisionSuccess
+                        + mSatelliteController2.countOfProvisionSuccess;
+        expected.countOfProvisionFail =
+                mSatelliteController1.countOfProvisionFail
+                        + mSatelliteController2.countOfProvisionFail;
+        expected.countOfDeprovisionSuccess =
+                mSatelliteController1.countOfDeprovisionSuccess
+                        + mSatelliteController2.countOfDeprovisionSuccess;
+        expected.countOfDeprovisionFail =
+                mSatelliteController1.countOfDeprovisionFail
+                        + mSatelliteController2.countOfDeprovisionFail;
+        expected.totalServiceUptimeSec =
+                mSatelliteController1.totalServiceUptimeSec
+                        + mSatelliteController2.totalServiceUptimeSec;
+        expected.totalBatteryConsumptionPercent =
+                mSatelliteController1.totalBatteryConsumptionPercent
+                        + mSatelliteController2.totalBatteryConsumptionPercent;
+        expected.totalBatteryChargedTimeSec =
+                mSatelliteController1.totalBatteryChargedTimeSec
+                        + mSatelliteController2.totalBatteryChargedTimeSec;
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteController[] output =
+                mPersistAtomsStorage.getSatelliteControllerStats(0L);
+        assertHasStats(output, expected);
+    }
+
+    @Test
+    public void getSatelliteControllerStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteController[] output =
+                mPersistAtomsStorage.getSatelliteControllerStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+    @Test
+    public void addSatelliteSessionStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteSessionStats(
+                mSatelliteSession1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteSession[] output =
+                mPersistAtomsStorage.getSatelliteSessionStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteSession[] {mSatelliteSession1}, output);
+    }
+
+    @Test
+    public void addSatelliteSessionStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteSessionStats(
+                mSatelliteSession1);
+        mPersistAtomsStorage.addSatelliteSessionStats(
+                mSatelliteSession2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteSession[] output =
+                mPersistAtomsStorage.getSatelliteSessionStats(0L);
+        assertProtoArrayEqualsIgnoringOrder(
+                new SatelliteSession[] {
+                        mSatelliteSession1, mSatelliteSession2},
+                output);
+    }
+
+    @Test
+    public void addSatelliteSessionStats_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store atoms up to maximum number + 1
+        int maxCount = 15 + 1;
+        for (int i = 0; i < maxCount; i++) {
+            mPersistAtomsStorage
+                    .addSatelliteSessionStats(
+                            copyOf(mSatelliteSession1));
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Store 1 different atom
+        mPersistAtomsStorage
+                .addSatelliteSessionStats(mSatelliteSession2);
+
+        verifyCurrentStateSavedToFileOnce();
+
+        SatelliteSession[] result =
+                mPersistAtomsStorage.getSatelliteSessionStats(0L);
+
+        // First atom has count 16, the other has 1
+        assertHasStatsAndCount(result, mSatelliteSession1, 16);
+        assertHasStatsAndCount(result, mSatelliteSession2, 1);
+
+    }
+
+    @Test
+    public void getSatelliteSessionStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteSession[] output =
+                mPersistAtomsStorage.getSatelliteSessionStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+
+
+    @Test
+    public void addSatelliteIncomingDatagramStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteIncomingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteIncomingDatagram[] {mSatelliteIncomingDatagram1}, output);
+    }
+
+    @Test
+    public void addSatelliteIncomingDatagramStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram1);
+        mPersistAtomsStorage.addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteIncomingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
+        assertProtoArrayEqualsIgnoringOrder(
+                new SatelliteIncomingDatagram[] {
+                        mSatelliteIncomingDatagram1, mSatelliteIncomingDatagram2}, output);
+    }
+
+    @Test
+    public void addSatelliteIncomingDatagramStats_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store atoms up to maximum number + 1
+        int maxCount = 15 + 1;
+        for (int i = 0; i < maxCount; i++) {
+            mPersistAtomsStorage
+                    .addSatelliteIncomingDatagramStats(copyOf(mSatelliteIncomingDatagram1));
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Store 1 different atom
+        mPersistAtomsStorage
+                .addSatelliteIncomingDatagramStats(mSatelliteIncomingDatagram2);
+
+        verifyCurrentStateSavedToFileOnce();
+
+        SatelliteIncomingDatagram[] result =
+                mPersistAtomsStorage.getSatelliteIncomingDatagramStats(0L);
+
+        // First atom has count 14, the other has 1
+        assertHasStatsAndCount(result, mSatelliteIncomingDatagram1, 14);
+        assertHasStatsAndCount(result, mSatelliteIncomingDatagram2, 1);
+
+    }
+
+    @Test
+    public void getSatelliteIncomingDatagramStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteIncomingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteIncomingDatagramStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+    @Test
+    public void addSatelliteOutgoingDatagramStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteOutgoingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteOutgoingDatagram[] {mSatelliteOutgoingDatagram1}, output);
+    }
+
+    @Test
+    public void addSatelliteOutgoingDatagramStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram1);
+        mPersistAtomsStorage.addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteOutgoingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
+        assertProtoArrayEqualsIgnoringOrder(
+                new SatelliteOutgoingDatagram[] {
+                        mSatelliteOutgoingDatagram1, mSatelliteOutgoingDatagram2}, output);
+    }
+
+    @Test
+    public void addSatelliteOutgoingDatagramStats_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store atoms up to maximum number + 1
+        int maxCount = 15 + 1;
+        for (int i = 0; i < maxCount; i++) {
+            mPersistAtomsStorage
+                    .addSatelliteOutgoingDatagramStats(copyOf(mSatelliteOutgoingDatagram1));
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Store 1 different atom
+        mPersistAtomsStorage
+                .addSatelliteOutgoingDatagramStats(mSatelliteOutgoingDatagram2);
+
+        verifyCurrentStateSavedToFileOnce();
+
+        SatelliteOutgoingDatagram[] result =
+                mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(0L);
+
+        // First atom has count 14, the other has 1
+        assertHasStatsAndCount(result, mSatelliteOutgoingDatagram1, 14);
+        assertHasStatsAndCount(result, mSatelliteOutgoingDatagram2, 1);
+
+    }
+
+    @Test
+    public void getSatelliteOutgoingDatagramStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteOutgoingDatagram[] output =
+                mPersistAtomsStorage.getSatelliteOutgoingDatagramStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+    @Test
+    public void addSatelliteProvisionStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteProvision[] output =
+                mPersistAtomsStorage.getSatelliteProvisionStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteProvision[] {mSatelliteProvision1}, output);
+    }
+
+    @Test
+    public void addSatelliteProvisionStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision1);
+        mPersistAtomsStorage.addSatelliteProvisionStats(mSatelliteProvision2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteProvision[] output =
+                mPersistAtomsStorage.getSatelliteProvisionStats(0L);
+        assertProtoArrayEqualsIgnoringOrder(
+                new SatelliteProvision[] {
+                        mSatelliteProvision1, mSatelliteProvision2}, output);
+    }
+
+    @Test
+    public void addSatelliteProvisionStats_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store atoms up to maximum number + 1
+        int maxCount = 15 + 1;
+        for (int i = 0; i < maxCount; i++) {
+            mPersistAtomsStorage
+                    .addSatelliteProvisionStats(copyOf(mSatelliteProvision1));
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Store 1 different atom
+        mPersistAtomsStorage
+                .addSatelliteProvisionStats(mSatelliteProvision2);
+
+        verifyCurrentStateSavedToFileOnce();
+
+        SatelliteProvision[] result =
+                mPersistAtomsStorage.getSatelliteProvisionStats(0L);
+
+        // First atom has count 14, the other has 1
+        assertHasStatsAndCount(result, mSatelliteProvision1, 14);
+        assertHasStatsAndCount(result, mSatelliteProvision2, 1);
+
+    }
+
+    @Test
+    public void getSatelliteProvisionStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteProvision[] output =
+                mPersistAtomsStorage.getSatelliteProvisionStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+    @Test
+    public void addSatelliteSosMessageRecommenderStats_emptyProto() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
+                mSatelliteSosMessageRecommender1);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteSosMessageRecommender[] output =
+                mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
+        assertProtoArrayEquals(
+                new SatelliteSosMessageRecommender[] {mSatelliteSosMessageRecommender1}, output);
+    }
+
+    @Test
+    public void addSatelliteSosMessageRecommenderStats_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
+                mSatelliteSosMessageRecommender1);
+        mPersistAtomsStorage.addSatelliteSosMessageRecommenderStats(
+                mSatelliteSosMessageRecommender2);
+        mPersistAtomsStorage.incTimeMillis(100L);
+
+        // Service state and service switch should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        SatelliteSosMessageRecommender[] output =
+                mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
+        assertProtoArrayEqualsIgnoringOrder(
+                new SatelliteSosMessageRecommender[] {
+                        mSatelliteSosMessageRecommender1, mSatelliteSosMessageRecommender2},
+                output);
+    }
+
+    @Test
+    public void addSatelliteSosMessageRecommenderStats_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+
+        // Store atoms up to maximum number + 1
+        int maxCount = 15 + 1;
+        for (int i = 0; i < maxCount; i++) {
+            mPersistAtomsStorage
+                    .addSatelliteSosMessageRecommenderStats(
+                            copyOf(mSatelliteSosMessageRecommender1));
+            mPersistAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Store 1 different atom
+        mPersistAtomsStorage
+                .addSatelliteSosMessageRecommenderStats(mSatelliteSosMessageRecommender2);
+
+        verifyCurrentStateSavedToFileOnce();
+
+        SatelliteSosMessageRecommender[] result =
+                mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(0L);
+
+        // First atom has count 16, the other has 1
+        assertHasStatsAndCount(result, mSatelliteSosMessageRecommender1, 16);
+        assertHasStatsAndCount(result, mSatelliteSosMessageRecommender2, 1);
+
+    }
+
+    @Test
+    public void getSatelliteSosMessageRecommenderStats_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
+        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
+        SatelliteSosMessageRecommender[] output =
+                mPersistAtomsStorage.getSatelliteSosMessageRecommenderStats(100L);
+
+        // Should be denied
+        assertNull(output);
+    }
+
+    @Test
     @SmallTest
     public void clearAtoms() throws Exception {
         createTestFile(START_TIME_MILLIS);
@@ -3469,6 +4270,20 @@
         atoms.sipMessageResponse = mSipMessageResponse;
         atoms.sipTransportSessionPullTimestampMillis = lastPullTimeMillis;
         atoms.sipTransportSession = mSipTransportSession;
+        atoms.outgoingShortCodeSms = mOutgoingShortCodeSms;
+        atoms.outgoingShortCodeSmsPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteController = mSatelliteControllers;
+        atoms.satelliteControllerPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteSession = mSatelliteSessions;
+        atoms.satelliteSessionPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteIncomingDatagram = mSatelliteIncomingDatagrams;
+        atoms.satelliteIncomingDatagramPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteOutgoingDatagram = mSatelliteOutgoingDatagrams;
+        atoms.satelliteOutgoingDatagramPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteProvision = mSatelliteProvisions;
+        atoms.satelliteProvisionPullTimestampMillis = lastPullTimeMillis;
+        atoms.satelliteSosMessageRecommender = mSatelliteSosMessageRecommenders;
+        atoms.satelliteSosMessageRecommenderPullTimestampMillis = lastPullTimeMillis;
         FileOutputStream stream = new FileOutputStream(mTestFile);
         stream.write(PersistAtoms.toByteArray(atoms));
         stream.close();
@@ -3587,6 +4402,41 @@
         return SipTransportSession.parseFrom(MessageNano.toByteArray(source));
     }
 
+    private static OutgoingShortCodeSms copyOf(OutgoingShortCodeSms source)
+            throws Exception {
+        return OutgoingShortCodeSms.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteController copyOf(SatelliteController source)
+            throws Exception {
+        return SatelliteController.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteSession copyOf(SatelliteSession source)
+            throws Exception {
+        return SatelliteSession.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteIncomingDatagram copyOf(SatelliteIncomingDatagram source)
+            throws Exception {
+        return SatelliteIncomingDatagram.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteOutgoingDatagram copyOf(SatelliteOutgoingDatagram source)
+            throws Exception {
+        return SatelliteOutgoingDatagram.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteProvision copyOf(SatelliteProvision source)
+            throws Exception {
+        return SatelliteProvision.parseFrom(MessageNano.toByteArray(source));
+    }
+
+    private static SatelliteSosMessageRecommender copyOf(SatelliteSosMessageRecommender source)
+            throws Exception {
+        return SatelliteSosMessageRecommender.parseFrom(MessageNano.toByteArray(source));
+    }
+
     private void assertAllPullTimestampEquals(long timestamp) {
         assertEquals(
                 timestamp,
@@ -3732,6 +4582,119 @@
         assertEquals(expectedCount, actualCount);
     }
 
+    private static void assertHasStats(
+            SatelliteController[] tested,
+            @Nullable SatelliteController expectedStats) {
+        assertNotNull(tested);
+        assertEquals(tested[0].countOfSatelliteServiceEnablementsSuccess,
+                expectedStats.countOfSatelliteServiceEnablementsSuccess);
+        assertEquals(tested[0].countOfSatelliteServiceEnablementsFail,
+                expectedStats.countOfSatelliteServiceEnablementsFail);
+        assertEquals(tested[0].countOfOutgoingDatagramSuccess,
+                expectedStats.countOfOutgoingDatagramSuccess);
+        assertEquals(tested[0].countOfOutgoingDatagramFail,
+                expectedStats.countOfOutgoingDatagramFail);
+        assertEquals(tested[0].countOfIncomingDatagramSuccess,
+                expectedStats.countOfIncomingDatagramSuccess);
+        assertEquals(tested[0].countOfIncomingDatagramFail,
+                expectedStats.countOfIncomingDatagramFail);
+        assertEquals(tested[0].countOfDatagramTypeSosSmsSuccess,
+                expectedStats.countOfDatagramTypeSosSmsSuccess);
+        assertEquals(tested[0].countOfDatagramTypeSosSmsFail,
+                expectedStats.countOfDatagramTypeSosSmsFail);
+        assertEquals(tested[0].countOfDatagramTypeLocationSharingSuccess,
+                expectedStats.countOfDatagramTypeLocationSharingSuccess);
+        assertEquals(tested[0].countOfDatagramTypeLocationSharingFail,
+                expectedStats.countOfDatagramTypeLocationSharingFail);
+        assertEquals(tested[0].totalServiceUptimeSec,
+                expectedStats.totalServiceUptimeSec);
+        assertEquals(tested[0].totalBatteryConsumptionPercent,
+                expectedStats.totalBatteryConsumptionPercent);
+        assertEquals(tested[0].totalBatteryChargedTimeSec,
+                expectedStats.totalBatteryChargedTimeSec);
+    }
+
+    private static void assertHasStatsAndCount(
+            SatelliteSession[] tested,
+            @Nullable SatelliteSession expectedStats, int expectedCount) {
+        assertNotNull(tested);
+        int actualCount = 0;
+        for (SatelliteSession stats : tested) {
+            if (stats.satelliteServiceInitializationResult
+                    == expectedStats.satelliteServiceInitializationResult
+                    && stats.satelliteTechnology == expectedStats.satelliteTechnology) {
+                actualCount = stats.count;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
+
+    private static void assertHasStatsAndCount(
+            SatelliteIncomingDatagram[] tested,
+            @Nullable SatelliteIncomingDatagram expectedStats, int expectedCount) {
+        assertNotNull(tested);
+        int actualCount = 0;
+        for (SatelliteIncomingDatagram stats : tested) {
+            if (stats.resultCode == expectedStats.resultCode
+                    && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
+                    && stats.datagramTransferTimeMillis
+                        == expectedStats.datagramTransferTimeMillis) {
+                actualCount++;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
+
+    private static void assertHasStatsAndCount(
+            SatelliteOutgoingDatagram[] tested,
+            @Nullable SatelliteOutgoingDatagram expectedStats, int expectedCount) {
+        assertNotNull(tested);
+        int actualCount = 0;
+        for (SatelliteOutgoingDatagram stats : tested) {
+            if (stats.datagramType == expectedStats.datagramType
+                    && stats.resultCode == expectedStats.resultCode
+                    && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
+                    && stats.datagramTransferTimeMillis
+                        == expectedStats.datagramTransferTimeMillis) {
+                actualCount++;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
+
+    private static void assertHasStatsAndCount(
+            SatelliteProvision[] tested,
+            @Nullable SatelliteProvision expectedStats, int expectedCount) {
+        assertNotNull(tested);
+        int actualCount = 0;
+        for (SatelliteProvision stats : tested) {
+            if (stats.resultCode == expectedStats.resultCode
+                    && stats.provisioningTimeSec == expectedStats.provisioningTimeSec
+                    && stats.isProvisionRequest == expectedStats.isProvisionRequest
+                    && stats.isCanceled == expectedStats.isCanceled) {
+                actualCount++;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
+
+    private static void assertHasStatsAndCount(
+            SatelliteSosMessageRecommender[] tested,
+            @Nullable SatelliteSosMessageRecommender expectedStats, int expectedCount) {
+        assertNotNull(tested);
+        int actualCount = 0;
+        for (SatelliteSosMessageRecommender stats : tested) {
+            if (stats.isDisplaySosMessageSent
+                    == expectedStats.isDisplaySosMessageSent
+                    && stats.countOfTimerStarted == expectedStats.countOfTimerStarted
+                    && stats.isImsRegistered == expectedStats.isImsRegistered
+                    && stats.cellularServiceState == expectedStats.cellularServiceState) {
+                actualCount = stats.count;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
+
     private static void assertHasStatsAndCountDuration(
             RcsAcsProvisioningStats[] statses,
             @Nullable RcsAcsProvisioningStats expectedStats, int count, long duration) {
@@ -3866,4 +4829,18 @@
         }
         assertEquals(expectedCount, actualCount);
     }
+
+    private static void assertHasStatsAndCount(
+            OutgoingShortCodeSms[] outgoingShortCodeSmsList,
+            @Nullable OutgoingShortCodeSms expectedOutgoingShortCodeSms, int expectedCount) {
+        assertNotNull(outgoingShortCodeSmsList);
+        int actualCount = -1;
+        for (OutgoingShortCodeSms outgoingShortCodeSms : outgoingShortCodeSmsList) {
+            if (outgoingShortCodeSms.category == expectedOutgoingShortCodeSms.category
+                    && outgoingShortCodeSms.xmlVersion == expectedOutgoingShortCodeSms.xmlVersion) {
+                actualCount = outgoingShortCodeSms.shortCodeSmsCount;
+            }
+        }
+        assertEquals(expectedCount, actualCount);
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
new file mode 100644
index 0000000..22032ae
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2023 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.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.telephony.SatelliteProtoEnums;
+import android.telephony.TelephonyProtoEnums;
+
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteIncomingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteOutgoingDatagram;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteProvision;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSession;
+import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessageRecommender;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+public class SatelliteStatsTest extends TelephonyTest {
+    private static final String TAG = SatelliteStatsTest.class.getSimpleName();
+
+    private TestableSatelliteStats mSatelliteStats;
+
+    private class TestableSatelliteStats extends SatelliteStats {
+        TestableSatelliteStats() {
+            super();
+        }
+    }
+
+    @Before
+    public void setup() throws Exception {
+        super.setUp(getClass().getSimpleName());
+
+        mSatelliteStats = new TestableSatelliteStats();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mSatelliteStats = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void onSatelliteControllerMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteControllerParams param =
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setCountOfSatelliteServiceEnablementsSuccess(2)
+                        .setCountOfSatelliteServiceEnablementsFail(2)
+                        .setCountOfOutgoingDatagramSuccess(8)
+                        .setCountOfOutgoingDatagramFail(9)
+                        .setCountOfIncomingDatagramSuccess(10)
+                        .setCountOfIncomingDatagramFail(11)
+                        .setCountOfDatagramTypeSosSmsSuccess(5)
+                        .setCountOfDatagramTypeSosSmsFail(5)
+                        .setCountOfDatagramTypeLocationSharingSuccess(6)
+                        .setCountOfDatagramTypeLocationSharingFail(6)
+                        .setCountOfProvisionSuccess(3)
+                        .setCountOfProvisionFail(4)
+                        .setCountOfDeprovisionSuccess(5)
+                        .setCountOfDeprovisionFail(6)
+                        .setTotalServiceUptimeSec(60 * 60 * 24 * 7)
+                        .setTotalBatteryConsumptionPercent(7)
+                        .setTotalBatteryChargedTimeSec(60 * 60 * 3)
+                        .build();
+
+        mSatelliteStats.onSatelliteControllerMetrics(param);
+
+        ArgumentCaptor<SatelliteController> captor =
+                ArgumentCaptor.forClass(SatelliteController.class);
+        verify(mPersistAtomsStorage).addSatelliteControllerStats(captor.capture());
+        SatelliteController stats = captor.getValue();
+        assertEquals(param.getCountOfSatelliteServiceEnablementsSuccess(),
+                stats.countOfSatelliteServiceEnablementsSuccess);
+        assertEquals(param.getCountOfSatelliteServiceEnablementsFail(),
+                stats.countOfSatelliteServiceEnablementsFail);
+        assertEquals(param.getCountOfOutgoingDatagramSuccess(),
+                stats.countOfOutgoingDatagramSuccess);
+        assertEquals(param.getCountOfOutgoingDatagramFail(),
+                stats.countOfOutgoingDatagramFail);
+        assertEquals(param.getCountOfIncomingDatagramSuccess(),
+                stats.countOfIncomingDatagramSuccess);
+        assertEquals(param.getCountOfIncomingDatagramFail(),
+                stats.countOfIncomingDatagramFail);
+        assertEquals(param.getCountOfDatagramTypeSosSmsSuccess(),
+                stats.countOfDatagramTypeSosSmsSuccess);
+        assertEquals(param.getCountOfDatagramTypeSosSmsFail(),
+                stats.countOfDatagramTypeSosSmsFail);
+        assertEquals(param.getCountOfDatagramTypeLocationSharingSuccess(),
+                stats.countOfDatagramTypeLocationSharingSuccess);
+        assertEquals(param.getCountOfDatagramTypeLocationSharingFail(),
+                stats.countOfDatagramTypeLocationSharingFail);
+        assertEquals(param.getCountOfProvisionSuccess(),
+                stats.countOfProvisionSuccess);
+        assertEquals(param.getCountOfProvisionFail(),
+                stats.countOfProvisionFail);
+        assertEquals(param.getCountOfDeprovisionSuccess(),
+                stats.countOfDeprovisionSuccess);
+        assertEquals(param.getCountOfDeprovisionFail(),
+                stats.countOfDeprovisionFail);
+        assertEquals(param.getTotalServiceUptimeSec(),
+                stats.totalServiceUptimeSec);
+        assertEquals(param.getTotalBatteryConsumptionPercent(),
+                stats.totalBatteryConsumptionPercent);
+        assertEquals(param.getTotalBatteryChargedTimeSec(),
+                stats.totalBatteryChargedTimeSec);
+
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteSessionMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteSessionParams param =
+                new SatelliteStats.SatelliteSessionParams.Builder()
+                        .setSatelliteServiceInitializationResult(
+                                SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+                        .setSatelliteTechnology(SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_PROPRIETARY)
+                        .build();
+
+        mSatelliteStats.onSatelliteSessionMetrics(param);
+
+        ArgumentCaptor<SatelliteSession> captor =
+                ArgumentCaptor.forClass(SatelliteSession.class);
+        verify(mPersistAtomsStorage).addSatelliteSessionStats(captor.capture());
+        SatelliteSession stats = captor.getValue();
+        assertEquals(param.getSatelliteServiceInitializationResult(),
+                stats.satelliteServiceInitializationResult);
+        assertEquals(param.getSatelliteTechnology(), stats.satelliteTechnology);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteIncomingDatagramMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteIncomingDatagramParams param =
+                new SatelliteStats.SatelliteIncomingDatagramParams.Builder()
+                        .setResultCode(SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+                        .setDatagramSizeBytes(1 * 1024)
+                        .setDatagramTransferTimeMillis(3 * 1000)
+                        .build();
+
+        mSatelliteStats.onSatelliteIncomingDatagramMetrics(param);
+
+        ArgumentCaptor<SatelliteIncomingDatagram> captor =
+                ArgumentCaptor.forClass(SatelliteIncomingDatagram.class);
+        verify(mPersistAtomsStorage).addSatelliteIncomingDatagramStats(captor.capture());
+        SatelliteIncomingDatagram stats = captor.getValue();
+        assertEquals(param.getResultCode(), stats.resultCode);
+        assertEquals(param.getDatagramSizeBytes(), stats.datagramSizeBytes);
+        assertEquals(param.getDatagramTransferTimeMillis(), stats.datagramTransferTimeMillis);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteOutgoingDatagramMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteOutgoingDatagramParams param =
+                new SatelliteStats.SatelliteOutgoingDatagramParams.Builder()
+                        .setDatagramType(SatelliteProtoEnums.DATAGRAM_TYPE_LOCATION_SHARING)
+                        .setResultCode(SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+                        .setDatagramSizeBytes(1 * 1024)
+                        .setDatagramTransferTimeMillis(3 * 1000)
+                        .build();
+
+        mSatelliteStats.onSatelliteOutgoingDatagramMetrics(param);
+
+        ArgumentCaptor<SatelliteOutgoingDatagram> captor =
+                ArgumentCaptor.forClass(SatelliteOutgoingDatagram.class);
+        verify(mPersistAtomsStorage).addSatelliteOutgoingDatagramStats(captor.capture());
+        SatelliteOutgoingDatagram stats = captor.getValue();
+        assertEquals(param.getDatagramType(), stats.datagramType);
+        assertEquals(param.getResultCode(), stats.resultCode);
+        assertEquals(param.getDatagramSizeBytes(), stats.datagramSizeBytes);
+        assertEquals(param.getDatagramTransferTimeMillis(), stats.datagramTransferTimeMillis);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteProvisionMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteProvisionParams param =
+                new SatelliteStats.SatelliteProvisionParams.Builder()
+                        .setResultCode(SatelliteProtoEnums.SATELLITE_SERVICE_PROVISION_IN_PROGRESS)
+                        .setProvisioningTimeSec(5 * 1000)
+                        .setIsProvisionRequest(true)
+                        .setIsCanceled(false)
+                        .build();
+
+        mSatelliteStats.onSatelliteProvisionMetrics(param);
+
+        ArgumentCaptor<SatelliteProvision> captor =
+                ArgumentCaptor.forClass(SatelliteProvision.class);
+        verify(mPersistAtomsStorage).addSatelliteProvisionStats(captor.capture());
+        SatelliteProvision stats = captor.getValue();
+        assertEquals(param.getResultCode(), stats.resultCode);
+        assertEquals(param.getProvisioningTimeSec(), stats.provisioningTimeSec);
+        assertEquals(param.getIsProvisionRequest(), stats.isProvisionRequest);
+        assertEquals(param.getIsCanceled(), stats.isCanceled);
+
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteSosMessageRecommenderMetrics_withAtoms() throws Exception {
+        SatelliteStats.SatelliteSosMessageRecommenderParams param =
+                new SatelliteStats.SatelliteSosMessageRecommenderParams.Builder()
+                        .setDisplaySosMessageSent(true)
+                        .setCountOfTimerStarted(5)
+                        .setImsRegistered(false)
+                        .setCellularServiceState(TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE)
+                        .build();
+
+        mSatelliteStats.onSatelliteSosMessageRecommender(param);
+
+        ArgumentCaptor<SatelliteSosMessageRecommender> captor =
+                ArgumentCaptor.forClass(SatelliteSosMessageRecommender.class);
+        verify(mPersistAtomsStorage).addSatelliteSosMessageRecommenderStats(captor.capture());
+        SatelliteSosMessageRecommender stats = captor.getValue();
+        assertEquals(param.isDisplaySosMessageSent(),
+                stats.isDisplaySosMessageSent);
+        assertEquals(param.getCountOfTimerStarted(), stats.countOfTimerStarted);
+        assertEquals(param.isImsRegistered(), stats.isImsRegistered);
+        assertEquals(param.getCellularServiceState(), stats.cellularServiceState);
+        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 8406bc5..7b66a52 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
@@ -16,6 +16,15 @@
 
 package com.android.internal.telephony.metrics;
 
+import static android.telephony.TelephonyManager.DATA_CONNECTED;
+import static android.telephony.TelephonyManager.DATA_UNKNOWN;
+
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED;
+import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN;
+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 org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotSame;
@@ -35,10 +44,6 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
-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 com.android.internal.telephony.Phone;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
@@ -109,6 +114,9 @@
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_LTE);
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
 
+        doReturn(DATA_CONNECTED).when(mDataNetworkController).getInternetDataNetworkState();
+        doReturn(mDataNetworkController).when(mSecondPhone).getDataNetworkController();
+
         mServiceStateStats = new TestableServiceStateStats(mPhone);
     }
 
@@ -143,6 +151,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -155,6 +164,7 @@
         doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
         mockWwanCsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        doReturn(DATA_UNKNOWN).when(mDataNetworkController).getInternetDataNetworkState();
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
         mServiceStateStats.incTimeMillis(100L);
@@ -176,6 +186,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(false, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -221,6 +232,7 @@
         doReturn(CardState.CARDSTATE_ABSENT).when(mPhysicalSlot0).getCardState();
         mockLimitedService(TelephonyManager.NETWORK_TYPE_UMTS);
         doReturn(-1).when(mPhone).getCarrierId();
+        doReturn(DATA_UNKNOWN).when(mDataNetworkController).getInternetDataNetworkState();
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
         mServiceStateStats.incTimeMillis(100L);
@@ -242,6 +254,7 @@
         assertEquals(-1, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(true, state.isEmergencyOnly);
+        assertEquals(false, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -256,6 +269,7 @@
         mockWwanCsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
         doReturn(-1).when(mPhone).getCarrierId();
+        doReturn(DATA_UNKNOWN).when(mDataNetworkController).getInternetDataNetworkState();
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
         mServiceStateStats.incTimeMillis(100L);
@@ -277,6 +291,7 @@
         assertEquals(-1, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(false, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -308,6 +323,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -319,6 +335,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -355,6 +372,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
@@ -366,6 +384,50 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    @SmallTest
+    public void onInternetDataNetworkDisconnected() throws Exception {
+         // Using default service state for LTE
+        mServiceStateStats.onServiceStateChanged(mServiceState);
+
+        mServiceStateStats.incTimeMillis(100L);
+        mServiceStateStats.onInternetDataNetworkDisconnected();
+        mServiceStateStats.incTimeMillis(200L);
+        mServiceStateStats.conclude();
+
+        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_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);
+        assertEquals(0, state.simSlotIndex);
+        assertFalse(state.isMultiSim);
+        assertEquals(CARRIER1_ID, state.carrierId);
+        assertEquals(100L, state.totalTimeMillis);
+        assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
+        state = captor.getAllValues().get(1);
+        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);
+        assertEquals(0, state.simSlotIndex);
+        assertFalse(state.isMultiSim);
+        assertEquals(CARRIER1_ID, state.carrierId);
+        assertEquals(200L, state.totalTimeMillis);
+        assertEquals(false, state.isEmergencyOnly);
+        assertEquals(false, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -394,6 +456,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -431,6 +494,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -442,6 +506,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratTo);
@@ -482,6 +547,7 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -492,6 +558,7 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -520,6 +587,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(0L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -560,6 +628,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -571,6 +640,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -582,6 +652,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(400L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(3);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -593,6 +664,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(800L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -637,6 +709,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
@@ -648,6 +721,7 @@
         assertEquals(-1, state.carrierId);
         assertEquals(5000L, state.totalTimeMillis);
         assertEquals(true, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -659,6 +733,7 @@
         assertEquals(CARRIER2_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -703,6 +778,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -714,6 +790,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -725,6 +802,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(400L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, serviceSwitch.ratTo);
@@ -781,6 +859,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -792,6 +871,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -803,6 +883,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = serviceStateCaptor.getAllValues().get(3);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -814,6 +895,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, serviceSwitch.ratTo);
@@ -874,6 +956,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -885,6 +968,7 @@
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
         assertEquals(false, state.isEmergencyOnly);
+        assertEquals(true, state.isInternetPdnUp);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -911,6 +995,47 @@
                 mPhone, mServiceState, VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_UNKNOWN));
     }
 
+    @Test
+    @SmallTest
+    public void onFoldStateChanged_modemOff() throws Exception {
+        doReturn(ServiceState.STATE_POWER_OFF).when(mServiceState).getVoiceRegState();
+        doReturn(ServiceState.STATE_POWER_OFF).when(mServiceState).getDataRegState();
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).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(100L);
+
+        mServiceStateStats.onFoldStateChanged(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    @SmallTest
+    public void onFoldStateChanged_LTEMode() throws Exception {
+        // Using default service state for LTE with fold state unknown
+        mServiceStateStats.onServiceStateChanged(mServiceState);
+        mServiceStateStats.incTimeMillis(100L);
+        mServiceStateStats.onFoldStateChanged(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED);
+        mServiceStateStats.incTimeMillis(1000L);
+        // Same fold state as before should not generate a new atom
+        mServiceStateStats.onFoldStateChanged(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED);
+        mServiceStateStats.incTimeMillis(1000L);
+
+        // There should be 2 service state updates
+        mServiceStateStats.conclude();
+        ArgumentCaptor<CellularServiceState> captor =
+                ArgumentCaptor.forClass(CellularServiceState.class);
+        verify(mPersistAtomsStorage, times(2))
+                .addCellularServiceStateAndCellularDataServiceSwitch(captor.capture(), eq(null));
+        CellularServiceState state = captor.getAllValues().get(0);
+        assertEquals(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_UNKNOWN, state.foldState);
+        state = captor.getAllValues().get(1);
+        assertEquals(CELLULAR_SERVICE_STATE__FOLD_STATE__STATE_CLOSED, state.foldState);
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
     private void mockWwanPsRat(@NetworkType int rat) {
         mockWwanRat(
                 NetworkRegistrationInfo.DOMAIN_PS,
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 fb556e6..2ca0b16 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -77,7 +77,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -927,7 +926,6 @@
 
     @Test
     @SmallTest
-    @Ignore("b/256234604")
     public void singleImsCall_ratSwitchToUnknown() {
         setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
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 2ac0c98..580d533 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
@@ -910,7 +910,8 @@
             suggestedTimes.set(timeSuggestion);
             if (timeSuggestion.getUnixEpochTime() != null) {
                 // The fake time service just uses the latest suggestion.
-                mFakeDeviceState.currentTimeMillis = timeSuggestion.getUnixEpochTime().getValue();
+                mFakeDeviceState.currentTimeMillis =
+                        timeSuggestion.getUnixEpochTime().getUnixEpochTimeMillis();
             }
         }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaDirectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaDirectionTest.java
new file mode 100644
index 0000000..6a91d95
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaDirectionTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+import android.telephony.satellite.AntennaDirection;
+
+import org.junit.Test;
+
+public class AntennaDirectionTest {
+
+    @Test
+    public void testParcel() {
+        AntennaDirection antennaDirection = new AntennaDirection(1, 2, 3);
+
+        Parcel p = Parcel.obtain();
+        antennaDirection.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        AntennaDirection fromParcel = AntennaDirection.CREATOR.createFromParcel(p);
+        assertThat(antennaDirection).isEqualTo(fromParcel);
+    }
+
+    @Test
+    public void testEquals() {
+        AntennaDirection antennaDirection1 = new AntennaDirection(1.12f, 1.13f, 1.14f);
+        AntennaDirection antennaDirection2 = new AntennaDirection(1.12f, 1.13f, 1.14f);
+        assertEquals(antennaDirection1, antennaDirection2);
+
+        AntennaDirection antennaDirection3 = new AntennaDirection(1.121f, 1.131f, 1.141f);
+        assertNotEquals(antennaDirection1, antennaDirection3);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaPositionTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaPositionTest.java
new file mode 100644
index 0000000..919ab83
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/AntennaPositionTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+import android.telephony.satellite.AntennaDirection;
+import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.SatelliteManager;
+
+import org.junit.Test;
+
+public class AntennaPositionTest {
+
+    private AntennaDirection mAntennaDirection = new AntennaDirection(1,1,1);
+
+    @Test
+    public void testParcel() {
+        AntennaPosition antennaPosition = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+
+        Parcel p = Parcel.obtain();
+        antennaPosition.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        AntennaPosition fromParcel = AntennaPosition.CREATOR.createFromParcel(p);
+        assertThat(antennaPosition).isEqualTo(fromParcel);
+    }
+
+    @Test
+    public void testEquals() {
+        AntennaPosition antennaPosition1 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+        AntennaPosition antennaPosition2 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+        assertEquals(antennaPosition1, antennaPosition2);
+
+        AntennaPosition antennaPosition3 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT);
+        assertNotEquals(antennaPosition1, antennaPosition3);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/ControllerMetricsStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/ControllerMetricsStatsTest.java
new file mode 100644
index 0000000..baa00c1
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/ControllerMetricsStatsTest.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.telephony.satellite.SatelliteManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.metrics.SatelliteStats;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.telephony.Rlog;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ControllerMetricsStatsTest extends TelephonyTest {
+    private static final String TAG = "ControllerMetricsStatsTest";
+
+    private static final long MODEM_ENABLED_TIME = 1000L;
+
+    private TestControllerMetricsStats mControllerMetricsStatsUT;
+    private TestSatelliteStats mTestStats;
+
+    @Mock private Context mMockContext;
+    @Spy private ControllerMetricsStats mSpyControllerMetricsStats;
+    @Mock private SatelliteStats mMockSatelliteStats;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        Rlog.d(TAG, "setUp()");
+        mTestStats = new TestSatelliteStats();
+        mControllerMetricsStatsUT =
+                new TestControllerMetricsStats(mMockContext, mTestStats);
+        mMockContext = mock(Context.class);
+        mMockSatelliteStats = mock(SatelliteStats.class);
+        mSpyControllerMetricsStats =
+                Mockito.spy(ControllerMetricsStats.make(mMockContext, mMockSatelliteStats));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        Rlog.d(TAG, "tearDown()");
+        mTestStats = null;
+        mControllerMetricsStatsUT = null;
+        mMockSatelliteStats = null;
+        mSpyControllerMetricsStats = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testReportServiceEnablementSuccessCount() {
+        mTestStats.initializeParams();
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportServiceEnablementSuccessCount();
+        }
+        assertEquals(10, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testReportServiceEnablementFailCount() {
+        mTestStats.initializeParams();
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportServiceEnablementFailCount();
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(10, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testReportOutgoingDatagramSuccessCount() {
+        mTestStats.initializeParams();
+        int datagramType = SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramSuccessCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(10, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        datagramType = SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramSuccessCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(10, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        datagramType = SatelliteManager.DATAGRAM_TYPE_UNKNOWN;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramSuccessCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void reportOutgoingDatagramFailCount() {
+        mTestStats.initializeParams();
+        int datagramType = SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramFailCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(10, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        datagramType = SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramFailCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(10, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        datagramType = SatelliteManager.DATAGRAM_TYPE_UNKNOWN;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportOutgoingDatagramFailCount(datagramType);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(10, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testReportIncomingDatagramCount() {
+        mTestStats.initializeParams();
+
+        int result = SatelliteManager.SATELLITE_ERROR_NONE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportIncomingDatagramCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(10, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_SERVER_ERROR;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportIncomingDatagramCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(10, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportIncomingDatagramCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(10, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testReportProvisionCount() {
+        mTestStats.initializeParams();
+
+        int result = SatelliteManager.SATELLITE_ERROR_NONE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportProvisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(10, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_SERVER_ERROR;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportProvisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(10, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportProvisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(10, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testReportDeprovisionCount() {
+        mTestStats.initializeParams();
+
+        int result = SatelliteManager.SATELLITE_ERROR_NONE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportDeprovisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(10, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(0, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_SERVER_ERROR;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportDeprovisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(10, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+
+        result = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+        for (int i = 0; i < 10; i++) {
+            mControllerMetricsStatsUT.reportDeprovisionCount(result);
+        }
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsSuccess);
+        assertEquals(0, mTestStats.mCountOfSatelliteServiceEnablementsFail);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfOutgoingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramSuccess);
+        assertEquals(0, mTestStats.mCountOfIncomingDatagramFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeSosSmsFail);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingSuccess);
+        assertEquals(0, mTestStats.mCountOfDatagramTypeLocationSharingFail);
+        assertEquals(0, mTestStats.mCountOfProvisionSuccess);
+        assertEquals(0, mTestStats.mCountOfProvisionFail);
+        assertEquals(0, mTestStats.mCountOfDeprovisionSuccess);
+        assertEquals(10, mTestStats.mCountOfDeprovisionFail);
+        assertEquals(0, mTestStats.mTotalServiceUptimeSec);
+        assertEquals(0, mTestStats.mTotalBatteryConsumptionPercent);
+        assertEquals(0, mTestStats.mTotalBatteryChargedTimeSec);
+        mTestStats.initializeParams();
+    }
+
+    @Test
+    public void testOnSatelliteEnabled() {
+        // set precondition
+        doReturn(false).when(mSpyControllerMetricsStats).isSatelliteModemOn();
+
+        doNothing().when(mSpyControllerMetricsStats).startCaptureBatteryLevel();
+        doReturn(MODEM_ENABLED_TIME).when(mSpyControllerMetricsStats).getCurrentTime();
+
+        // test object
+        mSpyControllerMetricsStats.onSatelliteEnabled();
+
+        // verification
+        verify(mSpyControllerMetricsStats).startCaptureBatteryLevel();
+        verify(mSpyControllerMetricsStats).getCurrentTime();
+    }
+
+    @Test
+    public void testOnSatelliteDisabled() {
+        // set precondition
+        doNothing().when(mMockSatelliteStats).onSatelliteControllerMetrics(any());
+
+        doReturn(true).when(mSpyControllerMetricsStats).isSatelliteModemOn();
+
+        doReturn(0).when(mSpyControllerMetricsStats).captureTotalServiceUpTimeSec();
+        doReturn(0).when(mSpyControllerMetricsStats).captureTotalBatteryConsumptionPercent(any());
+        doReturn(0).when(mSpyControllerMetricsStats).captureTotalBatteryChargeTimeSec();
+
+        // test object
+        mSpyControllerMetricsStats.onSatelliteDisabled();
+
+        // verification
+        verify(mSpyControllerMetricsStats).captureTotalServiceUpTimeSec();
+        verify(mSpyControllerMetricsStats).captureTotalBatteryConsumptionPercent(any());
+        verify(mSpyControllerMetricsStats).captureTotalBatteryChargeTimeSec();
+    }
+
+    static class TestControllerMetricsStats extends ControllerMetricsStats {
+        TestControllerMetricsStats(Context context, SatelliteStats satelliteStats) {
+            super(context, satelliteStats);
+        }
+    }
+
+    static class TestSatelliteStats extends SatelliteStats {
+        public int mCountOfSatelliteServiceEnablementsSuccess;
+        public int mCountOfSatelliteServiceEnablementsFail;
+        public int mCountOfOutgoingDatagramSuccess;
+        public int mCountOfOutgoingDatagramFail;
+        public int mCountOfIncomingDatagramSuccess;
+        public int mCountOfIncomingDatagramFail;
+        public int mCountOfDatagramTypeSosSmsSuccess;
+        public int mCountOfDatagramTypeSosSmsFail;
+        public int mCountOfDatagramTypeLocationSharingSuccess;
+        public int mCountOfDatagramTypeLocationSharingFail;
+        public int mCountOfProvisionSuccess;
+        public int mCountOfProvisionFail;
+        public int mCountOfDeprovisionSuccess;
+        public int mCountOfDeprovisionFail;
+        public int mTotalServiceUptimeSec;
+        public int mTotalBatteryConsumptionPercent;
+        public int mTotalBatteryChargedTimeSec;
+
+        @Override
+        public synchronized void onSatelliteControllerMetrics(SatelliteControllerParams param) {
+            mCountOfSatelliteServiceEnablementsSuccess +=
+                    param.getCountOfSatelliteServiceEnablementsSuccess();
+            mCountOfSatelliteServiceEnablementsFail +=
+                    param.getCountOfSatelliteServiceEnablementsFail();
+            mCountOfOutgoingDatagramSuccess += param.getCountOfOutgoingDatagramSuccess();
+            mCountOfOutgoingDatagramFail += param.getCountOfOutgoingDatagramFail();
+            mCountOfIncomingDatagramSuccess += param.getCountOfIncomingDatagramSuccess();
+            mCountOfIncomingDatagramFail += param.getCountOfIncomingDatagramFail();
+            mCountOfDatagramTypeSosSmsSuccess += param.getCountOfDatagramTypeSosSmsSuccess();
+            mCountOfDatagramTypeSosSmsFail += param.getCountOfDatagramTypeSosSmsFail();
+            mCountOfDatagramTypeLocationSharingSuccess +=
+                    param.getCountOfDatagramTypeLocationSharingSuccess();
+            mCountOfDatagramTypeLocationSharingFail +=
+                    param.getCountOfDatagramTypeLocationSharingFail();
+            mCountOfProvisionSuccess += param.getCountOfProvisionSuccess();
+            mCountOfProvisionFail += param.getCountOfProvisionFail();
+            mCountOfDeprovisionSuccess += param.getCountOfDeprovisionSuccess();
+            mCountOfDeprovisionFail += param.getCountOfDeprovisionFail();
+            mTotalServiceUptimeSec += param.getTotalServiceUptimeSec();
+            mTotalBatteryConsumptionPercent += param.getTotalBatteryConsumptionPercent();
+            mTotalBatteryChargedTimeSec += param.getTotalBatteryChargedTimeSec();
+        }
+
+        public void initializeParams() {
+            mCountOfSatelliteServiceEnablementsSuccess = 0;
+            mCountOfSatelliteServiceEnablementsFail = 0;
+            mCountOfOutgoingDatagramSuccess = 0;
+            mCountOfOutgoingDatagramFail = 0;
+            mCountOfIncomingDatagramSuccess = 0;
+            mCountOfIncomingDatagramFail = 0;
+            mCountOfDatagramTypeSosSmsSuccess = 0;
+            mCountOfDatagramTypeSosSmsFail = 0;
+            mCountOfDatagramTypeLocationSharingSuccess = 0;
+            mCountOfDatagramTypeLocationSharingFail = 0;
+            mCountOfProvisionSuccess = 0;
+            mCountOfProvisionFail = 0;
+            mCountOfDeprovisionSuccess = 0;
+            mCountOfDeprovisionFail = 0;
+            mTotalServiceUptimeSec = 0;
+            mTotalBatteryConsumptionPercent = 0;
+            mTotalBatteryChargedTimeSec = 0;
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
new file mode 100644
index 0000000..bc1d767
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.android.internal.telephony.satellite.DatagramController.SATELLITE_ALIGN_TIMEOUT;
+
+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.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DatagramDispatcherTest extends TelephonyTest {
+    private static final String TAG = "DatagramDispatcherTest";
+    private static final int SUB_ID = 0;
+    private static final int DATAGRAM_TYPE1 = SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE;
+    private static final int DATAGRAM_TYPE2 = SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING;
+    private static final String TEST_MESSAGE = "This is a test datagram message";
+    private static final long TEST_EXPIRE_TIMER_SATELLITE_ALIGN = TimeUnit.SECONDS.toMillis(1);
+
+    private DatagramDispatcher mDatagramDispatcherUT;
+    private TestDatagramDispatcher mTestDemoModeDatagramDispatcher;
+
+    @Mock private DatagramController mMockDatagramController;
+    @Mock private DatagramReceiver mMockDatagramReceiver;
+    @Mock private SatelliteModemInterface mMockSatelliteModemInterface;
+    @Mock private ControllerMetricsStats mMockControllerMetricsStats;
+
+    /** Variables required to send datagram in the unit tests. */
+    LinkedBlockingQueue<Integer> mResultListener;
+    SatelliteDatagram mDatagram;
+    InOrder mInOrder;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+        logd(TAG + " Setup!");
+
+        replaceInstance(DatagramController.class, "sInstance", null,
+                mMockDatagramController);
+        replaceInstance(DatagramReceiver.class, "sInstance", null,
+                mMockDatagramReceiver);
+        replaceInstance(SatelliteModemInterface.class, "sInstance", null,
+                mMockSatelliteModemInterface);
+        replaceInstance(ControllerMetricsStats.class, "sInstance", null,
+                mMockControllerMetricsStats);
+
+        mDatagramDispatcherUT = DatagramDispatcher.make(mContext, Looper.myLooper(),
+                mMockDatagramController);
+        mTestDemoModeDatagramDispatcher = new TestDatagramDispatcher(mContext, Looper.myLooper(),
+                mMockDatagramController);
+
+        mResultListener = new LinkedBlockingQueue<>(1);
+        mDatagram = new SatelliteDatagram(TEST_MESSAGE.getBytes());
+        mInOrder = inOrder(mMockDatagramController);
+        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        logd(TAG + " tearDown");
+        mDatagramDispatcherUT.destroy();
+        mDatagramDispatcherUT = null;
+        mTestDemoModeDatagramDispatcher = null;
+        mResultListener = null;
+        mDatagram = null;
+        mInOrder = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_usingSatelliteModemInterface_success() throws  Exception {
+        doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[3];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                    new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(any(SatelliteDatagram.class),
+                anyBoolean(), anyBoolean(), any(Message.class));
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verifyNoMoreInteractions(mMockDatagramController);
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_usingSatelliteModemInterface_failure() throws  Exception {
+        doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[3];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null,
+                                    new SatelliteManager.SatelliteException(
+                                            SatelliteManager.SATELLITE_SERVICE_ERROR)))
+                    .sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).sendSatelliteDatagram(any(SatelliteDatagram.class),
+                anyBoolean(), anyBoolean(), any(Message.class));
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE2, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED), eq(0),
+                        eq(SatelliteManager.SATELLITE_SERVICE_ERROR));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verifyNoMoreInteractions(mMockDatagramController);
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_SERVICE_ERROR);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_usingCommandsInterface_phoneNull() throws Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {null});
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED), eq(0),
+                        eq(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verifyNoMoreInteractions(mMockDatagramController);
+
+        assertThat(mResultListener.peek())
+                .isEqualTo(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_usingCommandsInterface_success() throws  Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).sendSatelliteDatagram(any(Message.class), any(SatelliteDatagram.class),
+                anyBoolean());
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE2, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verifyNoMoreInteractions(mMockDatagramController);
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_usingCommandsInterface_failure() throws  Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null,
+                                    new SatelliteManager.SatelliteException(
+                                            SatelliteManager.SATELLITE_SERVICE_ERROR)))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).sendSatelliteDatagram(any(Message.class), any(SatelliteDatagram.class),
+                anyBoolean());
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED), eq(0),
+                        eq(SatelliteManager.SATELLITE_SERVICE_ERROR));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verifyNoMoreInteractions(mMockDatagramController);
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_SERVICE_ERROR);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_DemoMode_Align_Success() throws Exception {
+        mTestDemoModeDatagramDispatcher.setDemoMode(true);
+        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(true);
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).sendSatelliteDatagram(any(Message.class), any(SatelliteDatagram.class),
+                anyBoolean());
+
+        mTestDemoModeDatagramDispatcher.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+        mTestDemoModeDatagramDispatcher.setDemoMode(false);
+        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(false);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_DemoMode_Align_failed() throws Exception {
+        long previousTimer = mTestDemoModeDatagramDispatcher.getSatelliteAlignedTimeoutDuration();
+        mTestDemoModeDatagramDispatcher.setDemoMode(true);
+        mTestDemoModeDatagramDispatcher.setDuration(TEST_EXPIRE_TIMER_SATELLITE_ALIGN);
+        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(false);
+
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mTestDemoModeDatagramDispatcher.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).sendSatelliteDatagram(any(Message.class), any(SatelliteDatagram.class),
+                anyBoolean());
+
+        mTestDemoModeDatagramDispatcher.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        processAllFutureMessages();
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED),
+                        anyInt(), eq(SatelliteManager.SATELLITE_NOT_REACHABLE));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_NOT_REACHABLE);
+        mTestDemoModeDatagramDispatcher.setDemoMode(false);
+        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(false);
+        mTestDemoModeDatagramDispatcher.setDuration(previousTimer);
+    }
+
+    @Test
+    public void testSendSatelliteDatagram_DemoMode_data_type_location_sharing() throws Exception {
+        mTestDemoModeDatagramDispatcher.setDemoMode(true);
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramDispatcherUT.obtainMessage(2 /*EVENT_SEND_SATELLITE_DATAGRAM_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).sendSatelliteDatagram(any(Message.class), any(SatelliteDatagram.class),
+                anyBoolean());
+
+        mTestDemoModeDatagramDispatcher.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE2, mDatagram,
+                true, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        mTestDemoModeDatagramDispatcher.setDemoMode(false);
+        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(false);
+    }
+
+    @Test
+    public void testSatelliteModemBusy_modemPollingDatagram_sendingDelayed() {
+        when(mMockDatagramController.isPollingInIdleState()).thenReturn(false);
+
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+        processAllMessages();
+        // As modem is busy receiving datagrams, sending datagram did not proceed further.
+        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+        verifyNoMoreInteractions(mMockDatagramController);
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateListening() {
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+        processAllMessages();
+        verifyNoMoreInteractions(mMockDatagramController);
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateOff_modemSendingDatagrams() {
+        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
+                true, mResultListener::offer);
+
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED),
+                        eq(1), eq(SatelliteManager.SATELLITE_REQUEST_ABORTED));
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateOff_modemNotSendingDatagrams() {
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateSendStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    private static class TestDatagramDispatcher extends DatagramDispatcher {
+        private long mLong = SATELLITE_ALIGN_TIMEOUT;
+
+        TestDatagramDispatcher(@NonNull Context context, @NonNull Looper looper,
+                @NonNull DatagramController datagramController) {
+            super(context, looper, datagramController);
+        }
+
+        @Override
+        protected void setDemoMode(boolean isDemoMode) {
+            super.setDemoMode(isDemoMode);
+        }
+
+        @Override
+        protected  void onDeviceAlignedWithSatellite(boolean isAligned) {
+            super.onDeviceAlignedWithSatellite(isAligned);
+        }
+
+        @Override
+        protected long getSatelliteAlignedTimeoutDuration() {
+            return mLong;
+        }
+
+        public void setDuration(long duration) {
+            mLong = duration;
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
new file mode 100644
index 0000000..1c3777d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.android.internal.telephony.satellite.DatagramController.SATELLITE_ALIGN_TIMEOUT;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.provider.Telephony;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.test.mock.MockContentResolver;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+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 static org.mockito.Mockito.when;
+
+import android.os.AsyncResult;
+import android.os.Looper;
+import android.os.Message;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.util.Pair;
+
+import com.android.internal.telephony.IVoidConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DatagramReceiverTest extends TelephonyTest {
+    private static final String TAG = "DatagramReceiverTest";
+    private static final int SUB_ID = 0;
+    private static final String TEST_MESSAGE = "This is a test datagram message";
+    private static final long TEST_EXPIRE_TIMER_SATELLITE_ALIGN = TimeUnit.SECONDS.toMillis(1);
+
+    private DatagramReceiver mDatagramReceiverUT;
+    private DatagramReceiver.SatelliteDatagramListenerHandler mSatelliteDatagramListenerHandler;
+    private TestDatagramReceiver mTestDemoModeDatagramReceiver;
+
+    @Mock private SatelliteController mMockSatelliteController;
+    @Mock private DatagramController mMockDatagramController;
+    @Mock private SatelliteModemInterface mMockSatelliteModemInterface;
+    @Mock private ControllerMetricsStats mMockControllerMetricsStats;
+
+    /** Variables required to receive datagrams in the unit tests. */
+    LinkedBlockingQueue<Integer> mResultListener;
+    SatelliteDatagram mDatagram;
+    InOrder mInOrder;
+    private FakeSatelliteProvider mFakeSatelliteProvider;
+    private MockContentResolver mMockContentResolver;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+        logd(TAG + " Setup!");
+
+        // Setup mock satellite provider DB.
+        mFakeSatelliteProvider = new FakeSatelliteProvider();
+        mMockContentResolver = new MockContentResolver();
+        mMockContentResolver.addProvider(
+                Telephony.SatelliteDatagrams.PROVIDER_NAME, mFakeSatelliteProvider);
+        doReturn(mMockContentResolver).when(mContext).getContentResolver();
+
+        replaceInstance(SatelliteController.class, "sInstance", null, mMockSatelliteController);
+        replaceInstance(DatagramController.class, "sInstance", null,
+                mMockDatagramController);
+        replaceInstance(SatelliteModemInterface.class, "sInstance", null,
+                mMockSatelliteModemInterface);
+        replaceInstance(ControllerMetricsStats.class, "sInstance", null,
+                mMockControllerMetricsStats);
+
+        mDatagramReceiverUT = DatagramReceiver.make(mContext, Looper.myLooper(),
+                mMockDatagramController);
+        mTestDemoModeDatagramReceiver = new TestDatagramReceiver(mContext, Looper.myLooper(),
+                mMockDatagramController);
+        mSatelliteDatagramListenerHandler = new DatagramReceiver.SatelliteDatagramListenerHandler(
+                Looper.myLooper(), SUB_ID);
+
+        mResultListener = new LinkedBlockingQueue<>(1);
+        mDatagram = new SatelliteDatagram(TEST_MESSAGE.getBytes());
+        mInOrder = inOrder(mMockDatagramController);
+
+        when(mMockDatagramController.isSendingInIdleState()).thenReturn(true);
+        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
+        processAllMessages();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        logd(TAG + " tearDown");
+        mFakeSatelliteProvider.shutdown();
+        mDatagramReceiverUT.destroy();
+        mDatagramReceiverUT = null;
+        mTestDemoModeDatagramReceiver = null;
+        mResultListener = null;
+        mDatagram = null;
+        mInOrder = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_usingSatelliteModemInterface_success()
+            throws Exception {
+        doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramReceiverUT.obtainMessage(2 /*EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).pollPendingSatelliteDatagrams(any(Message.class));
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_usingSatelliteModemInterface_failure()
+            throws Exception {
+        doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramReceiverUT.obtainMessage(2 /*EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE*/,
+                            new AsyncResult(message.obj, null,
+                                    new SatelliteManager.SatelliteException(
+                                            SatelliteManager.SATELLITE_SERVICE_ERROR)))
+                    .sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).pollPendingSatelliteDatagrams(any(Message.class));
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        eq(0), eq(SatelliteManager.SATELLITE_SERVICE_ERROR));
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_SERVICE_ERROR);
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_usingCommandsInterface_phoneNull()
+            throws Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {null});
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        eq(0), eq(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        assertThat(mResultListener.peek())
+                .isEqualTo(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_usingCommandsInterface_success()
+            throws Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramReceiverUT.obtainMessage(2 /*EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE*/,
+                            new AsyncResult(message.obj, null, null))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).pollPendingSatelliteDatagrams(any(Message.class));
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_ERROR_NONE);
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_usingCommandsInterface_failure()
+            throws Exception {
+        doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone});
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+
+            mDatagramReceiverUT.obtainMessage(2 /*EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE*/,
+                            new AsyncResult(message.obj, null,
+                                    new SatelliteManager.SatelliteException(
+                                            SatelliteManager.SATELLITE_SERVICE_ERROR)))
+                    .sendToTarget();
+            return null;
+        }).when(mPhone).pollPendingSatelliteDatagrams(any(Message.class));
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING), eq(0),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        eq(0), eq(SatelliteManager.SATELLITE_SERVICE_ERROR));
+
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_SERVICE_ERROR);
+    }
+
+    @Test
+    public void testSatelliteDatagramReceived_receiveNone() {
+        mSatelliteDatagramListenerHandler.obtainMessage(1 /*EVENT_SATELLITE_DATAGRAM_RECEIVED*/,
+                new AsyncResult(null, new Pair<>(null, 0), null))
+                .sendToTarget();
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testSatelliteDatagramReceived_success_zeroPendingCount() {
+        mSatelliteDatagramListenerHandler.obtainMessage(1 /*EVENT_SATELLITE_DATAGRAM_RECEIVED*/,
+                        new AsyncResult(null, new Pair<>(mDatagram, 0), null))
+                .sendToTarget();
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testSatelliteDatagramReceived_success_nonZeroPendingCount() {
+        mSatelliteDatagramListenerHandler.obtainMessage(1 /*EVENT_SATELLITE_DATAGRAM_RECEIVED*/,
+                        new AsyncResult(null, new Pair<>(mDatagram, 10), null))
+                .sendToTarget();
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS),
+                        eq(10), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_DemoMode_Align_succeed() throws Exception {
+        // Checks invalid case only as SatelliteController does not exist in unit test
+        mTestDemoModeDatagramReceiver.setDemoMode(true);
+        mTestDemoModeDatagramReceiver.onDeviceAlignedWithSatellite(true);
+        when(mMockDatagramController.getDemoModeDatagram()).thenReturn(mDatagram);
+        mTestDemoModeDatagramReceiver.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+        processAllMessages();
+        verify(mMockDatagramController, times(1)).getDemoModeDatagram();
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE));
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        assertThat(mResultListener.peek())
+                .isEqualTo(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams_DemoMode_Align_failed() throws Exception {
+        // Checks invalid case only as SatelliteController does not exist in unit test
+        long previousTimer = mTestDemoModeDatagramReceiver.getSatelliteAlignedTimeoutDuration();
+        mTestDemoModeDatagramReceiver.setDemoMode(true);
+        mTestDemoModeDatagramReceiver.setDuration(TEST_EXPIRE_TIMER_SATELLITE_ALIGN);
+        mTestDemoModeDatagramReceiver.onDeviceAlignedWithSatellite(false);
+        when(mMockDatagramController.getDemoModeDatagram()).thenReturn(mDatagram);
+        mTestDemoModeDatagramReceiver.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+        processAllMessages();
+        verify(mMockDatagramController, never()).getDemoModeDatagram();
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        processAllFutureMessages();
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_NOT_REACHABLE));
+        verify(mMockDatagramController)
+                .updateReceiveStatus(eq(SUB_ID),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        anyInt(),
+                        eq(SatelliteManager.SATELLITE_ERROR_NONE));
+        assertThat(mResultListener.peek())
+                .isEqualTo(SatelliteManager.SATELLITE_NOT_REACHABLE);
+
+        mTestDemoModeDatagramReceiver.setDemoMode(false);
+        mTestDemoModeDatagramReceiver.onDeviceAlignedWithSatellite(false);
+        mTestDemoModeDatagramReceiver.setDuration(previousTimer);
+    }
+
+    @Test
+    public void testSatelliteModemBusy_modemSendingDatagram_pollingFailure() {
+        when(mMockDatagramController.isSendingInIdleState()).thenReturn(false);
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+        processAllMessages();
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_MODEM_BUSY);
+    }
+
+    @Test
+    public void testSatelliteModemBusy_modemPollingDatagrams_pollingFailure() {
+        when(mMockDatagramController.isSendingInIdleState()).thenReturn(false);
+        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
+
+        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
+        processAllMessages();
+        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_MODEM_BUSY);
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateIdle() {
+        mDatagramReceiverUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        processAllMessages();
+        verifyNoMoreInteractions(mMockDatagramController);
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateOff_modemReceivingDatagrams() {
+        when(mMockDatagramController.isReceivingDatagrams()).thenReturn(true);
+        when(mMockDatagramController.getReceivePendingCount()).thenReturn(10);
+
+        mDatagramReceiverUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED),
+                        eq(10), eq(SatelliteManager.SATELLITE_REQUEST_ABORTED));
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_modemStateOff_modemNotReceivingDatagrams() {
+        when(mMockDatagramController.isReceivingDatagrams()).thenReturn(false);
+
+        mDatagramReceiverUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+
+        processAllMessages();
+
+        mInOrder.verify(mMockDatagramController)
+                .updateReceiveStatus(anyInt(),
+                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
+                        eq(0), eq(SatelliteManager.SATELLITE_ERROR_NONE));
+    }
+
+    @Test
+    public void testRegisterForSatelliteDatagram_satelliteNotSupported() {
+        when(mMockSatelliteController.isSatelliteSupported()).thenReturn(false);
+
+        ISatelliteDatagramCallback callback = new ISatelliteDatagramCallback() {
+            @Override
+            public void onSatelliteDatagramReceived(long datagramId, SatelliteDatagram datagram,
+                    int pendingCount, IVoidConsumer callback) throws RemoteException {
+                logd("onSatelliteDatagramReceived");
+            }
+
+            @Override
+            public IBinder asBinder() {
+                return null;
+            }
+        };
+
+        assertThat(mDatagramReceiverUT.registerForSatelliteDatagram(SUB_ID, callback))
+                .isEqualTo(SatelliteManager.SATELLITE_NOT_SUPPORTED);
+    }
+
+    private static class TestDatagramReceiver extends DatagramReceiver {
+        private long mLong =  SATELLITE_ALIGN_TIMEOUT;
+
+        TestDatagramReceiver(@NonNull Context context, @NonNull Looper looper,
+                @NonNull DatagramController datagramController) {
+            super(context, looper, datagramController);
+        }
+
+        @Override
+        protected void setDemoMode(boolean isDemoMode) {
+            super.setDemoMode(isDemoMode);
+        }
+
+        @Override
+        protected void onDeviceAlignedWithSatellite(boolean isAligned) {
+            super.onDeviceAlignedWithSatellite(isAligned);
+        }
+
+        @Override
+        protected long getSatelliteAlignedTimeoutDuration() {
+            return mLong;
+        }
+
+        public void setDuration(long duration) {
+            mLong = duration;
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/FakeSatelliteProvider.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/FakeSatelliteProvider.java
new file mode 100644
index 0000000..b0c6a81
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/FakeSatelliteProvider.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Telephony;
+import android.test.mock.MockContentProvider;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+public class FakeSatelliteProvider extends MockContentProvider {
+    private static final String TAG = "FakeSatelliteProvider";
+
+    private InMemorySatelliteProviderDbHelper mDbHelper = new InMemorySatelliteProviderDbHelper();
+
+    private class InMemorySatelliteProviderDbHelper extends SQLiteOpenHelper {
+
+        InMemorySatelliteProviderDbHelper() {
+            super(InstrumentationRegistry.getTargetContext(),
+                    null,    // db file name is null for in-memory db
+                    null,    // CursorFactory is null by default
+                    1);      // db version is no-op for tests
+            Log.d(TAG, "InMemorySatelliteProviderDbHelper creating in-memory database");
+        }
+        public static String getStringForDatagramTableCreation(String tableName) {
+            return "CREATE TABLE " + tableName + "("
+                    + Telephony.SatelliteDatagrams.COLUMN_UNIQUE_KEY_DATAGRAM_ID
+                    + " INTEGER PRIMARY KEY,"
+                    + Telephony.SatelliteDatagrams.COLUMN_DATAGRAM + " BLOB DEFAULT ''" +
+                    ");";
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            Log.d(TAG, "InMemoryTelephonyProviderDbHelper onCreate:"
+                    + " creating satellite incoming datagram table");
+            db.execSQL(getStringForDatagramTableCreation(Telephony.SatelliteDatagrams.TABLE_NAME));
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            // Do nothing.
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        Log.d(TAG, "insert. values=" + values);
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        long id = db.insert(Telephony.SatelliteDatagrams.TABLE_NAME, null, values);
+        return ContentUris.withAppendedId(Telephony.SatelliteDatagrams.CONTENT_URI, id);
+    }
+
+    @Override
+    public synchronized int delete(Uri url, String where, String[] whereArgs) {
+        return mDbHelper.getWritableDatabase()
+                .delete(Telephony.SatelliteDatagrams.TABLE_NAME, where, whereArgs);
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return mDbHelper.getReadableDatabase().query(Telephony.SatelliteDatagrams.TABLE_NAME,
+                projection, selection, selectionArgs, null, null, sortOrder);
+    }
+
+    @Override
+    public Bundle call(String method, String request, Bundle args) {
+        return null;
+    }
+
+    @Override
+    public final int update(Uri uri, ContentValues values, String where, String[] selectionArgs) {
+        // Do nothing.
+        return 0;
+    }
+
+    @Override
+    public void shutdown() {
+        mDbHelper.close();
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteCapabilitiesTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteCapabilitiesTest.java
new file mode 100644
index 0000000..29473c9
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteCapabilitiesTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+import android.telephony.satellite.AntennaDirection;
+import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteManager;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class SatelliteCapabilitiesTest {
+
+    private AntennaDirection mAntennaDirection = new AntennaDirection(1,1,1);
+
+    @Test
+    public void testParcel() {
+        Set<Integer> satelliteRadioTechnologies = new HashSet<>();
+        satelliteRadioTechnologies.add(SatelliteManager.NT_RADIO_TECHNOLOGY_NB_IOT_NTN);
+        satelliteRadioTechnologies.add(SatelliteManager.NT_RADIO_TECHNOLOGY_NR_NTN);
+
+        Map<Integer, AntennaPosition> antennaPositionMap = new HashMap<>();
+        AntennaPosition antennaPosition = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+        antennaPositionMap.put(SatelliteManager.DISPLAY_MODE_OPENED, antennaPosition);
+
+        SatelliteCapabilities capabilities = new SatelliteCapabilities(satelliteRadioTechnologies,
+                true, 10, antennaPositionMap);
+
+        Parcel p = Parcel.obtain();
+        capabilities.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        SatelliteCapabilities fromParcel = SatelliteCapabilities.CREATOR.createFromParcel(p);
+        assertThat(capabilities).isEqualTo(fromParcel);
+    }
+
+    @Test
+    public void testParcel_emptySatelliteRadioTechnologies() {
+        Set<Integer> satelliteRadioTechnologies = new HashSet<>();
+
+        Map<Integer, AntennaPosition> antennaPositionMap = new HashMap<>();
+        AntennaPosition antennaPosition1 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+        AntennaPosition antennaPosition2 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT);
+        antennaPositionMap.put(SatelliteManager.DISPLAY_MODE_OPENED, antennaPosition1);
+        antennaPositionMap.put(SatelliteManager.DISPLAY_MODE_CLOSED, antennaPosition2);
+
+        SatelliteCapabilities capabilities = new SatelliteCapabilities(satelliteRadioTechnologies,
+                false, 100, antennaPositionMap);
+
+        Parcel p = Parcel.obtain();
+        capabilities.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        SatelliteCapabilities fromParcel = SatelliteCapabilities.CREATOR.createFromParcel(p);
+        assertThat(capabilities).isEqualTo(fromParcel);
+    }
+
+
+    @Test
+    public void testParcel_emptyAntennaPosition() {
+        Set<Integer> satelliteRadioTechnologies = new HashSet<>();
+        satelliteRadioTechnologies.add(SatelliteManager.NT_RADIO_TECHNOLOGY_EMTC_NTN);
+
+        SatelliteCapabilities capabilities = new SatelliteCapabilities(satelliteRadioTechnologies,
+                true, 0, new HashMap<>());
+
+        Parcel p = Parcel.obtain();
+        capabilities.writeToParcel(p, 0);
+        p.setDataPosition(0);
+
+        SatelliteCapabilities fromParcel = SatelliteCapabilities.CREATOR.createFromParcel(p);
+        assertThat(capabilities).isEqualTo(fromParcel);
+    }
+
+    @Test
+    public void testEquals() {
+        Set<Integer> satelliteRadioTechnologies = new HashSet<>();
+        satelliteRadioTechnologies.add(SatelliteManager.NT_RADIO_TECHNOLOGY_NB_IOT_NTN);
+        satelliteRadioTechnologies.add(SatelliteManager.NT_RADIO_TECHNOLOGY_NR_NTN);
+
+        AntennaPosition antennaPosition1 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT);
+        AntennaPosition antennaPosition2 = new AntennaPosition(mAntennaDirection,
+                SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT);
+
+        Map<Integer, AntennaPosition> antennaPositionMap1 = new HashMap<>();
+        antennaPositionMap1.put(SatelliteManager.DISPLAY_MODE_OPENED, antennaPosition1);
+        antennaPositionMap1.put(SatelliteManager.DISPLAY_MODE_CLOSED, antennaPosition2);
+
+        SatelliteCapabilities satelliteCapabilities1 =
+                new SatelliteCapabilities(satelliteRadioTechnologies, true, 10,
+                        antennaPositionMap1);
+        SatelliteCapabilities satelliteCapabilities2 =
+                new SatelliteCapabilities(satelliteRadioTechnologies, true, 10,
+                        antennaPositionMap1);
+        assertEquals(satelliteCapabilities1, satelliteCapabilities2);
+
+        Map<Integer, AntennaPosition> antennaPositionMap2 = new HashMap<>();
+        antennaPositionMap2.put(SatelliteManager.DISPLAY_MODE_CLOSED, antennaPosition1);
+        antennaPositionMap2.put(SatelliteManager.DISPLAY_MODE_OPENED, antennaPosition2);
+        satelliteCapabilities2 =
+                new SatelliteCapabilities(satelliteRadioTechnologies, true, 10,
+                        antennaPositionMap2);
+        assertNotEquals(satelliteCapabilities1, satelliteCapabilities2);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
new file mode 100644
index 0000000..f6ed2e2
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -0,0 +1,2025 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static android.telephony.satellite.SatelliteManager.KEY_DEMO_MODE_ENABLED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_CAPABILITIES;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ENABLED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_NEXT_VISIBILITY;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_EMTC_NTN;
+import static android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_NR_NTN;
+import static android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_PROPRIETARY;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_ERROR_NONE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_ARGUMENTS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_MODEM_STATE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_NOT_AUTHORIZED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_NOT_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_NO_RESOURCES;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_REQUEST_IN_PROGRESS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS;
+
+import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_FALSE;
+import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_TRUE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+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.doNothing;
+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.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ResultReceiver;
+import android.telephony.Rlog;
+import android.telephony.satellite.ISatelliteDatagramCallback;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteStateCallback;
+import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteManager.SatelliteException;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.IVoidConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.internal.telephony.satellite.metrics.ProvisionMetricsStats;
+import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
+
+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;
+
+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.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class SatelliteControllerTest extends TelephonyTest {
+    private static final String TAG = "SatelliteControllerTest";
+    private static final long TIMEOUT = 500;
+    private static final int SUB_ID = 0;
+    private static final int MAX_BYTES_PER_OUT_GOING_DATAGRAM = 339;
+    private static final String TEST_SATELLITE_TOKEN = "TEST_SATELLITE_TOKEN";
+    private static final String TEST_NEXT_SATELLITE_TOKEN = "TEST_NEXT_SATELLITE_TOKEN";
+
+    private TestSatelliteController mSatelliteControllerUT;
+    private TestSharedPreferences mSharedPreferences;
+
+    @Mock private DatagramController mMockDatagramController;
+    @Mock private SatelliteModemInterface mMockSatelliteModemInterface;
+    @Mock private SatelliteSessionController mMockSatelliteSessionController;
+    @Mock private PointingAppController mMockPointingAppController;
+    @Mock private ControllerMetricsStats mMockControllerMetricsStats;
+    @Mock private ProvisionMetricsStats mMockProvisionMetricsStats;
+    @Mock private SessionMetricsStats mMockSessionMetricsStats;
+    private List<Integer> mIIntegerConsumerResults =  new ArrayList<>();
+    @Mock private ISatelliteTransmissionUpdateCallback mStartTransmissionUpdateCallback;
+    @Mock private ISatelliteTransmissionUpdateCallback mStopTransmissionUpdateCallback;
+    private Semaphore mIIntegerConsumerSemaphore = new Semaphore(0);
+    private IIntegerConsumer mIIntegerConsumer = new IIntegerConsumer.Stub() {
+        @Override
+        public void accept(int result) {
+            logd("mIIntegerConsumer: result=" + result);
+            mIIntegerConsumerResults.add(result);
+            try {
+                mIIntegerConsumerSemaphore.release();
+            } catch (Exception ex) {
+                loge("mIIntegerConsumer: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private boolean mIsSatelliteServiceSupported = true;
+    private boolean mIsPointingRequired = true;
+    private Set<Integer> mSupportedRadioTechnologies = new HashSet<>(Arrays.asList(
+            NT_RADIO_TECHNOLOGY_NR_NTN,
+            NT_RADIO_TECHNOLOGY_EMTC_NTN,
+            NT_RADIO_TECHNOLOGY_PROPRIETARY));
+    private SatelliteCapabilities mSatelliteCapabilities = new SatelliteCapabilities(
+            mSupportedRadioTechnologies, mIsPointingRequired, MAX_BYTES_PER_OUT_GOING_DATAGRAM,
+            new HashMap<>());
+    private Semaphore mSatelliteCapabilitiesSemaphore = new Semaphore(0);
+    private SatelliteCapabilities mQueriedSatelliteCapabilities = null;
+    private int mQueriedSatelliteCapabilitiesResultCode = SATELLITE_ERROR_NONE;
+    private ResultReceiver mSatelliteCapabilitiesReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedSatelliteCapabilitiesResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_CAPABILITIES)) {
+                    mQueriedSatelliteCapabilities = resultData.getParcelable(
+                            KEY_SATELLITE_CAPABILITIES, SatelliteCapabilities.class);
+                } else {
+                    loge("KEY_SATELLITE_SUPPORTED does not exist.");
+                    mQueriedSatelliteCapabilities = null;
+                }
+            } else {
+                logd("mSatelliteSupportReceiver: resultCode=" + resultCode);
+                mQueriedSatelliteCapabilities = null;
+            }
+            try {
+                mSatelliteCapabilitiesSemaphore.release();
+            } catch (Exception ex) {
+                loge("mSatelliteSupportReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private boolean mQueriedSatelliteSupported = false;
+    private int mQueriedSatelliteSupportedResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mSatelliteSupportSemaphore = new Semaphore(0);
+    private ResultReceiver mSatelliteSupportReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedSatelliteSupportedResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) {
+                    mQueriedSatelliteSupported = resultData.getBoolean(KEY_SATELLITE_SUPPORTED);
+                } else {
+                    loge("KEY_SATELLITE_SUPPORTED does not exist.");
+                    mQueriedSatelliteSupported = false;
+                }
+            } else {
+                logd("mSatelliteSupportReceiver: resultCode=" + resultCode);
+                mQueriedSatelliteSupported = false;
+            }
+            try {
+                mSatelliteSupportSemaphore.release();
+            } catch (Exception ex) {
+                loge("mSatelliteSupportReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private boolean mQueriedIsSatelliteEnabled = false;
+    private int mQueriedIsSatelliteEnabledResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mIsSatelliteEnabledSemaphore = new Semaphore(0);
+    private ResultReceiver mIsSatelliteEnabledReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedIsSatelliteEnabledResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_ENABLED)) {
+                    mQueriedIsSatelliteEnabled = resultData.getBoolean(KEY_SATELLITE_ENABLED);
+                } else {
+                    loge("KEY_SATELLITE_ENABLED does not exist.");
+                    mQueriedIsSatelliteEnabled = false;
+                }
+            } else {
+                logd("mIsSatelliteEnableReceiver: resultCode=" + resultCode);
+                mQueriedIsSatelliteEnabled = false;
+            }
+            try {
+                mIsSatelliteEnabledSemaphore.release();
+            } catch (Exception ex) {
+                loge("mIsSatelliteEnableReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private boolean mQueriedIsDemoModeEnabled = false;
+    private int mQueriedIsDemoModeEnabledResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mIsDemoModeEnabledSemaphore = new Semaphore(0);
+    private ResultReceiver mIsDemoModeEnabledReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedIsDemoModeEnabledResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_DEMO_MODE_ENABLED)) {
+                    mQueriedIsDemoModeEnabled = resultData.getBoolean(KEY_DEMO_MODE_ENABLED);
+                } else {
+                    loge("KEY_DEMO_MODE_ENABLED does not exist.");
+                    mQueriedIsDemoModeEnabled = false;
+                }
+            } else {
+                logd("mIsSatelliteEnableReceiver: resultCode=" + resultCode);
+                mQueriedIsDemoModeEnabled = false;
+            }
+            try {
+                mIsDemoModeEnabledSemaphore.release();
+            } catch (Exception ex) {
+                loge("mIsDemoModeEnabledReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private boolean mQueriedIsSatelliteProvisioned = false;
+    private int mQueriedIsSatelliteProvisionedResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mIsSatelliteProvisionedSemaphore = new Semaphore(0);
+    private ResultReceiver mIsSatelliteProvisionedReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedIsSatelliteProvisionedResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+                    mQueriedIsSatelliteProvisioned =
+                            resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+                } else {
+                    loge("KEY_SATELLITE_PROVISIONED does not exist.");
+                    mQueriedIsSatelliteProvisioned = false;
+                }
+            } else {
+                mQueriedIsSatelliteProvisioned = false;
+            }
+            try {
+                mIsSatelliteProvisionedSemaphore.release();
+            } catch (Exception ex) {
+                loge("mIsSatelliteProvisionedReceiver: Got exception in releasing semaphore ex="
+                        + ex);
+            }
+        }
+    };
+
+    private boolean mQueriedSatelliteAllowed = false;
+    private int mQueriedSatelliteAllowedResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mSatelliteAllowedSemaphore = new Semaphore(0);
+    private ResultReceiver mSatelliteAllowedReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedSatelliteAllowedResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+                    mQueriedSatelliteAllowed = resultData.getBoolean(
+                            KEY_SATELLITE_COMMUNICATION_ALLOWED);
+                } else {
+                    loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+                    mQueriedSatelliteAllowed = false;
+                }
+            } else {
+                logd("mSatelliteSupportReceiver: resultCode=" + resultCode);
+                mQueriedSatelliteAllowed = false;
+            }
+            try {
+                mSatelliteAllowedSemaphore.release();
+            } catch (Exception ex) {
+                loge("mSatelliteAllowedReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+    private int mQueriedSatelliteVisibilityTime = -1;
+    private int mSatelliteNextVisibilityTime = 3600;
+    private int mQueriedSatelliteVisibilityTimeResultCode = SATELLITE_ERROR_NONE;
+    private Semaphore mSatelliteVisibilityTimeSemaphore = new Semaphore(0);
+    private ResultReceiver mSatelliteVisibilityTimeReceiver = new ResultReceiver(null) {
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            mQueriedSatelliteVisibilityTimeResultCode = resultCode;
+            if (resultCode == SATELLITE_ERROR_NONE) {
+                if (resultData.containsKey(KEY_SATELLITE_NEXT_VISIBILITY)) {
+                    mQueriedSatelliteVisibilityTime = resultData.getInt(
+                            KEY_SATELLITE_NEXT_VISIBILITY);
+                } else {
+                    loge("KEY_SATELLITE_NEXT_VISIBILITY does not exist.");
+                    mQueriedSatelliteVisibilityTime = -1;
+                }
+            } else {
+                logd("mSatelliteSupportReceiver: resultCode=" + resultCode);
+                mQueriedSatelliteVisibilityTime = -1;
+            }
+            try {
+                mSatelliteVisibilityTimeSemaphore.release();
+            } catch (Exception ex) {
+                loge("mSatelliteAllowedReceiver: Got exception in releasing semaphore, ex=" + ex);
+            }
+        }
+    };
+
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+        logd(TAG + " Setup!");
+
+        replaceInstance(DatagramController.class, "sInstance", null,
+                mMockDatagramController);
+        replaceInstance(SatelliteModemInterface.class, "sInstance", null,
+                mMockSatelliteModemInterface);
+        replaceInstance(SatelliteSessionController.class, "sInstance", null,
+                mMockSatelliteSessionController);
+        replaceInstance(PointingAppController.class, "sInstance", null,
+                mMockPointingAppController);
+        replaceInstance(ControllerMetricsStats.class, "sInstance", null,
+                mMockControllerMetricsStats);
+        replaceInstance(ProvisionMetricsStats.class, "sInstance", null,
+                mMockProvisionMetricsStats);
+        replaceInstance(SessionMetricsStats.class, "sInstance", null,
+                mMockSessionMetricsStats);
+
+        mSharedPreferences = new TestSharedPreferences();
+        when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences);
+        doReturn(mIsSatelliteServiceSupported)
+                .when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+        setUpResponseForRequestSatelliteCapabilities(
+                mSatelliteCapabilities, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RADIO_NOT_AVAILABLE);
+        doNothing().when(mMockDatagramController).setDemoMode(anyBoolean());
+        doNothing().when(mMockSatelliteSessionController)
+                .onSatelliteEnabledStateChanged(anyBoolean());
+        doNothing().when(mMockSatelliteSessionController).setDemoMode(anyBoolean());
+        doNothing().when(mMockControllerMetricsStats).onSatelliteEnabled();
+        doNothing().when(mMockControllerMetricsStats).reportServiceEnablementSuccessCount();
+        doNothing().when(mMockControllerMetricsStats).reportServiceEnablementFailCount();
+        doReturn(mMockSessionMetricsStats)
+                .when(mMockSessionMetricsStats).setInitializationResult(anyInt());
+        doReturn(mMockSessionMetricsStats)
+                .when(mMockSessionMetricsStats).setRadioTechnology(anyInt());
+        doNothing().when(mMockSessionMetricsStats).reportSessionMetrics();
+
+        doReturn(mMockProvisionMetricsStats).when(mMockProvisionMetricsStats)
+                .setResultCode(anyInt());
+        doReturn(mMockProvisionMetricsStats).when(mMockProvisionMetricsStats)
+                    .setIsProvisionRequest(eq(false));
+        doNothing().when(mMockProvisionMetricsStats).reportProvisionMetrics();
+        doNothing().when(mMockControllerMetricsStats).reportDeprovisionCount(anyInt());
+        mSatelliteControllerUT = new TestSatelliteController(mContext, Looper.myLooper());
+        verify(mMockSatelliteModemInterface).registerForSatelliteProvisionStateChanged(
+                any(Handler.class),
+                eq(26) /* EVENT_SATELLITE_PROVISION_STATE_CHANGED */,
+                eq(null));
+        verify(mMockSatelliteModemInterface).registerForPendingDatagrams(
+                any(Handler.class),
+                eq(27) /* EVENT_PENDING_DATAGRAMS */,
+                eq(null));
+        verify(mMockSatelliteModemInterface).registerForSatelliteModemStateChanged(
+                any(Handler.class),
+                eq(28) /* EVENT_SATELLITE_MODEM_STATE_CHANGED */,
+                eq(null));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        logd(TAG + " tearDown");
+        mSatelliteControllerUT = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void testRequestIsSatelliteCommunicationAllowedForCurrentLocation() {
+        mSatelliteAllowedSemaphore.drainPermits();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsSatelliteCommunicationAllowedForCurrentLocation(SUB_ID,
+                mSatelliteAllowedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, mQueriedSatelliteAllowedResultCode);
+
+        resetSatelliteControllerUT();
+        mSatelliteControllerUT.requestIsSatelliteCommunicationAllowedForCurrentLocation(SUB_ID,
+                mSatelliteAllowedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteAllowedResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteAllowedForCurrentLocation(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsSatelliteCommunicationAllowedForCurrentLocation(SUB_ID,
+                mSatelliteAllowedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, mQueriedSatelliteAllowedResultCode);
+        assertTrue(mQueriedSatelliteAllowed);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestIsSatelliteAllowedForCurrentLocation(SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsSatelliteCommunicationAllowedForCurrentLocation(SUB_ID,
+                mSatelliteAllowedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteAllowedResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestIsSatelliteAllowedForCurrentLocation(
+                SATELLITE_INVALID_MODEM_STATE);
+        mSatelliteControllerUT.requestIsSatelliteCommunicationAllowedForCurrentLocation(SUB_ID,
+                mSatelliteAllowedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteAllowedForCurrentLocationResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, mQueriedSatelliteAllowedResultCode);
+    }
+
+    @Test
+    public void testRequestTimeForNextSatelliteVisibility() {
+        mSatelliteVisibilityTimeSemaphore.drainPermits();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, mQueriedSatelliteVisibilityTimeResultCode);
+
+        resetSatelliteControllerUT();
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteVisibilityTimeResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestTimeForNextSatelliteVisibility(mSatelliteNextVisibilityTime,
+                SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteVisibilityTimeResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestTimeForNextSatelliteVisibility(mSatelliteNextVisibilityTime,
+                SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, mQueriedSatelliteVisibilityTimeResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestTimeForNextSatelliteVisibility(mSatelliteNextVisibilityTime,
+                SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, mQueriedSatelliteVisibilityTimeResultCode);
+        assertEquals(mSatelliteNextVisibilityTime, mQueriedSatelliteVisibilityTime);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestTimeForNextSatelliteVisibility(
+                SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteVisibilityTimeResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestTimeForNextSatelliteVisibility(
+                SATELLITE_INVALID_MODEM_STATE);
+        mSatelliteControllerUT.requestTimeForNextSatelliteVisibility(SUB_ID,
+                mSatelliteVisibilityTimeReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, mQueriedSatelliteVisibilityTimeResultCode);
+    }
+
+    @Test
+    public void testRequestSatelliteEnabled() {
+        mIsSatelliteEnabledSemaphore.drainPermits();
+
+        // Fail to enable satellite when SatelliteController is not fully loaded yet.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        // Fail to enable satellite when the device does not support satellite.
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
+
+        // Fail to enable satellite when the device is not provisioned yet.
+        mIIntegerConsumerResults.clear();
+        resetSatelliteControllerUT();
+        verify(mMockSatelliteSessionController, times(1)).onSatelliteEnabledStateChanged(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).setDemoMode(eq(false));
+        verify(mMockDatagramController, times(1)).setDemoMode(eq(false));
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, (long) mIIntegerConsumerResults.get(0));
+
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+
+        // Successfully disable satellite when radio is turned off.
+        mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
+        setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_ERROR_NONE);
+        setRadioPower(false);
+        processAllMessages();
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+        assertTrue(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
+        assertEquals(
+                SATELLITE_MODE_ENABLED_FALSE, mSatelliteControllerUT.satelliteModeSettingValue);
+        verify(mMockSatelliteSessionController, times(2)).onSatelliteEnabledStateChanged(eq(false));
+        verify(mMockSatelliteSessionController, times(2)).setDemoMode(eq(false));
+        verify(mMockDatagramController, times(2)).setDemoMode(eq(false));
+        verify(mMockControllerMetricsStats, times(1)).onSatelliteDisabled();
+
+        // Fail to enable satellite when radio is off.
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        // Radio is not on, can not enable satellite
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        setRadioPower(true);
+        processAllMessages();
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+
+        // Fail to enable satellite with an error response from modem when radio is on.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_INVALID_MODEM_STATE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+        verify(mMockPointingAppController, never()).startPointingUI(anyBoolean());
+        assertFalse(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
+        verify(mMockControllerMetricsStats, times(1)).reportServiceEnablementFailCount();
+
+        // Successfully enable satellite when radio is on.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(true, SATELLITE_ERROR_NONE);
+        assertTrue(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
+        assertEquals(SATELLITE_MODE_ENABLED_TRUE, mSatelliteControllerUT.satelliteModeSettingValue);
+        verify(mMockPointingAppController).startPointingUI(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).onSatelliteEnabledStateChanged(eq(true));
+        verify(mMockSatelliteSessionController, times(3)).setDemoMode(eq(false));
+        verify(mMockDatagramController, times(3)).setDemoMode(eq(false));
+        verify(mMockControllerMetricsStats, times(1)).onSatelliteEnabled();
+        verify(mMockControllerMetricsStats, times(1)).reportServiceEnablementSuccessCount();
+        verify(mMockSessionMetricsStats, times(2)).setInitializationResult(anyInt());
+        verify(mMockSessionMetricsStats, times(2)).setRadioTechnology(anyInt());
+        verify(mMockSessionMetricsStats, times(2)).reportSessionMetrics();
+
+        // Successfully enable satellite when it is already enabled.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(true, SATELLITE_ERROR_NONE);
+
+        // Fail to enable satellite with a different demo mode when it is already enabled.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, true, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_ARGUMENTS, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(true, SATELLITE_ERROR_NONE);
+
+        // Disable satellite.
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+
+        // Disable satellite when satellite is already disabled.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+
+        // Disable satellite with a different demo mode when satellite is already disabled.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, true, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+
+        // Send a second request while the first request in progress
+        mIIntegerConsumerResults.clear();
+        setUpNoResponseForRequestSatelliteEnabled(true, false);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_REQUEST_IN_PROGRESS, (long) mIIntegerConsumerResults.get(0));
+
+        mIIntegerConsumerResults.clear();
+        resetSatelliteControllerUTToSupportedAndProvisionedState();
+        // Should receive callback for the above request when satellite modem is turned off.
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        // Move to satellite-disabling in progress.
+        setUpNoResponseForRequestSatelliteEnabled(false, false);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+
+        // Disable is in progress. Thus, a new request to enable satellite will be rejected.
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR, (long) mIIntegerConsumerResults.get(0));
+
+        mIIntegerConsumerResults.clear();
+        resetSatelliteControllerUTToOffAndProvisionedState();
+        // Should receive callback for the above request when satellite modem is turned off.
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        /**
+         * Make areAllRadiosDisabled return false and move mWaitingForRadioDisabled to true, which
+         * will lead to no response for requestSatelliteEnabled.
+         */
+        mSatelliteControllerUT.allRadiosDisabled = false;
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+
+        resetSatelliteControllerUTEnabledState();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, mIIntegerConsumer);
+        processAllMessages();
+        // We should receive 2 callbacks for the above 2 requests.
+        assertTrue(waitForIIntegerConsumerResult(2));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(1));
+
+        resetSatelliteControllerUTToOffAndProvisionedState();
+
+        // Repeat the same test as above but with error response from modem for the second request
+        mSatelliteControllerUT.allRadiosDisabled = false;
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+
+        resetSatelliteControllerUTEnabledState();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_NO_RESOURCES);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, mIIntegerConsumer);
+        processAllMessages();
+        // We should receive 2 callbacks for the above 2 requests.
+        assertTrue(waitForIIntegerConsumerResult(2));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        assertEquals(SATELLITE_NO_RESOURCES, (long) mIIntegerConsumerResults.get(1));
+        mSatelliteControllerUT.allRadiosDisabled = true;
+    }
+
+    @Test
+    public void testRequestSatelliteCapabilities() {
+        mSatelliteCapabilitiesSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteCapabilities(SUB_ID, mSatelliteCapabilitiesReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestSatelliteCapabilitiesResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteCapabilitiesResultCode);
+
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteCapabilities(SUB_ID, mSatelliteCapabilitiesReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestSatelliteCapabilitiesResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, mQueriedSatelliteCapabilitiesResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestSatelliteCapabilities(mSatelliteCapabilities, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteCapabilities(SUB_ID, mSatelliteCapabilitiesReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestSatelliteCapabilitiesResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, mQueriedSatelliteCapabilitiesResultCode);
+        assertEquals(mSatelliteCapabilities, mQueriedSatelliteCapabilities);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestSatelliteCapabilities(SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteCapabilities(SUB_ID, mSatelliteCapabilitiesReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestSatelliteCapabilitiesResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedSatelliteCapabilitiesResultCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpNullResponseForRequestSatelliteCapabilities(SATELLITE_INVALID_MODEM_STATE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteCapabilities(SUB_ID, mSatelliteCapabilitiesReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestSatelliteCapabilitiesResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, mQueriedSatelliteCapabilitiesResultCode);
+    }
+
+    @Test
+    public void testStartSatelliteTransmissionUpdates() {
+        mIIntegerConsumerSemaphore.drainPermits();
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForStartSatelliteTransmissionUpdates(SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForStartSatelliteTransmissionUpdates(SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        verify(mMockPointingAppController).registerForSatelliteTransmissionUpdates(anyInt(),
+                eq(mStartTransmissionUpdateCallback), any());
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockPointingAppController).startSatelliteTransmissionUpdates(any(Message.class),
+                any(Phone.class));
+        verify(mMockPointingAppController).setStartedSatelliteTransmissionUpdates(eq(true));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForStartSatelliteTransmissionUpdates(SATELLITE_INVALID_TELEPHONY_STATE);
+        mSatelliteControllerUT.startSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStartTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockPointingAppController).unregisterForSatelliteTransmissionUpdates(anyInt(),
+                any(),  eq(mStartTransmissionUpdateCallback), any(Phone.class));
+        verify(mMockPointingAppController).setStartedSatelliteTransmissionUpdates(eq(false));
+    }
+
+    @Test
+    public void testStopSatelliteTransmissionUpdates() {
+        mIIntegerConsumerSemaphore.drainPermits();
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForStopSatelliteTransmissionUpdates(SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForStopSatelliteTransmissionUpdates(SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        verify(mMockPointingAppController).unregisterForSatelliteTransmissionUpdates(anyInt(),
+                any(),  eq(mStopTransmissionUpdateCallback), any(Phone.class));
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockPointingAppController).stopSatelliteTransmissionUpdates(any(Message.class),
+                any(Phone.class));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForStopSatelliteTransmissionUpdates(SATELLITE_INVALID_TELEPHONY_STATE);
+        mSatelliteControllerUT.stopSatelliteTransmissionUpdates(SUB_ID, mIIntegerConsumer,
+                mStopTransmissionUpdateCallback);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+    }
+
+    @Test
+    public void testRequestIsDemoModeEnabled() {
+        mIsDemoModeEnabledSemaphore.drainPermits();
+        resetSatelliteControllerUT();
+        mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
+        assertTrue(waitForRequestIsDemoModeEnabledResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedIsDemoModeEnabledResultCode);
+        assertFalse(mQueriedIsDemoModeEnabled);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
+        assertTrue(waitForRequestIsDemoModeEnabledResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, mQueriedIsDemoModeEnabledResultCode);
+        assertFalse(mQueriedIsDemoModeEnabled);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
+        assertTrue(waitForRequestIsDemoModeEnabledResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, mQueriedIsDemoModeEnabledResultCode);
+        assertFalse(mQueriedIsDemoModeEnabled);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
+        assertTrue(waitForRequestIsDemoModeEnabledResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, mQueriedIsDemoModeEnabledResultCode);
+        assertFalse(mQueriedIsDemoModeEnabled);
+
+        resetSatelliteControllerUT();
+        boolean isDemoModeEnabled = mSatelliteControllerUT.isDemoModeEnabled();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
+        assertTrue(waitForRequestIsDemoModeEnabledResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, mQueriedIsDemoModeEnabledResultCode);
+        assertEquals(isDemoModeEnabled, mQueriedIsDemoModeEnabled);
+    }
+
+    @Test
+    public void testIsSatelliteEnabled() {
+        assertFalse(mSatelliteControllerUT.isSatelliteEnabled());
+        setUpResponseForRequestIsSatelliteEnabled(true, SATELLITE_ERROR_NONE);
+        mIsSatelliteEnabledSemaphore.drainPermits();
+        mSatelliteControllerUT.requestIsSatelliteEnabled(SUB_ID, mIsSatelliteEnabledReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteEnabledResult(1));
+        assertEquals(mSatelliteControllerUT.isSatelliteEnabled(), mQueriedIsSatelliteEnabled);
+    }
+
+    @Test
+    public void testOnSatelliteServiceConnected() {
+        verifySatelliteSupported(false, SATELLITE_RADIO_NOT_AVAILABLE);
+        verifySatelliteEnabled(false, SATELLITE_INVALID_TELEPHONY_STATE);
+        verifySatelliteProvisioned(false, SATELLITE_INVALID_TELEPHONY_STATE);
+
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_ERROR_NONE);
+
+        mSatelliteControllerUT.onSatelliteServiceConnected();
+        processAllMessages();
+
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+    }
+
+    @Test
+    public void testRegisterForSatelliteModemStateChanged() {
+        ISatelliteStateCallback callback = new ISatelliteStateCallback.Stub() {
+            @Override
+            public void onSatelliteModemStateChanged(int state) {
+                logd("onSatelliteModemStateChanged: state=" + state);
+            }
+        };
+        int errorCode = mSatelliteControllerUT.registerForSatelliteModemStateChanged(
+                SUB_ID, callback);
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, errorCode);
+        verify(mMockSatelliteSessionController, never())
+                .registerForSatelliteModemStateChanged(callback);
+
+        resetSatelliteControllerUTToSupportedAndProvisionedState();
+
+        errorCode = mSatelliteControllerUT.registerForSatelliteModemStateChanged(
+                SUB_ID, callback);
+        assertEquals(SATELLITE_ERROR_NONE, errorCode);
+        verify(mMockSatelliteSessionController).registerForSatelliteModemStateChanged(callback);
+    }
+
+    @Test
+    public void testUnregisterForSatelliteModemStateChanged() {
+        ISatelliteStateCallback callback = new ISatelliteStateCallback.Stub() {
+            @Override
+            public void onSatelliteModemStateChanged(int state) {
+                logd("onSatelliteModemStateChanged: state=" + state);
+            }
+        };
+        mSatelliteControllerUT.unregisterForSatelliteModemStateChanged(SUB_ID, callback);
+        verify(mMockSatelliteSessionController, never())
+                .unregisterForSatelliteModemStateChanged(callback);
+
+        resetSatelliteControllerUTToSupportedAndProvisionedState();
+
+        mSatelliteControllerUT.unregisterForSatelliteModemStateChanged(SUB_ID, callback);
+        verify(mMockSatelliteSessionController).unregisterForSatelliteModemStateChanged(callback);
+    }
+
+    @Test
+    public void testRegisterForSatelliteProvisionStateChanged() {
+        Semaphore semaphore = new Semaphore(0);
+        ISatelliteProvisionStateCallback callback =
+                new ISatelliteProvisionStateCallback.Stub() {
+                    @Override
+                    public void onSatelliteProvisionStateChanged(boolean provisioned) {
+                        logd("onSatelliteProvisionStateChanged: provisioned=" + provisioned);
+                        try {
+                            semaphore.release();
+                        } catch (Exception ex) {
+                            loge("onSatelliteProvisionStateChanged: Got exception in releasing "
+                                    + "semaphore, ex=" + ex);
+                        }
+                    }
+                };
+        int errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(
+                SUB_ID, callback);
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, errorCode);
+
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(
+                SUB_ID, callback);
+        assertEquals(SATELLITE_NOT_SUPPORTED, errorCode);
+
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(
+                SUB_ID, callback);
+        assertEquals(SATELLITE_ERROR_NONE, errorCode);
+
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        assertTrue(waitForForEvents(
+                semaphore, 1, "testRegisterForSatelliteProvisionStateChanged"));
+
+        mSatelliteControllerUT.unregisterForSatelliteProvisionStateChanged(SUB_ID, callback);
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        assertFalse(waitForForEvents(
+                semaphore, 1, "testRegisterForSatelliteProvisionStateChanged"));
+    }
+
+    @Test
+    public void testRegisterForSatelliteDatagram() {
+        ISatelliteDatagramCallback callback =
+                new ISatelliteDatagramCallback.Stub() {
+                    @Override
+                    public void onSatelliteDatagramReceived(long datagramId,
+                            @NonNull SatelliteDatagram datagram, int pendingCount,
+                            @NonNull IVoidConsumer internalAck) {
+                        logd("onSatelliteDatagramReceived");
+                    }
+                };
+        when(mMockDatagramController.registerForSatelliteDatagram(eq(SUB_ID), eq(callback)))
+                .thenReturn(SATELLITE_ERROR_NONE);
+        int errorCode = mSatelliteControllerUT.registerForSatelliteDatagram(SUB_ID, callback);
+        assertEquals(SATELLITE_ERROR_NONE, errorCode);
+        verify(mMockDatagramController).registerForSatelliteDatagram(eq(SUB_ID), eq(callback));
+    }
+
+    @Test
+    public void testUnregisterForSatelliteDatagram() {
+        ISatelliteDatagramCallback callback =
+                new ISatelliteDatagramCallback.Stub() {
+                    @Override
+                    public void onSatelliteDatagramReceived(long datagramId,
+                            @NonNull SatelliteDatagram datagram, int pendingCount,
+                            @NonNull IVoidConsumer internalAck) {
+                        logd("onSatelliteDatagramReceived");
+                    }
+                };
+        doNothing().when(mMockDatagramController)
+                .unregisterForSatelliteDatagram(eq(SUB_ID), eq(callback));
+        mSatelliteControllerUT.unregisterForSatelliteDatagram(SUB_ID, callback);
+        verify(mMockDatagramController).unregisterForSatelliteDatagram(eq(SUB_ID), eq(callback));
+    }
+
+    @Test
+    public void testSendSatelliteDatagram() {
+        String mText = "This is a test datagram message from user";
+        SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
+
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.sendSatelliteDatagram(SUB_ID,
+                SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE, datagram, true, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockDatagramController, never()).sendSatelliteDatagram(anyInt(),
+                eq(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE), eq(datagram), eq(true),
+                any());
+
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        sendProvisionedStateChangedEvent(false, null);
+        processAllMessages();
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.sendSatelliteDatagram(SUB_ID,
+                SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE, datagram, true, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockDatagramController, never()).sendSatelliteDatagram(anyInt(),
+                eq(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE), eq(datagram), eq(true),
+                any());
+
+        mIIntegerConsumerResults.clear();
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.sendSatelliteDatagram(SUB_ID,
+                SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE, datagram, true, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+        verify(mMockDatagramController, times(1)).sendSatelliteDatagram(anyInt(),
+                eq(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE), eq(datagram), eq(true),
+                any());
+        verify(mMockPointingAppController, times(1)).startPointingUI(eq(true));
+    }
+
+    @Test
+    public void testPollPendingSatelliteDatagrams() {
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.pollPendingSatelliteDatagrams(SUB_ID, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockDatagramController, never()).pollPendingSatelliteDatagrams(anyInt(), any());
+
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        sendProvisionedStateChangedEvent(false, null);
+        processAllMessages();
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.pollPendingSatelliteDatagrams(SUB_ID, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_NOT_PROVISIONED, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockDatagramController, never()).pollPendingSatelliteDatagrams(anyInt(), any());
+
+        mIIntegerConsumerResults.clear();
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.pollPendingSatelliteDatagrams(SUB_ID, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+        verify(mMockDatagramController, times(1)).pollPendingSatelliteDatagrams(anyInt(), any());
+    }
+
+    @Test
+    public void testProvisionSatelliteService() {
+        String mText = "This is test provision data.";
+        byte[] testProvisionData = mText.getBytes();
+        CancellationSignal cancellationSignal = new CancellationSignal();
+        ICancellationSignal cancelRemote = null;
+        mIIntegerConsumerResults.clear();
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+        assertNull(cancelRemote);
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
+        assertNull(cancelRemote);
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        assertNull(cancelRemote);
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
+                SATELLITE_ERROR_NONE);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        assertNotNull(cancelRemote);
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
+                SATELLITE_NOT_AUTHORIZED);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_AUTHORIZED, (long) mIIntegerConsumerResults.get(0));
+        assertNotNull(cancelRemote);
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForProvisionSatelliteService(TEST_NEXT_SATELLITE_TOKEN, testProvisionData,
+                SATELLITE_ERROR_NONE);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_NEXT_SATELLITE_TOKEN, testProvisionData, mIIntegerConsumer);
+        cancellationSignal.setRemote(cancelRemote);
+        cancellationSignal.cancel();
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verify(mMockSatelliteModemInterface).deprovisionSatelliteService(
+                eq(TEST_NEXT_SATELLITE_TOKEN), any(Message.class));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpNoResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN);
+        setUpResponseForProvisionSatelliteService(TEST_NEXT_SATELLITE_TOKEN, testProvisionData,
+                SATELLITE_ERROR_NONE);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+                TEST_NEXT_SATELLITE_TOKEN,
+                testProvisionData, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
+                (long) mIIntegerConsumerResults.get(0));
+    }
+
+    @Test
+    public void testDeprovisionSatelliteService() {
+        mIIntegerConsumerSemaphore.drainPermits();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                 TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_TELEPHONY_STATE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(false, SATELLITE_ERROR_NONE);
+        setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+
+        resetSatelliteControllerUT();
+        mIIntegerConsumerResults.clear();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+        setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN,
+                SATELLITE_INVALID_MODEM_STATE);
+        mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
+                TEST_SATELLITE_TOKEN, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+
+    }
+
+    private void resetSatelliteControllerUTEnabledState() {
+        logd("resetSatelliteControllerUTEnabledState");
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RADIO_NOT_AVAILABLE);
+        doReturn(true).when(mMockSatelliteModemInterface)
+                .setSatelliteServicePackageName(anyString());
+        mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService");
+        processAllMessages();
+
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+    }
+
+    private void resetSatelliteControllerUT() {
+        logd("resetSatelliteControllerUT");
+        // Trigger cleanUpResources
+        sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_UNAVAILABLE, null);
+        processAllMessages();
+
+        // Reset all cached states
+        setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RADIO_NOT_AVAILABLE);
+        doReturn(true).when(mMockSatelliteModemInterface)
+                .setSatelliteServicePackageName(anyString());
+        mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService");
+        processAllMessages();
+    }
+
+    private void resetSatelliteControllerUTToSupportedAndProvisionedState() {
+        resetSatelliteControllerUT();
+        setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_ERROR_NONE);
+        verifySatelliteSupported(true, SATELLITE_ERROR_NONE);
+        sendProvisionedStateChangedEvent(true, null);
+        processAllMessages();
+        verifySatelliteProvisioned(true, SATELLITE_ERROR_NONE);
+    }
+
+    private void resetSatelliteControllerUTToOffAndProvisionedState() {
+        resetSatelliteControllerUTToSupportedAndProvisionedState();
+        sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_OFF, null);
+        processAllMessages();
+        verifySatelliteEnabled(false, SATELLITE_ERROR_NONE);
+    }
+
+    private void resetSatelliteControllerUTToOnAndProvisionedState() {
+        resetSatelliteControllerUTToOffAndProvisionedState();
+        setRadioPower(true);
+        processAllMessages();
+
+        setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_ERROR_NONE);
+        mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_ERROR_NONE, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(true, SATELLITE_ERROR_NONE);
+    }
+
+    private void setUpResponseForRequestIsSatelliteEnabled(boolean isSatelliteEnabled,
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, isSatelliteEnabled, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).requestIsSatelliteEnabled(any(Message.class));
+    }
+
+    private void setUpResponseForRequestIsSatelliteSupported(
+            boolean isSatelliteSupported, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, isSatelliteSupported, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).requestIsSatelliteSupported(any(Message.class));
+    }
+
+    private void setUpResponseForRequestIsSatelliteAllowedForCurrentLocation(
+            boolean isSatelliteAllowed, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, isSatelliteAllowed, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .requestIsSatelliteCommunicationAllowedForCurrentLocation(any(Message.class));
+    }
+
+    private void setUpNullResponseForRequestIsSatelliteAllowedForCurrentLocation(
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .requestIsSatelliteCommunicationAllowedForCurrentLocation(any(Message.class));
+    }
+
+    private void setUpResponseForRequestTimeForNextSatelliteVisibility(
+            int satelliteVisibilityTime, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        int[] visibilityTime = new int[] {satelliteVisibilityTime};
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, visibilityTime, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .requestTimeForNextSatelliteVisibility(any(Message.class));
+    }
+
+    private void setUpNullResponseForRequestTimeForNextSatelliteVisibility(
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .requestTimeForNextSatelliteVisibility(any(Message.class));
+    }
+
+    private void setUpResponseForRequestIsSatelliteProvisioned(
+            boolean isSatelliteProvisioned, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        int[] provisioned = new int[] {isSatelliteProvisioned ? 1 : 0};
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, provisioned, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).requestIsSatelliteProvisioned(any(Message.class));
+    }
+
+    private void setUpResponseForRequestSatelliteEnabled(
+            boolean enabled, boolean demoMode, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[2];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .requestSatelliteEnabled(eq(enabled), eq(demoMode), any(Message.class));
+    }
+
+    private void setUpNoResponseForRequestSatelliteEnabled(boolean enabled, boolean demoMode) {
+        doNothing().when(mMockSatelliteModemInterface)
+                .requestSatelliteEnabled(eq(enabled), eq(demoMode), any(Message.class));
+    }
+
+    private void setUpResponseForProvisionSatelliteService(
+            String token, byte[] provisionData, @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[2];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .provisionSatelliteService(eq(token), any(byte[].class), any(Message.class));
+    }
+
+    private void setUpNoResponseForProvisionSatelliteService(String token) {
+        doNothing().when(mMockSatelliteModemInterface)
+                .provisionSatelliteService(eq(token), any(), any(Message.class));
+    }
+
+    private void setUpResponseForDeprovisionSatelliteService(String token,
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[1];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface)
+                .deprovisionSatelliteService(eq(token), any(Message.class));
+    }
+
+    private void setUpResponseForRequestSatelliteCapabilities(
+            SatelliteCapabilities satelliteCapabilities,
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, satelliteCapabilities, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).requestSatelliteCapabilities(any(Message.class));
+    }
+
+    private boolean waitForForEvents(
+            Semaphore semaphore, int expectedNumberOfEvents, String caller) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!semaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge(caller + ": Timeout to receive the expected event");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge(caller + ": Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void setUpNullResponseForRequestSatelliteCapabilities(
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockSatelliteModemInterface).requestSatelliteCapabilities(any(Message.class));
+    }
+
+    private void setUpResponseForStartSatelliteTransmissionUpdates(
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockPointingAppController).startSatelliteTransmissionUpdates(any(Message.class),
+                any());
+    }
+
+    private void setUpResponseForStopSatelliteTransmissionUpdates(
+            @SatelliteManager.SatelliteError int error) {
+        SatelliteException exception = (error == SATELLITE_ERROR_NONE)
+                ? null : new SatelliteException(error);
+        doAnswer(invocation -> {
+            Message message = (Message) invocation.getArguments()[0];
+            AsyncResult.forMessage(message, null, exception);
+            message.sendToTarget();
+            return null;
+        }).when(mMockPointingAppController).stopSatelliteTransmissionUpdates(any(Message.class),
+                any());
+    }
+
+    private boolean waitForRequestIsSatelliteSupportedResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mSatelliteSupportSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive requestIsSatelliteSupported() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestIsSatelliteSupportedResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestIsSatelliteAllowedForCurrentLocationResult(
+            int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mSatelliteAllowedSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive "
+                            + "requestIsSatelliteCommunicationAllowedForCurrentLocation()"
+                            + " callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestIsSatelliteSupportedResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestTimeForNextSatelliteVisibilityResult(
+            int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mSatelliteVisibilityTimeSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive "
+                            + "requestTimeForNextSatelliteVisibility() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestTimeForNextSatelliteVisibilityResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestIsSatelliteEnabledResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mIsSatelliteEnabledSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive requestIsSatelliteEnabled() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestIsSatelliteEnabledResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestIsSatelliteProvisionedResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mIsSatelliteProvisionedSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive requestIsSatelliteProvisioned() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestIsSatelliteProvisionedResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestSatelliteCapabilitiesResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mSatelliteCapabilitiesSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive requestSatelliteCapabilities() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestSatelliteCapabilitiesResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForRequestIsDemoModeEnabledResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mIsDemoModeEnabledSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive requestIsDemoModeEnabled() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForRequestIsDemoModeEnabled: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean waitForIIntegerConsumerResult(int expectedNumberOfEvents) {
+        for (int i = 0; i < expectedNumberOfEvents; i++) {
+            try {
+                if (!mIIntegerConsumerSemaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+                    loge("Timeout to receive IIntegerConsumer() callback");
+                    return false;
+                }
+            } catch (Exception ex) {
+                loge("waitForIIntegerConsumerResult: Got exception=" + ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void verifySatelliteSupported(boolean supported, int expectedErrorCode) {
+        mSatelliteSupportSemaphore.drainPermits();
+        mSatelliteControllerUT.requestIsSatelliteSupported(SUB_ID, mSatelliteSupportReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteSupportedResult(1));
+        assertEquals(expectedErrorCode, mQueriedSatelliteSupportedResultCode);
+        assertEquals(supported, mQueriedSatelliteSupported);
+    }
+
+    private void verifySatelliteEnabled(boolean enabled, int expectedErrorCode) {
+        mIsSatelliteEnabledSemaphore.drainPermits();
+        mSatelliteControllerUT.requestIsSatelliteEnabled(SUB_ID, mIsSatelliteEnabledReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteEnabledResult(1));
+        assertEquals(expectedErrorCode, mQueriedIsSatelliteEnabledResultCode);
+        assertEquals(enabled, mQueriedIsSatelliteEnabled);
+    }
+
+    private void verifySatelliteProvisioned(boolean provisioned, int expectedErrorCode) {
+        mIsSatelliteProvisionedSemaphore.drainPermits();
+        mSatelliteControllerUT.requestIsSatelliteProvisioned(
+                SUB_ID, mIsSatelliteProvisionedReceiver);
+        processAllMessages();
+        assertTrue(waitForRequestIsSatelliteProvisionedResult(1));
+        assertEquals(expectedErrorCode, mQueriedIsSatelliteProvisionedResultCode);
+        assertEquals(provisioned, mQueriedIsSatelliteProvisioned);
+    }
+
+    private void sendProvisionedStateChangedEvent(boolean provisioned, Throwable exception) {
+        Message msg = mSatelliteControllerUT.obtainMessage(
+                26 /* EVENT_SATELLITE_PROVISION_STATE_CHANGED */);
+        msg.obj = new AsyncResult(null, provisioned, exception);
+        msg.sendToTarget();
+    }
+
+    private void sendSatelliteModemStateChangedEvent(int state, Throwable exception) {
+        Message msg = mSatelliteControllerUT.obtainMessage(
+                28 /* EVENT_SATELLITE_MODEM_STATE_CHANGED */);
+        msg.obj = new AsyncResult(null, state, exception);
+        msg.sendToTarget();
+    }
+
+    private void setRadioPower(boolean on) {
+        mSimulatedCommands.setRadioPower(on, false, false, null);
+    }
+
+    private static void loge(String message) {
+        Rlog.e(TAG, message);
+    }
+
+    private static class TestSharedPreferences
+            implements SharedPreferences, SharedPreferences.Editor {
+        private HashMap<String, Object> mValues = new HashMap<String, Object>();
+
+        public int getValueCount() {
+            return mValues.size();
+        }
+
+        @Override
+        public Editor edit() {
+            return this;
+        }
+
+        @Override
+        public boolean contains(String key) {
+            return mValues.containsKey(key);
+        }
+
+        @Override
+        public Map<String, ?> getAll() {
+            return new HashMap<String, Object>(mValues);
+        }
+
+        @Override
+        public boolean getBoolean(String key, boolean defValue) {
+            if (mValues.containsKey(key)) {
+                return ((Boolean) mValues.get(key)).booleanValue();
+            }
+            return defValue;
+        }
+
+        @Override
+        public float getFloat(String key, float defValue) {
+            if (mValues.containsKey(key)) {
+                return ((Float) mValues.get(key)).floatValue();
+            }
+            return defValue;
+        }
+
+        @Override
+        public int getInt(String key, int defValue) {
+            if (mValues.containsKey(key)) {
+                return ((Integer) mValues.get(key)).intValue();
+            }
+            return defValue;
+        }
+
+        @Override
+        public long getLong(String key, long defValue) {
+            if (mValues.containsKey(key)) {
+                return ((Long) mValues.get(key)).longValue();
+            }
+            return defValue;
+        }
+
+        @Override
+        public String getString(String key, String defValue) {
+            if (mValues.containsKey(key)) return (String) mValues.get(key);
+            else return defValue;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Set<String> getStringSet(String key, Set<String> defValues) {
+            if (mValues.containsKey(key)) {
+                return (Set<String>) mValues.get(key);
+            }
+            return defValues;
+        }
+
+        @Override
+        public void registerOnSharedPreferenceChangeListener(
+                OnSharedPreferenceChangeListener listener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void unregisterOnSharedPreferenceChangeListener(
+                OnSharedPreferenceChangeListener listener) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Editor putBoolean(String key, boolean value) {
+            mValues.put(key, Boolean.valueOf(value));
+            return this;
+        }
+
+        @Override
+        public Editor putFloat(String key, float value) {
+            mValues.put(key, value);
+            return this;
+        }
+
+        @Override
+        public Editor putInt(String key, int value) {
+            mValues.put(key, value);
+            return this;
+        }
+
+        @Override
+        public Editor putLong(String key, long value) {
+            mValues.put(key, value);
+            return this;
+        }
+
+        @Override
+        public Editor putString(String key, String value) {
+            mValues.put(key, value);
+            return this;
+        }
+
+        @Override
+        public Editor putStringSet(String key, Set<String> values) {
+            mValues.put(key, values);
+            return this;
+        }
+
+        @Override
+        public Editor remove(String key) {
+            mValues.remove(key);
+            return this;
+        }
+
+        @Override
+        public Editor clear() {
+            mValues.clear();
+            return this;
+        }
+
+        @Override
+        public boolean commit() {
+            return true;
+        }
+
+        @Override
+        public void apply() {
+            commit();
+        }
+    }
+
+    private static class TestSatelliteController extends SatelliteController {
+        public boolean setSettingsKeyForSatelliteModeCalled = false;
+        public boolean allRadiosDisabled = true;
+        public int satelliteModeSettingValue = SATELLITE_MODE_ENABLED_FALSE;
+
+        TestSatelliteController(Context context, Looper looper) {
+            super(context, looper);
+            logd("Constructing TestSatelliteController");
+        }
+
+        @Override
+        protected void initializeSatelliteModeRadios() {
+            logd("initializeSatelliteModeRadios");
+        }
+
+        @Override
+        protected void setSettingsKeyForSatelliteMode(int val) {
+            logd("setSettingsKeyForSatelliteMode: val=" + val);
+            satelliteModeSettingValue = val;
+            setSettingsKeyForSatelliteModeCalled = true;
+        }
+
+        @Override
+        protected boolean areAllRadiosDisabled() {
+            return allRadiosDisabled;
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
new file mode 100644
index 0000000..418d0aa
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+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.Context;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telephony.BinderCacheManager;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.SatelliteManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.Log;
+
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.internal.telephony.Phone;
+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;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for SatelliteSOSMessageRecommender
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class SatelliteSOSMessageRecommenderTest extends TelephonyTest {
+    private static final String TAG = "SatelliteSOSMessageRecommenderTest";
+    private static final long TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500;
+    private static final int PHONE_ID = 0;
+    private static final String CALL_ID = "CALL_ID";
+    private static final String WRONG_CALL_ID = "WRONG_CALL_ID";
+    private TestSatelliteController mTestSatelliteController;
+    private TestImsManager mTestImsManager;
+
+    @Mock
+    private Context mMockContext;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private ImsManager.MmTelFeatureConnectionFactory mMmTelFeatureConnectionFactory;
+    private TestConnection mTestConnection;
+    private TestSOSMessageRecommender mTestSOSMessageRecommender;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+
+        when(mMockContext.getMainLooper()).thenReturn(Looper.myLooper());
+        when(mMockContext.getResources()).thenReturn(mResources);
+        when(mResources.getString(com.android.internal.R.string.config_satellite_service_package))
+                .thenReturn("");
+        mTestSatelliteController = new TestSatelliteController(mMockContext,
+                Looper.myLooper());
+        mTestImsManager = new TestImsManager(
+                mMockContext, PHONE_ID, mMmTelFeatureConnectionFactory, null, null, null);
+        mTestConnection = new TestConnection(CALL_ID);
+        when(mPhone.getServiceState()).thenReturn(mServiceState);
+        mTestSOSMessageRecommender = new TestSOSMessageRecommender(Looper.myLooper(),
+                mTestSatelliteController, mTestImsManager,
+                TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mPhone.isImsRegistered()).thenReturn(false);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testTimeoutBeforeEmergencyCallEnd() {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+
+        // Wait for the timeout to expires
+        moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        processAllMessages();
+
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+        assertTrue(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+    }
+
+    @Test
+    public void testStopTrackingCallBeforeTimeout_ConnectionActive() {
+        testStopTrackingCallBeforeTimeout(Connection.STATE_ACTIVE);
+    }
+
+    @Test
+    public void testStopTrackingCallBeforeTimeout_ConnectionDisconnected() {
+        testStopTrackingCallBeforeTimeout(Connection.STATE_DISCONNECTED);
+    }
+
+    @Test
+    public void testImsRegistrationStateChangedBeforeTimeout() {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestImsManager.sendImsRegistrationStateChangedEvent(true);
+        processAllMessages();
+
+        assertFalse(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
+
+        mTestImsManager.sendImsRegistrationStateChangedEvent(false);
+        processAllMessages();
+        assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
+
+        // Wait for the timeout to expires
+        moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        processAllMessages();
+
+        assertTrue(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+    }
+
+    @Test
+    public void testSatelliteProvisionStateChangedBeforeTimeout() {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestSatelliteController.sendProvisionStateChangedEvent(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false);
+        processAllMessages();
+
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 2, 2, 2);
+
+        mTestSatelliteController.sendProvisionStateChangedEvent(
+                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true);
+
+        // Wait for the timeout to expires
+        moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        processAllMessages();
+
+        assertTrue(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 2, 2);
+    }
+
+    @Test
+    public void testEmergencyCallRedialBeforeTimeout() {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        Phone newPhone = Mockito.mock(Phone.class);
+        when(newPhone.getServiceState()).thenReturn(mServiceState);
+        when(newPhone.isImsRegistered()).thenReturn(false);
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, newPhone);
+        processAllMessages();
+
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        /**
+         * Since {@link SatelliteSOSMessageRecommender} always uses
+         * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} when registering for provision state
+         * changed events with {@link SatelliteController}, registerForProvisionCount does
+         * not depend on Phone.
+         * <p>
+         * Since we use a single mocked ImsManager instance, registerForImsCount does not depend on
+         * Phone.
+         */
+        assertRegisterForStateChangedEventsTriggered(newPhone, 2, 2, 1);
+
+        // Wait for the timeout to expires
+        moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        processAllMessages();
+
+        assertTrue(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        /**
+         * Since {@link SatelliteSOSMessageRecommender} always uses
+         * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} when unregistering for provision
+         * state changed events with {@link SatelliteController}, unregisterForProvisionCount does
+         * not depend on Phone.
+         * <p>
+         * Since we use a single mocked ImsManager instance, unregisterForImsCount does not depend
+         * on Phone.
+         */
+        assertUnregisterForStateChangedEventsTriggered(newPhone, 2, 2, 1);
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+    }
+
+    @Test
+    public void testCellularServiceStateChangedBeforeTimeout_InServiceToOutOfService() {
+        testCellularServiceStateChangedBeforeTimeout(
+                ServiceState.STATE_IN_SERVICE, ServiceState.STATE_OUT_OF_SERVICE);
+    }
+
+    @Test
+    public void testCellularServiceStateChangedBeforeTimeout_InServiceToPowerOff() {
+        testCellularServiceStateChangedBeforeTimeout(
+                ServiceState.STATE_IN_SERVICE, ServiceState.STATE_POWER_OFF);
+    }
+
+    @Test
+    public void testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToOutOfService() {
+        testCellularServiceStateChangedBeforeTimeout(
+                ServiceState.STATE_EMERGENCY_ONLY, ServiceState.STATE_OUT_OF_SERVICE);
+    }
+
+    @Test
+    public void testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToPowerOff() {
+        testCellularServiceStateChangedBeforeTimeout(
+                ServiceState.STATE_EMERGENCY_ONLY, ServiceState.STATE_POWER_OFF);
+    }
+
+    @Test
+    public void testOnEmergencyCallConnectionStateChangedWithWrongCallId() {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
+                WRONG_CALL_ID, Connection.STATE_ACTIVE);
+        processAllMessages();
+
+        assertFalse(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+    }
+
+    @Test
+    public void testSatelliteNotAllowedInCurrentLocation() {
+        mTestSatelliteController.setIsSatelliteCommunicationAllowed(false);
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        /**
+         * We should have registered for the state change events abd started the timer when
+         * receiving the event onEmergencyCallStarted. After getting the callback for the result of
+         * the request requestIsSatelliteCommunicationAllowedForCurrentLocation, the resources
+         * should be cleaned up.
+         */
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+    }
+
+    @Test
+    public void testOnEmergencyCallStarted() {
+        SatelliteController satelliteController = new SatelliteController(
+                mMockContext, Looper.myLooper());
+        TestSOSMessageRecommender testSOSMessageRecommender = new TestSOSMessageRecommender(
+                Looper.myLooper(),
+                satelliteController, mTestImsManager,
+                TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertFalse(testSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, testSOSMessageRecommender.getCountOfTimerStarted());
+    }
+
+    private void testStopTrackingCallBeforeTimeout(
+            @Connection.ConnectionState int connectionState) {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(CALL_ID, connectionState);
+        processAllMessages();
+
+        assertFalse(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+    }
+
+    private void testCellularServiceStateChangedBeforeTimeout(
+            @ServiceState.RegState int availableServiceState,
+            @ServiceState.RegState int unavailableServiceState) {
+        mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+        processAllMessages();
+
+        assertTrue(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+
+        mTestSOSMessageRecommender.sendServiceStateChangedEvent(availableServiceState);
+        processAllMessages();
+
+        assertFalse(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+        assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
+
+        mTestSOSMessageRecommender.sendServiceStateChangedEvent(unavailableServiceState);
+        processAllMessages();
+        assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
+
+        // Wait for the timeout to expires
+        moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+        processAllMessages();
+
+        assertTrue(mTestConnection.isEventSent(Call.EVENT_DISPLAY_SOS_MESSAGE));
+        assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+        assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+    }
+
+    private void assertRegisterForStateChangedEventsTriggered(
+            Phone phone, int registerForProvisionCount, int registerForImsCount,
+            int registerForCellularCount) {
+        assertEquals(registerForProvisionCount,
+                mTestSatelliteController.getRegisterForSatelliteProvisionStateChangedCalls());
+        assertEquals(registerForImsCount, mTestImsManager.getAddRegistrationCallbackCalls());
+        verify(phone, times(registerForCellularCount))
+                .registerForServiceStateChanged(any(), anyInt(), any());
+    }
+
+    private void assertUnregisterForStateChangedEventsTriggered(
+            Phone phone, int unregisterForProvisionCount, int unregisterForImsCount,
+            int unregisterForCellularCount) {
+        assertEquals(unregisterForProvisionCount,
+                mTestSatelliteController.getUnregisterForSatelliteProvisionStateChangedCalls());
+        assertEquals(unregisterForImsCount, mTestImsManager.getRemoveRegistrationListenerCalls());
+        verify(phone, times(unregisterForCellularCount)).unregisterForServiceStateChanged(any());
+    }
+
+    private static class TestSatelliteController extends SatelliteController {
+
+        private static final String TAG = "TestSatelliteController";
+        private final Map<Integer, Set<ISatelliteProvisionStateCallback>>
+                mProvisionStateChangedCallbacks;
+        private int mRegisterForSatelliteProvisionStateChangedCalls = 0;
+        private int mUnregisterForSatelliteProvisionStateChangedCalls = 0;
+        private boolean mIsSatelliteProvisioned = true;
+        private boolean mIsSatelliteCommunicationAllowed = true;
+
+        /**
+         * Create a SatelliteController to act as a backend service of
+         * {@link SatelliteManager}
+         *
+         * @param context The Context for the SatelliteController.
+         */
+        protected TestSatelliteController(Context context, Looper looper) {
+            super(context, looper);
+            mProvisionStateChangedCallbacks = new HashMap<>();
+        }
+
+        @Override
+        public Boolean isSatelliteProvisioned() {
+            return mIsSatelliteProvisioned;
+        }
+
+        @Override
+        public boolean isSatelliteSupported() {
+            return true;
+        }
+
+        @Override
+        @SatelliteManager.SatelliteError public int registerForSatelliteProvisionStateChanged(
+                int subId, @NonNull ISatelliteProvisionStateCallback callback) {
+            mRegisterForSatelliteProvisionStateChangedCalls++;
+            Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
+                    mProvisionStateChangedCallbacks.getOrDefault(subId, new HashSet<>());
+            perSubscriptionCallbacks.add(callback);
+            mProvisionStateChangedCallbacks.put(subId, perSubscriptionCallbacks);
+            return SatelliteManager.SATELLITE_ERROR_NONE;
+        }
+
+        @Override
+        public void unregisterForSatelliteProvisionStateChanged(
+                int subId, @NonNull ISatelliteProvisionStateCallback callback) {
+            mUnregisterForSatelliteProvisionStateChangedCalls++;
+            Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
+                    mProvisionStateChangedCallbacks.get(subId);
+            if (perSubscriptionCallbacks != null) {
+                perSubscriptionCallbacks.remove(callback);
+            }
+        }
+
+        @Override
+        public void requestIsSatelliteCommunicationAllowedForCurrentLocation(int subId,
+                @NonNull ResultReceiver result) {
+            Bundle bundle = new Bundle();
+            bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
+                    mIsSatelliteCommunicationAllowed);
+            result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+        }
+
+        public void setIsSatelliteCommunicationAllowed(boolean allowed) {
+            mIsSatelliteCommunicationAllowed = allowed;
+        }
+
+        public int getRegisterForSatelliteProvisionStateChangedCalls() {
+            return mRegisterForSatelliteProvisionStateChangedCalls;
+        }
+
+        public int getUnregisterForSatelliteProvisionStateChangedCalls() {
+            return mUnregisterForSatelliteProvisionStateChangedCalls;
+        }
+
+        public void sendProvisionStateChangedEvent(int subId, boolean provisioned) {
+            mIsSatelliteProvisioned = provisioned;
+            Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
+                    mProvisionStateChangedCallbacks.get(subId);
+            if (perSubscriptionCallbacks != null) {
+                for (ISatelliteProvisionStateCallback callback : perSubscriptionCallbacks) {
+                    try {
+                        callback.onSatelliteProvisionStateChanged(provisioned);
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "sendProvisionStateChangedEvent: ex=" + ex);
+                    }
+                }
+            }
+        }
+    }
+
+    private static class TestImsManager extends ImsManager {
+
+        private final Set<RegistrationManager.RegistrationCallback> mCallbacks;
+        private int mAddRegistrationCallbackCalls = 0;
+        private int mRemoveRegistrationListenerCalls = 0;
+
+        /**
+         * Used for testing only to inject dependencies.
+         */
+        TestImsManager(Context context, int phoneId, MmTelFeatureConnectionFactory factory,
+                SubscriptionManagerProxy subManagerProxy, SettingsProxy settingsProxy,
+                BinderCacheManager binderCacheManager) {
+            super(context, phoneId, factory, subManagerProxy, settingsProxy, binderCacheManager);
+            mCallbacks = new HashSet<>();
+        }
+
+        @Override
+        public void addRegistrationCallback(RegistrationManager.RegistrationCallback callback,
+                Executor executor)
+                throws ImsException {
+            mAddRegistrationCallbackCalls++;
+
+            if (callback == null) {
+                throw new NullPointerException("registration callback can't be null");
+            }
+            if (executor == null) {
+                throw new NullPointerException("registration executor can't be null");
+            }
+
+            callback.setExecutor(executor);
+            mCallbacks.add(callback);
+        }
+
+        @Override
+        public void removeRegistrationListener(RegistrationManager.RegistrationCallback callback) {
+            mRemoveRegistrationListenerCalls++;
+
+            if (callback == null) {
+                throw new NullPointerException("registration callback can't be null");
+            }
+            mCallbacks.remove(callback);
+        }
+
+        public int getAddRegistrationCallbackCalls() {
+            return mAddRegistrationCallbackCalls;
+        }
+
+        public int getRemoveRegistrationListenerCalls() {
+            return mRemoveRegistrationListenerCalls;
+        }
+
+        public void sendImsRegistrationStateChangedEvent(boolean registered) {
+            if (registered) {
+                for (RegistrationManager.RegistrationCallback callback : mCallbacks) {
+                    callback.onRegistered(null);
+                }
+            } else {
+                for (RegistrationManager.RegistrationCallback callback : mCallbacks) {
+                    callback.onUnregistered(null);
+                }
+            }
+        }
+    }
+
+    private static class TestSOSMessageRecommender extends SatelliteSOSMessageRecommender {
+
+        /**
+         * Create an instance of SatelliteSOSMessageRecommender.
+         *
+         * @param looper              The looper used with the handler of this class.
+         * @param satelliteController The SatelliteController singleton instance.
+         * @param imsManager          The ImsManager instance associated with the phone, which is
+         *                            used for making the emergency call. This argument is not
+         *                            null only in unit tests.
+         * @param timeoutMillis       The timeout duration of the timer.
+         */
+        TestSOSMessageRecommender(Looper looper, SatelliteController satelliteController,
+                ImsManager imsManager, long timeoutMillis) {
+            super(looper, satelliteController, imsManager, timeoutMillis);
+        }
+
+        public boolean isTimerStarted() {
+            return hasMessages(EVENT_TIME_OUT);
+        }
+
+        public int getCountOfTimerStarted() {
+            return mCountOfTimerStarted;
+        }
+
+        public void sendServiceStateChangedEvent(@ServiceState.RegState int state) {
+            ServiceState serviceState = new ServiceState();
+            serviceState.setState(state);
+            sendMessage(obtainMessage(EVENT_CELLULAR_SERVICE_STATE_CHANGED,
+                    new AsyncResult(null, serviceState, null)));
+        }
+    }
+
+    private static class TestConnection extends Connection {
+        private final Set<String> mSentEvents;
+        TestConnection(String callId) {
+            setTelecomCallId(callId);
+            mSentEvents = new HashSet<>();
+        }
+
+        @Override
+        public void sendConnectionEvent(String event, Bundle extras) {
+            mSentEvents.add(event);
+        }
+
+        public boolean isEventSent(String event) {
+            return mSentEvents.contains(event);
+        }
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
new file mode 100644
index 0000000..3ccf512
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2023 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.satellite;
+
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.satellite.ISatelliteStateCallback;
+import android.telephony.satellite.SatelliteManager;
+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;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Unit tests for SatelliteSessionController
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class SatelliteSessionControllerTest extends TelephonyTest {
+    private static final String TAG = "SatelliteSessionControllerTest";
+    private static final long TEST_SATELLITE_STAY_AT_LISTENING_MILLIS = 200;
+    private static final long EVENT_PROCESSING_TIME_MILLIS = 100;
+
+    private static final String STATE_UNAVAILABLE = "UnavailableState";
+    private static final String STATE_POWER_OFF = "PowerOffState";
+    private static final String STATE_IDLE = "IdleState";
+    private static final String STATE_TRANSFERRING = "TransferringState";
+    private static final String STATE_LISTENING = "ListeningState";
+
+    private TestSatelliteModemInterface mSatelliteModemInterface;
+    private TestSatelliteSessionController mTestSatelliteSessionController;
+    private TestSatelliteStateCallback mTestSatelliteStateCallback;
+
+    @Mock
+    private SatelliteController mSatelliteController;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        MockitoAnnotations.initMocks(this);
+
+        mSatelliteModemInterface = new TestSatelliteModemInterface(
+                mContext, mSatelliteController, Looper.myLooper());
+        mTestSatelliteSessionController = new TestSatelliteSessionController(mContext,
+                Looper.myLooper(), true, mSatelliteModemInterface,
+                TEST_SATELLITE_STAY_AT_LISTENING_MILLIS,
+                TEST_SATELLITE_STAY_AT_LISTENING_MILLIS);
+        processAllMessages();
+
+        mTestSatelliteStateCallback = new TestSatelliteStateCallback();
+        mTestSatelliteSessionController.registerForSatelliteModemStateChanged(
+                mTestSatelliteStateCallback);
+        assertSuccessfulModemStateChangedCallback(
+                mTestSatelliteStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testInitialState() {
+        /**
+         * Since satellite is not supported, SatelliteSessionController should move to UNAVAILABLE
+         * state.
+         */
+        TestSatelliteSessionController sessionController1 = new TestSatelliteSessionController(
+                mContext, Looper.myLooper(), false,
+                mSatelliteModemInterface, 100, 100);
+        assertNotNull(sessionController1);
+        processAllMessages();
+        assertEquals(STATE_UNAVAILABLE, sessionController1.getCurrentStateName());
+
+        /**
+         * Since satellite is supported, SatelliteSessionController should move to POWER_OFF state.
+         */
+        TestSatelliteSessionController sessionController2 = new TestSatelliteSessionController(
+                mContext, Looper.myLooper(), true,
+                mSatelliteModemInterface, 100, 100);
+        assertNotNull(sessionController2);
+        processAllMessages();
+        assertEquals(STATE_POWER_OFF, sessionController2.getCurrentStateName());
+    }
+
+    @Test
+    public void testUnavailableState() throws Exception {
+        /**
+         * Since satellite is not supported, SatelliteSessionController should move to UNAVAILABLE
+         * state.
+         */
+        TestSatelliteSessionController sessionController = new TestSatelliteSessionController(
+                mContext, Looper.myLooper(), false,
+                mSatelliteModemInterface, 100, 100);
+        assertNotNull(sessionController);
+        processAllMessages();
+        assertEquals(STATE_UNAVAILABLE, sessionController.getCurrentStateName());
+
+        /**
+         *  SatelliteSessionController should stay at UNAVAILABLE state even after it receives the
+         *  satellite radio powered-on state changed event.
+         */
+        sessionController.onSatelliteEnabledStateChanged(true);
+        processAllMessages();
+        assertEquals(STATE_UNAVAILABLE, sessionController.getCurrentStateName());
+    }
+
+    @Test
+    public void testStateTransition() {
+        /**
+         * Since satellite is supported, SatelliteSessionController should move to POWER_OFF state.
+         */
+        assertNotNull(mTestSatelliteSessionController);
+        assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+
+        // Power on the modem.
+        mTestSatelliteSessionController.onSatelliteEnabledStateChanged(true);
+        processAllMessages();
+
+        // SatelliteSessionController should move to IDLE state after the modem is powered on.
+        assertSuccessfulModemStateChangedCallback(
+                mTestSatelliteStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Power off the modem.
+        mTestSatelliteSessionController.onSatelliteEnabledStateChanged(false);
+        processAllMessages();
+
+        // SatelliteSessionController should move back to POWER_OFF state.
+        assertSuccessfulModemStateChangedCallback(
+                mTestSatelliteStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+        assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Power on the modem.
+        mTestSatelliteSessionController.onSatelliteEnabledStateChanged(true);
+        processAllMessages();
+
+        // SatelliteSessionController should move to IDLE state after radio is turned on.
+        assertSuccessfulModemStateChangedCallback(
+                mTestSatelliteStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start sending datagrams
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING, SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Sending datagrams failed
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to IDLE state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start sending datagrams again
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Sending datagrams is successful and done.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to LISTENING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+        assertEquals(STATE_LISTENING, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(1, mSatelliteModemInterface.getListeningEnabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start receiving datagrams
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(1, mSatelliteModemInterface.getListeningDisabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Receiving datagrams is successful and done.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to LISTENING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+        assertEquals(STATE_LISTENING, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(2, mSatelliteModemInterface.getListeningEnabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start receiving datagrams again
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(2, mSatelliteModemInterface.getListeningDisabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Receiving datagrams failed.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED);
+        processAllMessages();
+
+        // SatelliteSessionController should move to IDLE state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start receiving datagrams again
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Receiving datagrams is successful and done.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE);
+        processAllMessages();
+
+        // SatelliteSessionController should move to LISTENING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+        assertEquals(STATE_LISTENING, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(3, mSatelliteModemInterface.getListeningEnabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Wait for timeout
+        moveTimeForward(TEST_SATELLITE_STAY_AT_LISTENING_MILLIS);
+        processAllMessages();
+
+        // SatelliteSessionController should move to IDLE state after timeout
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
+        assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+        assertEquals(3, mSatelliteModemInterface.getListeningDisabledCount());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start receiving datagrams again
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should move to TRANSFERRING state.
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start sending datagrams
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should stay at TRANSFERRING state.
+        assertModemStateChangedCallbackNotCalled(mTestSatelliteStateCallback);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Receiving datagrams failed.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED);
+        processAllMessages();
+
+        // SatelliteSessionController should stay at TRANSFERRING state instead of moving to IDLE
+        // state.
+        assertModemStateChangedCallbackNotCalled(mTestSatelliteStateCallback);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Start receiving datagrams again.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should stay at TRANSFERRING state.
+        assertModemStateChangedCallbackNotCalled(mTestSatelliteStateCallback);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Sending datagrams failed.
+        mTestSatelliteSessionController.onDatagramTransferStateChanged(
+                SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
+                SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
+        processAllMessages();
+
+        // SatelliteSessionController should stay at TRANSFERRING state instead of moving to IDLE
+        // state.
+        assertModemStateChangedCallbackNotCalled(mTestSatelliteStateCallback);
+        assertEquals(STATE_TRANSFERRING, mTestSatelliteSessionController.getCurrentStateName());
+        assertTrue(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+
+        // Power off the modem.
+        mTestSatelliteSessionController.onSatelliteEnabledStateChanged(false);
+        processAllMessages();
+
+        // SatelliteSessionController should move to POWER_OFF state.
+        assertSuccessfulModemStateChangedCallback(
+                mTestSatelliteStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+        assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+        assertFalse(mTestSatelliteSessionController.isSendingTriggeredDuringTransferringState());
+    }
+
+    private static class TestSatelliteModemInterface extends SatelliteModemInterface {
+        private final AtomicInteger mListeningEnabledCount = new AtomicInteger(0);
+        private final AtomicInteger mListeningDisabledCount = new AtomicInteger(0);
+
+        TestSatelliteModemInterface(@NonNull Context context,
+                SatelliteController satelliteController, @NonNull Looper looper) {
+            super(context, satelliteController, looper);
+            mExponentialBackoff.stop();
+        }
+
+        @Override
+        protected void bindService() {
+            logd("TestSatelliteModemInterface: bindService");
+        }
+
+        @Override
+        protected void unbindService() {
+            logd("TestSatelliteModemInterface: unbindService");
+        }
+
+        @Override
+        public void requestSatelliteListeningEnabled(boolean enable, int timeout,
+                @Nullable Message message) {
+            if (enable) mListeningEnabledCount.incrementAndGet();
+            else mListeningDisabledCount.incrementAndGet();
+        }
+
+        public int getListeningEnabledCount() {
+            return mListeningEnabledCount.get();
+        }
+
+        public int getListeningDisabledCount() {
+            return mListeningDisabledCount.get();
+        }
+    }
+
+    private static class TestSatelliteSessionController extends SatelliteSessionController {
+        TestSatelliteSessionController(Context context, Looper looper, boolean isSatelliteSupported,
+                SatelliteModemInterface satelliteModemInterface,
+                long satelliteStayAtListeningFromSendingMillis,
+                long satelliteStayAtListeningFromReceivingMillis) {
+            super(context, looper, isSatelliteSupported, satelliteModemInterface,
+                    satelliteStayAtListeningFromSendingMillis,
+                    satelliteStayAtListeningFromReceivingMillis);
+        }
+
+        public String getCurrentStateName() {
+            return getCurrentState().getName();
+        }
+
+        public boolean isSendingTriggeredDuringTransferringState() {
+            return mIsSendingTriggeredDuringTransferringState.get();
+        }
+    }
+
+    private static class TestSatelliteStateCallback extends ISatelliteStateCallback.Stub {
+        private final AtomicInteger mModemState = new AtomicInteger(
+                SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        @Override
+        public void onSatelliteModemStateChanged(int state) {
+            logd("onSatelliteModemStateChanged: state=" + state);
+            mModemState.set(state);
+            try {
+                mSemaphore.release();
+            } catch (Exception ex) {
+                logd("onSatelliteModemStateChanged: Got exception, ex=" + ex);
+            }
+        }
+
+        public boolean waitUntilResult() {
+            try {
+                if (!mSemaphore.tryAcquire(EVENT_PROCESSING_TIME_MILLIS, TimeUnit.MILLISECONDS)) {
+                    logd("Timeout to receive onSatelliteModemStateChanged");
+                    return false;
+                }
+                return true;
+            } catch (Exception ex) {
+                logd("onSatelliteModemStateChanged: Got exception=" + ex);
+                return false;
+            }
+        }
+
+        public int getModemState() {
+            return mModemState.get();
+        }
+    }
+
+    private static void assertSuccessfulModemStateChangedCallback(
+            TestSatelliteStateCallback callback,
+            @SatelliteManager.SatelliteModemState int expectedModemState) {
+        boolean successful = callback.waitUntilResult();
+        assertTrue(successful);
+        assertEquals(expectedModemState, callback.getModemState());
+    }
+
+    private static void assertModemStateChangedCallbackNotCalled(
+            TestSatelliteStateCallback callback) {
+        boolean successful = callback.waitUntilResult();
+        assertFalse(successful);
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
index f49f3db..9898353 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
@@ -30,11 +30,13 @@
 import static org.mockito.Mockito.verify;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Looper;
 import android.provider.Telephony;
 import android.provider.Telephony.SimInfo;
@@ -56,16 +58,19 @@
 import org.mockito.Mockito;
 
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class SubscriptionDatabaseManagerTest extends TelephonyTest {
+
+    static final String FAKE_DEFAULT_CARD_NAME = "CARD %d";
     static final String FAKE_ICCID1 = "123456";
     static final String FAKE_ICCID2 = "456789";
     static final String FAKE_PHONE_NUMBER1 = "6502530000";
@@ -113,6 +118,9 @@
     static final int FAKE_USER_ID1 = 10;
     static final int FAKE_USER_ID2 = 11;
 
+    static final String FAKE_MAC_ADDRESS1 = "DC:E5:5B:38:7D:40";
+    static final String FAKE_MAC_ADDRESS2 = "DC:B5:4F:47:F3:4C";
+
     static final SubscriptionInfoInternal FAKE_SUBSCRIPTION_INFO1 =
             new SubscriptionInfoInternal.Builder()
                     .setId(1)
@@ -134,6 +142,18 @@
                     .setNativeAccessRules(FAKE_NATIVE_ACCESS_RULES1)
                     .setCarrierConfigAccessRules(FAKE_CARRIER_CONFIG_ACCESS_RULES1)
                     .setRemovableEmbedded(0)
+                    .setCellBroadcastExtremeThreatAlertEnabled(1)
+                    .setCellBroadcastSevereThreatAlertEnabled(1)
+                    .setCellBroadcastAmberAlertEnabled(1)
+                    .setCellBroadcastEmergencyAlertEnabled(1)
+                    .setCellBroadcastAlertSoundDuration(4)
+                    .setCellBroadcastAlertReminderInterval(1)
+                    .setCellBroadcastAlertVibrationEnabled(1)
+                    .setCellBroadcastAlertSpeechEnabled(1)
+                    .setCellBroadcastEtwsTestAlertEnabled(1)
+                    .setCellBroadcastAreaInfoMessageEnabled(1)
+                    .setCellBroadcastTestAlertEnabled(1)
+                    .setCellBroadcastOptOutDialogEnabled(1)
                     .setEnhanced4GModeEnabled(1)
                     .setVideoTelephonyEnabled(1)
                     .setWifiCallingEnabled(1)
@@ -190,6 +210,18 @@
                     .setNativeAccessRules(FAKE_NATIVE_ACCESS_RULES2)
                     .setCarrierConfigAccessRules(FAKE_CARRIER_CONFIG_ACCESS_RULES2)
                     .setRemovableEmbedded(1)
+                    .setCellBroadcastExtremeThreatAlertEnabled(0)
+                    .setCellBroadcastSevereThreatAlertEnabled(0)
+                    .setCellBroadcastAmberAlertEnabled(0)
+                    .setCellBroadcastEmergencyAlertEnabled(0)
+                    .setCellBroadcastAlertSoundDuration(0)
+                    .setCellBroadcastAlertReminderInterval(0)
+                    .setCellBroadcastAlertVibrationEnabled(0)
+                    .setCellBroadcastAlertSpeechEnabled(0)
+                    .setCellBroadcastEtwsTestAlertEnabled(0)
+                    .setCellBroadcastAreaInfoMessageEnabled(0)
+                    .setCellBroadcastTestAlertEnabled(0)
+                    .setCellBroadcastOptOutDialogEnabled(0)
                     .setEnhanced4GModeEnabled(0)
                     .setVideoTelephonyEnabled(0)
                     .setWifiCallingEnabled(0)
@@ -343,19 +375,19 @@
             mDatabase.add(values);
             return ContentUris.withAppendedId(SimInfo.CONTENT_URI, subId);
         }
-    }
 
-    private void loadFromDatabase() throws Exception {
-        Method method = SubscriptionDatabaseManager.class.getDeclaredMethod("loadFromDatabase");
-        method.setAccessible(true);
-        method.invoke(mDatabaseManagerUT);
-        processAllMessages();
+        @Override
+        public Bundle call(String method, @Nullable String args, @Nullable Bundle bundle) {
+            return new Bundle();
+        }
     }
 
     @Before
     public void setUp() throws Exception {
         logd("SubscriptionDatabaseManagerTest +Setup!");
         super.setUp(getClass().getSimpleName());
+        mContextFixture.putBooleanResource(com.android.internal.R.bool
+                .config_subscription_database_async_update, true);
         mSubscriptionDatabaseManagerCallback =
                 Mockito.mock(SubscriptionDatabaseManagerCallback.class);
         doAnswer(invocation -> {
@@ -365,6 +397,7 @@
 
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 Telephony.Carriers.CONTENT_URI.getAuthority(), mSubscriptionProvider);
+
         doReturn(1).when(mUiccController).convertToPublicCardId(eq(FAKE_ICCID1));
         doReturn(2).when(mUiccController).convertToPublicCardId(eq(FAKE_ICCID2));
         mDatabaseManagerUT = new SubscriptionDatabaseManager(mContext, Looper.myLooper(),
@@ -389,7 +422,9 @@
                 .that(mDatabaseManagerUT.getSubscriptionInfoInternal(subId)).isEqualTo(subInfo);
 
         // Load subscription info from the database.
-        loadFromDatabase();
+        mDatabaseManagerUT.reloadDatabase();
+        processAllMessages();
+
         // Verify the database value is same as the inserted one.
         assertWithMessage("Subscription info database value is different.")
                 .that(mDatabaseManagerUT.getSubscriptionInfoInternal(subId)).isEqualTo(subInfo);
@@ -885,6 +920,294 @@
     }
 
     @Test
+    public void testUpdateCellBroadcastExtremeThreatAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastExtremeThreatAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastExtremeThreatAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastExtremeThreatAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastExtremeThreatAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastSevereThreatAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastSevereThreatAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastSevereThreatAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastSevereThreatAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastSevereThreatAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAmberAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAmberAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAmberAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAmberAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_AMBER_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_AMBER_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAmberAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastEmergencyAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastEmergencyAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastEmergencyAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastEmergencyAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_EMERGENCY_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_EMERGENCY_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastEmergencyAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAlertSoundDuration() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAlertSoundDuration(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAlertSoundDuration(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAlertSoundDuration(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_ALERT_SOUND_DURATION))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_ALERT_SOUND_DURATION, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAlertSoundDuration()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAlertReminderInterval() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAlertReminderInterval(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAlertReminderInterval(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAlertReminderInterval(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAlertReminderInterval()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAlertVibrationEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAlertVibrationEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAlertVibrationEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAlertVibrationEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_ALERT_VIBRATE))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_ALERT_VIBRATE, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAlertVibrationEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAlertSpeechEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAlertSpeechEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAlertSpeechEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAlertSpeechEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_ALERT_SPEECH))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_ALERT_SPEECH, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAlertSpeechEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastEtwsTestAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastEtwsTestAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastEtwsTestAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastEtwsTestAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_ETWS_TEST_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_ETWS_TEST_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastEtwsTestAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastAreaInfoMessageEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastAreaInfoMessageEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastAreaInfoMessageEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastAreaInfoMessageEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_CHANNEL_50_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_CHANNEL_50_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastAreaInfoMessageEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastTestAlertEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastTestAlertEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastTestAlertEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastTestAlertEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_CMAS_TEST_ALERT))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_CMAS_TEST_ALERT, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastTestAlertEnabled()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateCellBroadcastOptOutDialogEnabled() throws Exception {
+        // exception is expected if there is nothing in the database.
+        assertThrows(IllegalArgumentException.class,
+                () -> mDatabaseManagerUT.setCellBroadcastOptOutDialogEnabled(1, 1));
+
+        SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+        mDatabaseManagerUT.setCellBroadcastOptOutDialogEnabled(
+                subInfo.getSubscriptionId(), 0);
+        processAllMessages();
+
+        subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+                .setCellBroadcastOptOutDialogEnabled(0).build();
+        verifySubscription(subInfo);
+        verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+        assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+                1, SimInfo.COLUMN_CB_OPT_OUT_DIALOG))
+                .isEqualTo(0);
+        mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CB_OPT_OUT_DIALOG, 1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .getCellBroadcastOptOutDialogEnabled()).isEqualTo(1);
+    }
+
+    @Test
     public void testUpdateEnhanced4GModeEnabled() throws Exception {
         // exception is expected if there is nothing in the database.
         assertThrows(IllegalArgumentException.class,
@@ -903,6 +1226,8 @@
         mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).getEnhanced4GModeEnabled())
                 .isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).isEnhanced4GModeEnabled())
+                .isTrue();
     }
 
     @Test
@@ -924,6 +1249,8 @@
         mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_VT_IMS_ENABLED, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).getVideoTelephonyEnabled())
                 .isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).isVideoTelephonyEnabled())
+                .isTrue();
     }
 
     @Test
@@ -1040,6 +1367,8 @@
         mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_VOIMS_OPT_IN_STATUS, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
                 .getVoImsOptInEnabled()).isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).isVoImsOptInEnabled())
+                .isTrue();
     }
 
 
@@ -1290,6 +1619,8 @@
         mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_IMS_RCS_UCE_ENABLED, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).getRcsUceEnabled())
                 .isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).isRcsUceEnabled())
+                .isTrue();
     }
 
     @Test
@@ -1312,6 +1643,8 @@
         mDatabaseManagerUT.setSubscriptionProperty(1, SimInfo.COLUMN_CROSS_SIM_CALLING_ENABLED, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).getCrossSimCallingEnabled())
                 .isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1).isCrossSimCallingEnabled())
+                .isTrue();
     }
 
     @Test
@@ -1413,6 +1746,8 @@
                 1, SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED, 1);
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
                 .getNrAdvancedCallingEnabled()).isEqualTo(1);
+        assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(1)
+                .isNrAdvancedCallingEnabled()).isTrue();
     }
 
     @Test
@@ -1666,4 +2001,38 @@
         assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(3)).isNull();
         verify(mSubscriptionDatabaseManagerCallback).onSubscriptionChanged(eq(3));
     }
+
+    @Test
+    public void testCallback() {
+        CountDownLatch latch = new CountDownLatch(2);
+        Executor executor = Runnable::run;
+        SubscriptionDatabaseManagerCallback callback =
+                new SubscriptionDatabaseManagerCallback(executor) {
+                    @Override
+                    public void onInitialized() {
+                        latch.countDown();
+                        logd("onInitialized");
+                    }
+
+                    @Override
+                    public void onSubscriptionChanged(int subId) {
+                        latch.countDown();
+                        logd("onSubscriptionChanged");
+                    }
+                };
+        assertThat(callback.getExecutor()).isEqualTo(executor);
+        mDatabaseManagerUT = new SubscriptionDatabaseManager(mContext, Looper.myLooper(), callback);
+        processAllMessages();
+
+        assertThat(latch.getCount()).isEqualTo(1);
+
+        mDatabaseManagerUT.insertSubscriptionInfo(
+                new SubscriptionInfoInternal.Builder()
+                        .setId(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+                        .setIccId(FAKE_ICCID1)
+                        .setSimSlotIndex(0)
+                        .build());
+        processAllMessages();
+        assertThat(latch.getCount()).isEqualTo(0);
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
index 0b5217d..e03256b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
@@ -53,6 +53,18 @@
                     .setCarrierConfigAccessRules(SubscriptionDatabaseManagerTest
                             .FAKE_CARRIER_CONFIG_ACCESS_RULES1)
                     .setRemovableEmbedded(0)
+                    .setCellBroadcastExtremeThreatAlertEnabled(1)
+                    .setCellBroadcastSevereThreatAlertEnabled(1)
+                    .setCellBroadcastAmberAlertEnabled(1)
+                    .setCellBroadcastEmergencyAlertEnabled(1)
+                    .setCellBroadcastAlertSoundDuration(4)
+                    .setCellBroadcastAlertReminderInterval(1)
+                    .setCellBroadcastAlertVibrationEnabled(1)
+                    .setCellBroadcastAlertSpeechEnabled(1)
+                    .setCellBroadcastEtwsTestAlertEnabled(1)
+                    .setCellBroadcastAreaInfoMessageEnabled(1)
+                    .setCellBroadcastTestAlertEnabled(1)
+                    .setCellBroadcastOptOutDialogEnabled(1)
                     .setEnhanced4GModeEnabled(1)
                     .setVideoTelephonyEnabled(1)
                     .setWifiCallingEnabled(1)
@@ -145,6 +157,18 @@
         assertThat(mSubInfo.getCarrierConfigAccessRules()).isEqualTo(SubscriptionDatabaseManagerTest
                 .FAKE_CARRIER_CONFIG_ACCESS_RULES1);
         assertThat(mSubInfo.getRemovableEmbedded()).isEqualTo(0);
+        assertThat(mSubInfo.getCellBroadcastExtremeThreatAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastSevereThreatAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastAmberAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastEmergencyAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastAlertSoundDuration()).isEqualTo(4);
+        assertThat(mSubInfo.getCellBroadcastAlertReminderInterval()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastAlertVibrationEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastAlertSpeechEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastEtwsTestAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastAreaInfoMessageEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastTestAlertEnabled()).isEqualTo(1);
+        assertThat(mSubInfo.getCellBroadcastOptOutDialogEnabled()).isEqualTo(1);
         assertThat(mSubInfo.getEnhanced4GModeEnabled()).isEqualTo(1);
         assertThat(mSubInfo.getVideoTelephonyEnabled()).isEqualTo(1);
         assertThat(mSubInfo.getWifiCallingEnabled()).isEqualTo(1);
@@ -194,6 +218,7 @@
     public void testEquals() {
         SubscriptionInfoInternal another = new SubscriptionInfoInternal.Builder(mSubInfo).build();
         assertThat(another).isEqualTo(mSubInfo);
+        assertThat(another.hashCode()).isEqualTo(mSubInfo.hashCode());
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
index c4fd850..38b495a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.subscription;
 
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_ID1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_ID2;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_NAME1;
@@ -24,8 +23,14 @@
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CONTACT1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CONTACT2;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_COUNTRY_CODE2;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_DEFAULT_CARD_NAME;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_EHPLMNS1;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_HPLMNS1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_ICCID1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_ICCID2;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_IMSI1;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_MAC_ADDRESS1;
+import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_MAC_ADDRESS2;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_MCC1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_MCC2;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_MNC1;
@@ -51,10 +56,11 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -65,7 +71,6 @@
 import android.compat.testing.PlatformCompatChangeRule;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -79,21 +84,28 @@
 import android.service.euicc.EuiccProfileInfo;
 import android.service.euicc.EuiccService;
 import android.service.euicc.GetEuiccProfileInfoListResult;
+import android.telephony.RadioAccessFamily;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.test.mock.MockContentResolver;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.util.ArraySet;
 import android.util.Base64;
 
 import com.android.internal.telephony.ContextFixture;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.euicc.EuiccController;
 import com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.SubscriptionProvider;
 import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
-import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionMap;
+import com.android.internal.telephony.uicc.IccCardStatus;
 import com.android.internal.telephony.uicc.UiccSlot;
 
 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -107,11 +119,16 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Array;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -121,6 +138,8 @@
 
     private static final String CALLING_FEATURE = "calling_feature";
 
+    private static final String GROUP_UUID = "6adbc864-691c-45dc-b698-8fc9a2176fae";
+
     private SubscriptionManagerService mSubscriptionManagerServiceUT;
 
     private final SubscriptionProvider mSubscriptionProvider = new SubscriptionProvider();
@@ -130,8 +149,8 @@
     // mocked
     private SubscriptionManagerServiceCallback mMockedSubscriptionManagerServiceCallback;
     private EuiccController mEuiccController;
-    private UiccSlot mUiccSlot;
-    private UiccCard mUiccCard;
+
+    private Set<Integer> mActiveSubs = new ArraySet<>();
 
     @Rule
     public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -141,6 +160,16 @@
         logd("SubscriptionManagerServiceTest +Setup!");
         super.setUp(getClass().getSimpleName());
 
+        // Dual-SIM configuration
+        mPhones = new Phone[] {mPhone, mPhone2};
+        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
+        doReturn(2).when(mTelephonyManager).getSupportedModemCount();
+        doReturn(mUiccProfile).when(mPhone2).getIccCard();
+        doReturn(new UiccSlot[]{mUiccSlot}).when(mUiccController).getUiccSlots();
+
+        mContextFixture.putBooleanResource(com.android.internal.R.bool
+                .config_subscription_database_async_update, true);
         mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[0]);
 
         mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_EUICC);
@@ -150,18 +179,23 @@
         doReturn(true).when(mTelephonyManager).isVoiceCapable();
         mEuiccController = Mockito.mock(EuiccController.class);
         replaceInstance(EuiccController.class, "sInstance", null, mEuiccController);
-        mUiccSlot = Mockito.mock(UiccSlot.class);
-        mUiccCard = Mockito.mock(UiccCard.class);
         mMockedSubscriptionManagerServiceCallback = Mockito.mock(
                 SubscriptionManagerServiceCallback.class);
-        doReturn(mUiccCard).when(mUiccSlot).getUiccCard();
         doReturn(FAKE_ICCID1).when(mUiccCard).getCardId();
+        doReturn(FAKE_ICCID1).when(mUiccPort).getIccId();
+        doReturn(true).when(mUiccSlot).isActive();
+        doReturn(FAKE_ICCID1).when(mUiccController).convertToCardString(eq(1));
+        doReturn(FAKE_ICCID2).when(mUiccController).convertToCardString(eq(2));
+
+        doReturn(new int[0]).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
 
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 Telephony.Carriers.CONTENT_URI.getAuthority(), mSubscriptionProvider);
+
         mSubscriptionManagerServiceUT = new SubscriptionManagerService(mContext, Looper.myLooper());
 
         monitorTestableLooper(new TestableLooper(getBackgroundHandler().getLooper()));
+        monitorTestableLooper(new TestableLooper(getSubscriptionDatabaseManager().getLooper()));
 
         doAnswer(invocation -> {
             ((Runnable) invocation.getArguments()[0]).run();
@@ -169,8 +203,6 @@
         }).when(mMockedSubscriptionManagerServiceCallback).invokeFromExecutor(any(Runnable.class));
 
         mSubscriptionManagerServiceUT.registerCallback(mMockedSubscriptionManagerServiceCallback);
-        // Database loading is on a different thread. Need to wait a bit.
-        waitForMs(100);
         processAllFutureMessages();
 
         // Revoke all permissions.
@@ -204,8 +236,16 @@
         return (Handler) field.get(mSubscriptionManagerServiceUT);
     }
 
+    private SubscriptionDatabaseManager getSubscriptionDatabaseManager() throws Exception {
+        Field field = SubscriptionManagerService.class.getDeclaredField(
+                "mSubscriptionDatabaseManager");
+        field.setAccessible(true);
+        return (SubscriptionDatabaseManager) field.get(mSubscriptionManagerServiceUT);
+    }
+
     /**
-     * Insert the subscription info to the database.
+     * Insert the subscription info to the database. This is an instant insertion method. For real
+     * insertion sequence please use {@link #testInsertNewSim()}.
      *
      * @param subInfo The subscription to be inserted.
      * @return The new sub id.
@@ -215,39 +255,43 @@
             mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
             subInfo = new SubscriptionInfoInternal.Builder(subInfo)
                     .setId(SubscriptionManager.INVALID_SUBSCRIPTION_ID).build();
-
-            Field field = SubscriptionManagerService.class.getDeclaredField(
-                    "mSubscriptionDatabaseManager");
-            field.setAccessible(true);
-            SubscriptionDatabaseManager sdbm =
-                    (SubscriptionDatabaseManager) field.get(mSubscriptionManagerServiceUT);
-
-            Class[] cArgs = new Class[1];
-            cArgs[0] = SubscriptionInfoInternal.class;
-            Method method = SubscriptionDatabaseManager.class.getDeclaredMethod(
-                    "insertSubscriptionInfo", cArgs);
-            method.setAccessible(true);
-            int subId = (int) method.invoke(sdbm, subInfo);
+            int subId = getSubscriptionDatabaseManager().insertSubscriptionInfo(subInfo);
 
             // Insertion is sync, but the onSubscriptionChanged callback is handled by the handler.
             processAllMessages();
 
-            Class<?> WatchedMapClass = Class.forName("com.android.internal.telephony.subscription"
-                    + ".SubscriptionManagerService$WatchedMap");
-            field = SubscriptionManagerService.class.getDeclaredField("mSlotIndexToSubId");
+            Field field = SubscriptionManagerService.class.getDeclaredField("mSlotIndexToSubId");
             field.setAccessible(true);
-            Object map = field.get(mSubscriptionManagerServiceUT);
-            cArgs = new Class[2];
+            SubscriptionMap<Integer, Integer> map = (SubscriptionMap<Integer, Integer>)
+                    field.get(mSubscriptionManagerServiceUT);
+            Class[] cArgs = new Class[2];
             cArgs[0] = Object.class;
             cArgs[1] = Object.class;
 
-            method = WatchedMapClass.getDeclaredMethod("put", cArgs);
-            method.setAccessible(true);
-            method.invoke(map, subInfo.getSimSlotIndex(), subId);
+            if (subInfo.getSimSlotIndex() >= 0) {
+                // Change the slot -> subId mapping
+                map.put(subInfo.getSimSlotIndex(), subId);
+            }
+
             mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
             processAllMessages();
             verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(subId));
             Mockito.clearInvocations(mMockedSubscriptionManagerServiceCallback);
+
+            if (subInfo.getSimSlotIndex() >= 0) {
+                mActiveSubs.add(subId);
+
+                // Change the SIM state
+                field = SubscriptionManagerService.class.getDeclaredField("mSimState");
+                field.setAccessible(true);
+                Object array = field.get(mSubscriptionManagerServiceUT);
+                Array.set(array, subInfo.getSimSlotIndex(), TelephonyManager.SIM_STATE_LOADED);
+            } else {
+                mActiveSubs.remove(subId);
+            }
+
+            doReturn(mActiveSubs.stream().mapToInt(i->i).toArray()).when(mSubscriptionManager)
+                    .getCompleteActiveSubscriptionIdList();
             return subId;
         } catch (Exception e) {
             fail("Failed to insert subscription. e=" + e);
@@ -255,11 +299,15 @@
         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     }
 
-    private void enableGetSubscriptionUserHandle() {
-        Resources mResources = mock(Resources.class);
-        doReturn(true).when(mResources).getBoolean(
-                eq(com.android.internal.R.bool.config_enable_get_subscription_user_handle));
-        doReturn(mResources).when(mContext).getResources();
+    @Test
+    public void testBroadcastOnInitialization() {
+        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext, times(3)).sendBroadcastAsUser(
+                captorIntent.capture(), eq(UserHandle.ALL));
+        assertThat(captorIntent.getAllValues().stream().map(Intent::getAction).toList())
+                .containsExactly(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
+                        TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED,
+                        SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
     }
 
     @Test
@@ -378,7 +426,6 @@
     @Test
     public void testGetAllSubInfoList() {
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
-        doReturn(new int[]{1, 2}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
@@ -447,8 +494,6 @@
     @Test
     @EnableCompatChanges({SubscriptionManagerService.REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID})
     public void testGetSubscriptionsInGroup() {
-        doReturn(new int[]{1, 2}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
-
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         SubscriptionInfoInternal anotherSubInfo =
                 new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2)
@@ -536,6 +581,7 @@
 
     @Test
     public void testSetDefaultVoiceSubId() throws Exception {
+        clearInvocations(mContext);
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
@@ -548,11 +594,12 @@
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
 
         mSubscriptionManagerServiceUT.setDefaultVoiceSubId(1);
+        assertThat(mSubscriptionManagerServiceUT.getDefaultVoiceSubId()).isEqualTo(1);
 
         assertThat(Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION)).isEqualTo(1);
         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext, times(2)).sendStickyBroadcastAsUser(
+        verify(mContext, times(2)).sendBroadcastAsUser(
                 captorIntent.capture(), eq(UserHandle.ALL));
 
         Intent intent = captorIntent.getAllValues().get(0);
@@ -576,6 +623,7 @@
 
     @Test
     public void testSetDefaultDataSubId() throws Exception {
+        clearInvocations(mContext);
         doReturn(false).when(mTelephonyManager).isVoiceCapable();
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
@@ -589,11 +637,12 @@
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
 
         mSubscriptionManagerServiceUT.setDefaultDataSubId(1);
+        assertThat(mSubscriptionManagerServiceUT.getDefaultDataSubId()).isEqualTo(1);
 
         assertThat(Settings.Global.getInt(mContext.getContentResolver(),
                         Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION)).isEqualTo(1);
         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext, times(2)).sendStickyBroadcastAsUser(
+        verify(mContext, times(2)).sendBroadcastAsUser(
                 captorIntent.capture(), eq(UserHandle.ALL));
 
         Intent intent = captorIntent.getAllValues().get(0);
@@ -617,6 +666,7 @@
 
     @Test
     public void testSetDefaultSmsSubId() throws Exception {
+        clearInvocations(mContext);
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
@@ -628,11 +678,12 @@
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
 
         mSubscriptionManagerServiceUT.setDefaultSmsSubId(1);
+        assertThat(mSubscriptionManagerServiceUT.getDefaultSmsSubId()).isEqualTo(1);
 
         assertThat(Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION)).isEqualTo(1);
         ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext).sendStickyBroadcastAsUser(captorIntent.capture(), eq(UserHandle.ALL));
+        verify(mContext).sendBroadcastAsUser(captorIntent.capture(), eq(UserHandle.ALL));
 
         Intent intent = captorIntent.getValue();
         assertThat(intent.getAction()).isEqualTo(
@@ -664,7 +715,6 @@
 
     @Test
     public void testGetActiveSubscriptionInfoList() {
-        doReturn(new int[]{1}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
         // Grant MODIFY_PHONE_STATE permission for insertion.
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
@@ -673,9 +723,9 @@
         // Remove MODIFY_PHONE_STATE
         mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
 
-        // Should fail without READ_PHONE_STATE
-        assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
-                .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE));
+        // Should get an empty list without READ_PHONE_STATE.
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
 
         // Grant READ_PHONE_STATE permission for insertion.
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
@@ -750,8 +800,8 @@
         result = new GetEuiccProfileInfoListResult(EuiccService.RESULT_OK,
                 new EuiccProfileInfo[]{profileInfo2}, false);
         doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(2));
-        doReturn(FAKE_ICCID1).when(mUiccController).convertToCardString(eq(1));
-        doReturn(FAKE_ICCID2).when(mUiccController).convertToCardString(eq(2));
+        doReturn(TelephonyManager.INVALID_PORT_INDEX).when(mUiccSlot)
+                .getPortIndexFromIccId(anyString());
 
         mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1, 2), null);
         processAllMessages();
@@ -760,6 +810,7 @@
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -775,6 +826,7 @@
         subInfo = mSubscriptionManagerServiceUT.getSubscriptionInfoInternal(2);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(2);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID2);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME2);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -789,6 +841,21 @@
     }
 
     @Test
+    public void testUpdateEmbeddedSubscriptionsNullResult() {
+        // Grant READ_PHONE_STATE permission.
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
+
+        doReturn(null).when(mEuiccController).blockingGetEuiccProfileInfoList(anyInt());
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1, 2), null);
+        processAllMessages();
+
+        List<SubscriptionInfo> subInfoList = mSubscriptionManagerServiceUT
+                .getAllSubInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+        assertThat(subInfoList).isEmpty();
+    }
+
+    @Test
     public void testGetActiveSubscriptionInfo() {
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
 
@@ -842,7 +909,6 @@
 
     @Test
     public void testGetActiveSubInfoCount() {
-        doReturn(new int[]{1, 2}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
@@ -890,21 +956,33 @@
 
     @Test
     public void testGetAccessibleSubscriptionInfoList() {
+        doReturn(true).when(mEuiccManager).isEnabled();
+        insertSubscription(FAKE_SUBSCRIPTION_INFO2);
+
+        doReturn(true).when(mSubscriptionManager).canManageSubscription(
+                any(SubscriptionInfo.class), eq(CALLING_PACKAGE));
+        // FAKE_SUBSCRIPTION_INFO2 is a not eSIM. So the list should be empty.
+        assertThat(mSubscriptionManagerServiceUT.getAccessibleSubscriptionInfoList(
+                CALLING_PACKAGE)).isEmpty();
+
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
 
         doReturn(false).when(mEuiccManager).isEnabled();
         assertThat(mSubscriptionManagerServiceUT.getAccessibleSubscriptionInfoList(
                 CALLING_PACKAGE)).isNull();
 
+        doReturn(false).when(mSubscriptionManager).canManageSubscription(
+                any(SubscriptionInfo.class), eq(CALLING_PACKAGE));
+
         doReturn(true).when(mEuiccManager).isEnabled();
         assertThat(mSubscriptionManagerServiceUT.getAccessibleSubscriptionInfoList(
                 CALLING_PACKAGE)).isEmpty();
 
         doReturn(true).when(mSubscriptionManager).canManageSubscription(
-                eq(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()), eq(CALLING_PACKAGE));
-
+                any(SubscriptionInfo.class), eq(CALLING_PACKAGE));
         assertThat(mSubscriptionManagerServiceUT.getAccessibleSubscriptionInfoList(
-                CALLING_PACKAGE)).isEqualTo(List.of(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()));
+                CALLING_PACKAGE)).isEqualTo(List.of(new SubscriptionInfoInternal.Builder(
+                        FAKE_SUBSCRIPTION_INFO1).setId(2).build().toSubscriptionInfo()));
     }
 
     @Test
@@ -932,7 +1010,6 @@
         assertThrows(IllegalArgumentException.class, () -> mSubscriptionManagerServiceUT
                 .getEnabledSubscriptionId(SubscriptionManager.INVALID_SIM_SLOT_INDEX));
 
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
         assertThat(mSubscriptionManagerServiceUT.getEnabledSubscriptionId(0)).isEqualTo(1);
         assertThat(mSubscriptionManagerServiceUT.getEnabledSubscriptionId(1)).isEqualTo(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
@@ -949,7 +1026,6 @@
     @Test
     public void testSetGetSubscriptionUserHandle() {
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
-        enableGetSubscriptionUserHandle();
 
         // Should fail without MANAGE_SUBSCRIPTION_USER_ASSOCIATION
         assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
@@ -983,7 +1059,6 @@
     @Test
     public void testIsSubscriptionAssociatedWithUser() {
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
-        enableGetSubscriptionUserHandle();
 
         // Should fail without MANAGE_SUBSCRIPTION_USER_ASSOCIATION
         assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
@@ -1010,7 +1085,6 @@
 
     @Test
     public void testSetUsageSetting() {
-        doReturn(new int[]{1}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
 
         // Should fail without MODIFY_PHONE_STATE
@@ -1050,12 +1124,11 @@
         SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo).isNotNull();
-        assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_PHONE_NUMBER2);
+        assertThat(subInfo.getNumber()).isEqualTo(FAKE_PHONE_NUMBER2);
     }
 
     @Test
     public void testSetOpportunistic() {
-        doReturn(new int[]{1}).when(mSubscriptionManager).getCompleteActiveSubscriptionIdList();
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
 
         // Should fail without MODIFY_PHONE_STATE
@@ -1078,9 +1151,9 @@
         testSetOpportunistic();
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
-        // Should fail without READ_PHONE_STATE
-        assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
-                .getOpportunisticSubscriptions(CALLING_PACKAGE, CALLING_FEATURE));
+        // Should get an empty list without READ_PHONE_STATE.
+        assertThat(mSubscriptionManagerServiceUT.getOpportunisticSubscriptions(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
 
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
 
@@ -1124,7 +1197,7 @@
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
-        ParcelUuid newUuid = ParcelUuid.fromString("6adbc864-691c-45dc-b698-8fc9a2176fae");
+        ParcelUuid newUuid = ParcelUuid.fromString(GROUP_UUID);
         String newOwner = "new owner";
         // Should fail without MODIFY_PHONE_STATE
         assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
@@ -1213,11 +1286,20 @@
         mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, 1);
         processAllMessages();
         verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(1));
+        verify(mMockedSubscriptionManagerServiceCallback).onUiccApplicationsEnabledChanged(eq(1));
 
         SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo).isNotNull();
         assertThat(subInfo.areUiccApplicationsEnabled()).isFalse();
+
+        Mockito.clearInvocations(mMockedSubscriptionManagerServiceCallback);
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, 1);
+        processAllMessages();
+
+        verify(mMockedSubscriptionManagerServiceCallback, never()).onSubscriptionChanged(eq(1));
+        verify(mMockedSubscriptionManagerServiceCallback, never())
+                .onUiccApplicationsEnabledChanged(eq(1));
     }
 
     @Test
@@ -1695,20 +1777,23 @@
 
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
         assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(0);
+                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true);
         assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID2,
-                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(0);
+                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true);
 
         mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(
                 CALLING_PACKAGE, CALLING_FEATURE).isEmpty()).isTrue();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
     }
 
     @Test
     public void testUserUnlockUpdateEmbeddedSubscriptions() {
         doReturn(true).when(mUiccSlot).isEuicc();
         doReturn(1).when(mUiccController).convertToPublicCardId(FAKE_ICCID1);
-        doReturn(new UiccSlot[]{mUiccSlot}).when(mUiccController).getUiccSlots();
+        doReturn(TelephonyManager.INVALID_PORT_INDEX).when(mUiccSlot)
+                .getPortIndexFromIccId(anyString());
 
         EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
                 .setIccid(FAKE_ICCID1)
@@ -1723,7 +1808,6 @@
         GetEuiccProfileInfoListResult result = new GetEuiccProfileInfoListResult(
                 EuiccService.RESULT_OK, new EuiccProfileInfo[]{profileInfo1}, false);
         doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
-        doReturn(FAKE_ICCID1).when(mUiccController).convertToCardString(eq(1));
 
         mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED));
         processAllMessages();
@@ -1734,6 +1818,7 @@
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -1746,4 +1831,555 @@
         assertThat(subInfo.isRemovableEmbedded()).isFalse();
         assertThat(subInfo.getNativeAccessRules()).isEqualTo(FAKE_NATIVE_ACCESS_RULES1);
     }
+
+    @Test
+    public void testInsertNewSim() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+
+        doReturn(FAKE_IMSI1).when(mTelephonyManager).getSubscriberId();
+        doReturn(FAKE_MCC1 + FAKE_MNC1).when(mTelephonyManager).getSimOperatorNumeric(anyInt());
+        doReturn(FAKE_PHONE_NUMBER1).when(mTelephonyManager).getLine1Number(anyInt());
+        doReturn(FAKE_EHPLMNS1.split(",")).when(mSimRecords).getEhplmns();
+        doReturn(FAKE_HPLMNS1.split(",")).when(mSimRecords).getPlmnsFromHplmnActRecord();
+        doReturn(0).when(mUiccSlot).getPortIndexFromIccId(anyString());
+        doReturn(false).when(mUiccSlot).isEuicc();
+        doReturn(1).when(mUiccController).convertToPublicCardId(eq(FAKE_ICCID1));
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_READY, null, null);
+        processAllMessages();
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_LOADED, null, null);
+        processAllMessages();
+
+        assertThat(mSubscriptionManagerServiceUT.getSubId(0)).isEqualTo(1);
+        assertThat(mSubscriptionManagerServiceUT.getSlotIndex(1)).isEqualTo(0);
+        assertThat(mSubscriptionManagerServiceUT.getPhoneId(1)).isEqualTo(0);
+
+        mSubscriptionManagerServiceUT.setCarrierId(1, FAKE_CARRIER_ID1);
+        mSubscriptionManagerServiceUT.setDisplayNameUsingSrc(FAKE_CARRIER_NAME1, 1,
+                SubscriptionManager.NAME_SOURCE_SIM_SPN);
+        mSubscriptionManagerServiceUT.setCarrierName(1, FAKE_CARRIER_NAME1);
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
+        assertThat(subInfo.getSimSlotIndex()).isEqualTo(0);
+        assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
+        assertThat(subInfo.getPortIndex()).isEqualTo(0);
+        assertThat(subInfo.isEmbedded()).isFalse();
+        assertThat(subInfo.getCarrierId()).isEqualTo(FAKE_CARRIER_ID1);
+        assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
+        assertThat(subInfo.getDisplayNameSource()).isEqualTo(
+                SubscriptionManager.NAME_SOURCE_SIM_SPN);
+        assertThat(subInfo.getCarrierName()).isEqualTo(FAKE_CARRIER_NAME1);
+        assertThat(subInfo.isOpportunistic()).isFalse();
+        assertThat(subInfo.getNumber()).isEqualTo(FAKE_PHONE_NUMBER1);
+        assertThat(subInfo.getMcc()).isEqualTo(FAKE_MCC1);
+        assertThat(subInfo.getMnc()).isEqualTo(FAKE_MNC1);
+        assertThat(subInfo.getEhplmns()).isEqualTo(FAKE_EHPLMNS1);
+        assertThat(subInfo.getHplmns()).isEqualTo(FAKE_HPLMNS1);
+        assertThat(subInfo.getCardString()).isEqualTo(FAKE_ICCID1);
+        assertThat(subInfo.getCardId()).isEqualTo(1);
+        assertThat(subInfo.getSubscriptionType()).isEqualTo(
+                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
+        assertThat(subInfo.areUiccApplicationsEnabled()).isTrue();
+        assertThat(subInfo.getAllowedNetworkTypesForReasons()).isEqualTo("user="
+                + RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE));
+    }
+
+    @Test
+    public void testGroupDisable() {
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+        insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2)
+                .setGroupUuid(FAKE_UUID1).build());
+
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isGroupDisabled())
+                .isFalse();
+    }
+
+    @Test
+    public void testGetPhoneNumber() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        testSetPhoneNumber();
+        assertThat(mSubscriptionManagerServiceUT.getPhoneNumber(1,
+                SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER, CALLING_PACKAGE, CALLING_FEATURE))
+                .isEqualTo(FAKE_PHONE_NUMBER2);
+        assertThat(mSubscriptionManagerServiceUT.getPhoneNumber(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER, CALLING_PACKAGE, CALLING_FEATURE))
+                .isEmpty();
+    }
+
+    @Test
+    public void testDeleteEsim() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        // pSIM with ICCID2
+        insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2)
+                .setSimSlotIndex(0).build());
+
+        // eSIM with ICCID1
+        EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
+                .setIccid(FAKE_ICCID1)
+                .setNickname(FAKE_CARRIER_NAME1)
+                .setProfileClass(SubscriptionManager.PROFILE_CLASS_OPERATIONAL)
+                .setCarrierIdentifier(new CarrierIdentifier(FAKE_MCC1, FAKE_MNC1, null, null, null,
+                        null, FAKE_CARRIER_ID1, FAKE_CARRIER_ID1))
+                .setUiccAccessRule(Arrays.asList(UiccAccessRule.decodeRules(
+                        FAKE_NATIVE_ACCESS_RULES1)))
+                .build();
+
+        GetEuiccProfileInfoListResult result = new GetEuiccProfileInfoListResult(
+                EuiccService.RESULT_OK, new EuiccProfileInfo[]{profileInfo1}, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        processAllMessages();
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_READY, null, null);
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_LOADED, null, null);
+        processAllMessages();
+
+        // Now we should have two subscriptions in the database. One for pSIM, one for eSIM.
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1).isEmbedded()).isFalse();
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isEmbedded()).isTrue();
+
+        // Delete the eSIM. blockingGetEuiccProfileInfoList will return an empty list.
+        result = new GetEuiccProfileInfoListResult(
+                EuiccService.RESULT_OK, new EuiccProfileInfo[0], false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+        doReturn("").when(mUiccPort).getIccId();
+        doReturn(TelephonyManager.INVALID_PORT_INDEX)
+                .when(mUiccSlot).getPortIndexFromIccId(anyString());
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+
+        processAllMessages();
+
+        // The original pSIM is still pSIM
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1).isEmbedded()).isFalse();
+        // The original eSIM becomes removed pSIM ¯\_(ツ)_/¯
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isEmbedded()).isFalse();
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).getPortIndex())
+                .isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
+    }
+
+    @Test
+    public void testEsimSwitch() {
+        setIdentifierAccess(true);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+
+        EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID2)
+                .setIccid(FAKE_ICCID2)
+                .setNickname(FAKE_CARRIER_NAME2)
+                .setProfileClass(SubscriptionManager.PROFILE_CLASS_OPERATIONAL)
+                .setCarrierIdentifier(new CarrierIdentifier(FAKE_MCC2, FAKE_MNC2, null, null, null,
+                        null, FAKE_CARRIER_ID2, FAKE_CARRIER_ID2))
+                .setUiccAccessRule(Arrays.asList(UiccAccessRule.decodeRules(
+                        FAKE_NATIVE_ACCESS_RULES2)))
+                .build();
+
+        GetEuiccProfileInfoListResult result = new GetEuiccProfileInfoListResult(
+                EuiccService.RESULT_OK, new EuiccProfileInfo[]{profileInfo1}, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+        doReturn(FAKE_ICCID2).when(mUiccCard).getCardId();
+        doReturn(FAKE_ICCID2).when(mUiccController).convertToCardString(eq(1));
+        doReturn(FAKE_ICCID2).when(mUiccPort).getIccId();
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        processAllMessages();
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_READY, null, null);
+        processAllMessages();
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_LOADED, null, null);
+        processAllMessages();
+
+        List<SubscriptionInfo> subInfoList = mSubscriptionManagerServiceUT
+                .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+
+        assertThat(subInfoList).hasSize(1);
+        assertThat(subInfoList.get(0).isActive()).isTrue();
+        assertThat(subInfoList.get(0).getSubscriptionId()).isEqualTo(2);
+        assertThat(subInfoList.get(0).getIccId()).isEqualTo(FAKE_ICCID2);
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getSimSlotIndex()).isEqualTo(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.DEFAULT_PORT_INDEX);
+    }
+
+    @Test
+    public void testDump() {
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+        insertSubscription(FAKE_SUBSCRIPTION_INFO2);
+
+        final StringWriter stringWriter = new StringWriter();
+        assertThrows(SecurityException.class, ()
+                -> mSubscriptionManagerServiceUT.dump(new FileDescriptor(),
+                new PrintWriter(stringWriter), null));
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.DUMP);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        mSubscriptionManagerServiceUT.dump(new FileDescriptor(), new PrintWriter(stringWriter),
+                null);
+        assertThat(stringWriter.toString().length()).isGreaterThan(0);
+    }
+
+    @Test
+    public void testOnSubscriptionChanged() {
+        CountDownLatch latch = new CountDownLatch(1);
+        SubscriptionManagerServiceCallback callback =
+                new SubscriptionManagerServiceCallback(Runnable::run) {
+                    @Override
+                    public void onSubscriptionChanged(int subId) {
+                        latch.countDown();
+                        logd("testOnSubscriptionChanged: onSubscriptionChanged");
+                    }
+                };
+        mSubscriptionManagerServiceUT.registerCallback(callback);
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+        processAllMessages();
+        assertThat(latch.getCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testOnUiccApplicationsEnabled() {
+        CountDownLatch latch = new CountDownLatch(1);
+        Executor executor = Runnable::run;
+        SubscriptionManagerServiceCallback callback =
+                new SubscriptionManagerServiceCallback(executor) {
+                    @Override
+                    public void onUiccApplicationsEnabledChanged(int subId) {
+                        latch.countDown();
+                        logd("testOnSubscriptionChanged: onUiccApplicationsEnabledChanged");
+                    }
+                };
+        assertThat(callback.getExecutor()).isEqualTo(executor);
+        mSubscriptionManagerServiceUT.registerCallback(callback);
+        int subId = insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, subId);
+        processAllMessages();
+        assertThat(latch.getCount()).isEqualTo(0);
+
+        mSubscriptionManagerServiceUT.unregisterCallback(callback);
+        // without override. Nothing should happen.
+        callback = new SubscriptionManagerServiceCallback(Runnable::run);
+        mSubscriptionManagerServiceUT.registerCallback(callback);
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(true, subId);
+        processAllMessages();
+    }
+
+    @Test
+    public void testDeactivatePsim() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        testInsertNewSim();
+
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, 1);
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+
+        processAllMessages();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.isActive()).isFalse();
+        assertThat(subInfo.areUiccApplicationsEnabled()).isFalse();
+    }
+
+    @Test
+    public void testRemoteSim() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+
+        mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS1, FAKE_CARRIER_NAME1,
+                0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
+        processAllMessages();
+
+        verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(1));
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getIccId()).isEqualTo(FAKE_MAC_ADDRESS1);
+        assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
+        assertThat(subInfo.getSimSlotIndex()).isEqualTo(0);
+        assertThat(subInfo.getSubscriptionType()).isEqualTo(
+                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
+
+        assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_MAC_ADDRESS1,
+                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(true);
+        assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+
+        setIdentifierAccess(true);
+        mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS2, FAKE_CARRIER_NAME2,
+                0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isNotEmpty();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isNotEmpty();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE).get(0).getIccId()).isEqualTo(FAKE_MAC_ADDRESS2);
+    }
+
+    @Test
+    public void testRemoveSubscriptionsFromGroup() {
+        testAddSubscriptionsIntoGroup();
+
+        mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        assertThrows(SecurityException.class, ()
+                -> mSubscriptionManagerServiceUT.removeSubscriptionsFromGroup(new int[]{2},
+                ParcelUuid.fromString(GROUP_UUID), CALLING_PACKAGE));
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+
+        assertThrows(IllegalArgumentException.class, ()
+                -> mSubscriptionManagerServiceUT.removeSubscriptionsFromGroup(new int[]{3},
+                ParcelUuid.fromString(GROUP_UUID), CALLING_PACKAGE));
+
+        assertThrows(IllegalArgumentException.class, ()
+                -> mSubscriptionManagerServiceUT.removeSubscriptionsFromGroup(new int[]{2},
+                ParcelUuid.fromString("55911c5b-83ed-419d-8f9b-4e027cf09305"), CALLING_PACKAGE));
+
+        mSubscriptionManagerServiceUT.removeSubscriptionsFromGroup(new int[]{2},
+                ParcelUuid.fromString(GROUP_UUID), CALLING_PACKAGE);
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(2);
+        assertThat(subInfo.getGroupUuid()).isEmpty();
+        assertThat(subInfo.getGroupOwner()).isEmpty();
+    }
+
+    @Test
+    public void testUpdateSimStateForInactivePort() {
+        testSetUiccApplicationsEnabled();
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        mSubscriptionManagerServiceUT.updateSimStateForInactivePort(0, null);
+        processAllMessages();
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.areUiccApplicationsEnabled()).isTrue();
+    }
+
+    @Test
+    public void testInactiveSimInserted() {
+        mContextFixture.putResource(com.android.internal.R.string.default_card_name,
+                FAKE_DEFAULT_CARD_NAME);
+
+        doReturn(0).when(mUiccSlot).getPortIndexFromIccId(eq(FAKE_ICCID1));
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        mSubscriptionManagerServiceUT.updateSimStateForInactivePort(-1, FAKE_ICCID1);
+        processAllMessages();
+
+        // Make sure the inactive SIM's information was inserted.
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
+        assertThat(subInfo.getDisplayName()).isEqualTo("CARD 1");
+        assertThat(subInfo.getPortIndex()).isEqualTo(0);
+    }
+
+    @Test
+    public void testRestoreAllSimSpecificSettingsFromBackup() {
+        assertThrows(SecurityException.class, ()
+                -> mSubscriptionManagerServiceUT.restoreAllSimSpecificSettingsFromBackup(
+                        new byte[0]));
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+
+        // TODO: Briefly copy the logic from TelephonyProvider to
+        //  SubscriptionDatabaseManagerTest.SubscriptionProvider
+        mSubscriptionManagerServiceUT.restoreAllSimSpecificSettingsFromBackup(
+                new byte[0]);
+    }
+
+    @Test
+    public void testSubscriptionMap() {
+        SubscriptionMap<Integer, Integer> map = new SubscriptionMap<>();
+        map.put(1, 1);
+        assertThat(map.get(1)).isEqualTo(1);
+        map.put(0, 2);
+        assertThat(map.get(0)).isEqualTo(2);
+        map.remove(1);
+        assertThat(map.get(1)).isNull();
+        map.clear();
+        assertThat(map).hasSize(0);
+    }
+
+    @Test
+    public void testSimNotReady() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+        processAllMessages();
+
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+    }
+
+    @Test
+    public void testSimNotReadyBySimDeactivate() {
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+        doReturn(true).when(mUiccProfile).isEmptyProfile();
+        processAllMessages();
+
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+    }
+
+    @Test
+    public void testInactiveSimRemoval() {
+        insertSubscription(FAKE_SUBSCRIPTION_INFO2);
+
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        doReturn(FAKE_ICCID2).when(mUiccSlot).getIccId(0);
+        doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
+
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, 1);
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+        processAllMessages();
+
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1)
+                .areUiccApplicationsEnabled()).isFalse();
+        assertThat(mSubscriptionManagerServiceUT.getAvailableSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).hasSize(1);
+
+        // Now remove the SIM
+        doReturn(null).when(mUiccSlot).getIccId(0);
+        doReturn(IccCardStatus.CardState.CARDSTATE_ABSENT).when(mUiccSlot).getCardState();
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_ABSENT, null, null);
+        processAllMessages();
+
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+        // UICC should be re-enabled again for next re-insertion.
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1)
+                .areUiccApplicationsEnabled()).isTrue();
+        assertThat(mSubscriptionManagerServiceUT.getAvailableSubscriptionInfoList(
+                CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+    }
+
+    @Test
+    public void testEmbeddedProfilesUpdateFailed() {
+        insertSubscription(FAKE_SUBSCRIPTION_INFO1);
+
+        GetEuiccProfileInfoListResult result = new GetEuiccProfileInfoListResult(
+                EuiccService.RESULT_MUST_DEACTIVATE_SIM, null, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        processAllMessages();
+
+        // The existing subscription should not be altered if the previous update failed.
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfoInternal(1))
+                .isEqualTo(FAKE_SUBSCRIPTION_INFO1);
+
+        EuiccProfileInfo profileInfo = new EuiccProfileInfo.Builder(FAKE_ICCID2)
+                .setIccid(FAKE_ICCID2)
+                .setNickname(FAKE_CARRIER_NAME2)
+                .setProfileClass(SubscriptionManager.PROFILE_CLASS_OPERATIONAL)
+                .setCarrierIdentifier(new CarrierIdentifier(FAKE_MCC2, FAKE_MNC2, null, null, null,
+                        null, FAKE_CARRIER_ID2, FAKE_CARRIER_ID2))
+                .setUiccAccessRule(Arrays.asList(UiccAccessRule.decodeRules(
+                        FAKE_NATIVE_ACCESS_RULES2)))
+                .build();
+        result = new GetEuiccProfileInfoListResult(EuiccService.RESULT_OK,
+                new EuiccProfileInfo[]{profileInfo}, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+
+        // Update for the 2nd time.
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        processAllMessages();
+
+        // The previous subscription should be marked as non-embedded.
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1).isEmbedded())
+                .isEqualTo(false);
+
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).getIccId())
+                .isEqualTo(FAKE_ICCID2);
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isEmbedded())
+                .isEqualTo(true);
+    }
+
+
+    @Test
+    public void testNonNullSubInfoBuilderFromEmbeddedProfile() {
+        EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
+                .setIccid(FAKE_ICCID1) //can't build profile with null iccid.
+                .setNickname(null) //nullable
+                .setServiceProviderName(null) //nullable
+                .setProfileName(null) //nullable
+                .setCarrierIdentifier(null) //nullable
+                .setUiccAccessRule(null) //nullable
+                .build();
+
+        EuiccProfileInfo profileInfo2 = new EuiccProfileInfo.Builder(FAKE_ICCID2)
+                .setIccid(FAKE_ICCID2) //impossible to build profile with null iccid.
+                .setNickname(null) //nullable
+                .setCarrierIdentifier(new CarrierIdentifier(FAKE_MCC2, FAKE_MNC2, null, null, null,
+                        null, FAKE_CARRIER_ID2, FAKE_CARRIER_ID2)) //not allow null mcc/mnc.
+                .setUiccAccessRule(null) //nullable
+                .build();
+
+        GetEuiccProfileInfoListResult result = new GetEuiccProfileInfoListResult(
+                EuiccService.RESULT_OK, new EuiccProfileInfo[]{profileInfo1}, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+        result = new GetEuiccProfileInfoListResult(EuiccService.RESULT_OK,
+                new EuiccProfileInfo[]{profileInfo2}, false);
+        doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(2));
+        doReturn(TelephonyManager.INVALID_PORT_INDEX).when(mUiccSlot)
+                .getPortIndexFromIccId(anyString());
+
+        mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1, 2), null);
+        processAllMessages();
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
+        assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
+        assertThat(subInfo.getDisplayName()).isEqualTo("");
+        assertThat(subInfo.getDisplayNameSource()).isEqualTo(
+                SubscriptionManager.NAME_SOURCE_UNKNOWN);
+        assertThat(subInfo.getMcc()).isEqualTo("");
+        assertThat(subInfo.getMnc()).isEqualTo("");
+        assertThat(subInfo.isEmbedded()).isTrue();
+        assertThat(subInfo.isRemovableEmbedded()).isFalse();
+        assertThat(subInfo.getNativeAccessRules()).isEqualTo(new byte[]{});
+
+        subInfo = mSubscriptionManagerServiceUT.getSubscriptionInfoInternal(2);
+        assertThat(subInfo.getSubscriptionId()).isEqualTo(2);
+        assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID2);
+        assertThat(subInfo.getDisplayName()).isEqualTo("");
+        assertThat(subInfo.getDisplayNameSource()).isEqualTo(
+                SubscriptionManager.NAME_SOURCE_UNKNOWN);
+        assertThat(subInfo.getMcc()).isEqualTo(FAKE_MCC2);
+        assertThat(subInfo.getMnc()).isEqualTo(FAKE_MNC2);
+        assertThat(subInfo.isEmbedded()).isTrue();
+        assertThat(subInfo.isRemovableEmbedded()).isFalse();
+        assertThat(subInfo.getNativeAccessRules()).isEqualTo(new byte[]{});
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/AdnRecordCacheTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/AdnRecordCacheTest.java
new file mode 100644
index 0000000..c040b9e
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/AdnRecordCacheTest.java
@@ -0,0 +1,340 @@
+/*
+ * 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.uicc;
+
+import static com.android.internal.telephony.uicc.IccConstants.EF_ADN;
+import static com.android.internal.telephony.uicc.IccConstants.EF_MBDN;
+import static com.android.internal.telephony.uicc.IccConstants.EF_PBR;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+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.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.test.TestLooper;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.gsm.UsimPhoneBookManager;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class AdnRecordCacheTest extends TelephonyTest {
+
+    private AdnRecordCacheUT mAdnRecordCache;
+    private TestLooper mTestLooper;
+    private Handler mTestHandler;
+    private IccFileHandler mFhMock;
+    private UsimPhoneBookManager mUsimPhoneBookManager;
+
+    @SuppressWarnings("ClassCanBeStatic")
+    private class AdnRecordCacheUT extends AdnRecordCache {
+        AdnRecordCacheUT(IccFileHandler fh, UsimPhoneBookManager usimPhoneBookManager) {
+            super(fh, usimPhoneBookManager);
+        }
+
+        protected void setAdnLikeWriters(int key, ArrayList<Message> waiters) {
+            super.setAdnLikeWriters(key, waiters);
+        }
+
+        protected void setAdnLikeFiles(int key, ArrayList<AdnRecord> adnRecordList) {
+            super.setAdnLikeFiles(key, adnRecordList);
+        }
+
+        protected void setUserWriteResponse(int key, Message message) {
+            super.setUserWriteResponse(key, message);
+        }
+
+        protected UsimPhoneBookManager getUsimPhoneBookManager() {
+            return super.getUsimPhoneBookManager();
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        // Mocked classes
+        mFhMock = mock(IccFileHandler.class);
+        mUsimPhoneBookManager = mock(UsimPhoneBookManager.class);
+        mTestLooper = new TestLooper();
+        mTestHandler = new Handler(mTestLooper.getLooper());
+        mTestHandler.post(
+                () -> mAdnRecordCache = new AdnRecordCacheUT(mFhMock, mUsimPhoneBookManager));
+        mTestLooper.dispatchAll();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestLooper != null) {
+            mTestLooper.dispatchAll();
+            mTestLooper = null;
+        }
+        mTestHandler.removeCallbacksAndMessages(null);
+        mTestHandler = null;
+        mAdnRecordCache = null;
+        super.tearDown();
+    }
+
+    @Test
+    public void resetTest() {
+        Message message1 = Message.obtain(mTestHandler);
+        Message message2 = Message.obtain(mTestHandler);
+
+        // test data to create mAdnLikeWaiters
+        ArrayList<Message> waiters = new ArrayList<>();
+        waiters.add(message1);
+        mAdnRecordCache.setAdnLikeWriters(EF_MBDN, waiters);
+
+        // test data to create mAdnLikeFiles
+        setAdnLikeFiles(EF_MBDN);
+
+        // test data to create mUserWriteResponse
+        mAdnRecordCache.setUserWriteResponse(EF_MBDN, message2);
+
+        mAdnRecordCache.reset();
+
+        mTestLooper.dispatchAll();
+        AsyncResult ar1 = (AsyncResult) message1.obj;
+        AsyncResult ar2 = (AsyncResult) message2.obj;
+        Assert.assertTrue(ar1.exception.toString().contains("AdnCache reset"));
+        Assert.assertTrue(ar2.exception.toString().contains("AdnCace reset"));
+    }
+
+    @Test
+    public void updateAdnByIndexEfException() {
+        int efId = 0x6FC5;
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.updateAdnByIndex(efId, null, 0, null, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains("EF is not known ADN-like EF:0x6FC5")));
+    }
+
+    @Test
+    public void updateAdnByIndex_WriteResponseException() {
+        int efId = EF_MBDN;
+        Message message = Message.obtain(mTestHandler);
+        Message message2 = Message.obtain(mTestHandler);
+        AdnRecord adnRecord = new AdnRecord("AlphaTag", "123456789");
+        // test data to create mUserWriteResponse
+        mAdnRecordCache.setUserWriteResponse(efId, message2);
+        mAdnRecordCache.updateAdnByIndex(efId, adnRecord, 0, null, message);
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains("Have pending update for EF:0x6FC7")));
+    }
+
+    @Test
+    public void updateAdnByIndex() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(2);
+                    AsyncResult.forMessage(response, "success2", null);
+                    response.sendToTarget();
+                    return response;
+                })
+                .when(mFhMock)
+                .getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        Assert.assertNotNull(message);
+        AdnRecord adnRecord = new AdnRecord("AlphaTag", "123456789");
+        // test data to create mUserWriteResponse
+        mAdnRecordCache.updateAdnByIndex(EF_MBDN, adnRecord, 0, null, message);
+        mTestLooper.startAutoDispatch();
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void updateAdnBySearch_EfException() {
+        int efId = 0x6FC5;
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.updateAdnBySearch(efId, null, null, null, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains("EF is not known ADN-like EF:0x6FC5")));
+    }
+
+    @Test
+    public void updateAdnBySearch_Exception() {
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.updateAdnBySearch(EF_MBDN, null, null, null, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains("Adn list not exist for EF:0x6FC7")));
+    }
+
+    @Test
+    public void updateAdnBySearch_AdnListError() {
+        int efId = EF_MBDN;
+        setAdnLikeFiles(efId);
+        Message message = Message.obtain(mTestHandler);
+        AdnRecord oldAdn = new AdnRecord("oldAlphaTag", "123456789");
+        mAdnRecordCache.updateAdnBySearch(efId, oldAdn, null, null, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains(
+                "Adn record don't exist for ADN Record 'oldAlphaTag'")));
+    }
+
+    @Test
+    public void updateAdnBySearch_PendingUpdate() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(2);
+                    AsyncResult.forMessage(response, "success2", null);
+                    response.sendToTarget();
+                    return response;
+                })
+                .when(mFhMock)
+                .getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        int efId = EF_MBDN;
+        setAdnLikeFiles(efId);
+        Message message = Message.obtain(mTestHandler);
+        AdnRecord oldAdn = new AdnRecord("AlphaTag", "123456789");
+        mAdnRecordCache.updateAdnBySearch(efId, oldAdn, null, null, message);
+        mTestLooper.dispatchAll();
+
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void updateAdnBySearch() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(2);
+                    AsyncResult.forMessage(response, "success", null);
+                    response.sendToTarget();
+                    return response;
+                })
+                .when(mFhMock)
+                .getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        int efId = EF_MBDN;
+        setAdnLikeFiles(efId);
+        Message message = Message.obtain(mTestHandler);
+        AdnRecord oldAdn = new AdnRecord("AlphaTag", "123456789");
+        mAdnRecordCache.updateAdnBySearch(efId, oldAdn, null, null, message);
+        mTestLooper.dispatchAll();
+
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+    }
+
+
+    @Test
+    public void updateAdnBySearch_AdnException() {
+        doReturn(null).when(mUsimPhoneBookManager).loadEfFilesFromUsim();
+        Message message = Message.obtain(mTestHandler);
+        AdnRecord oldAdn = new AdnRecord("oldAlphaTag", "123456789");
+        mAdnRecordCache.updateAdnBySearch(EF_PBR, oldAdn, null, null, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNotNull(ar.exception);
+        assertTrue((ar.exception.toString().contains("Adn list not exist for EF:0x4F30")));
+    }
+
+    @Test
+    public void requestLoadAllAdnLike_AlreadyLoadedEf() {
+        int efId = EF_MBDN;
+        setAdnLikeFiles(efId);
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.requestLoadAllAdnLike(efId, 0, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNull(ar.exception);
+        Assert.assertNotNull(ar.result);
+    }
+
+    @Test
+    public void requestLoadAllAdnLike_AlreadyLoadingEf() {
+        int efId = EF_MBDN;
+        // test data to create mAdnLikeWaiters
+        Message message = Message.obtain(mTestHandler);
+        ArrayList<Message> waiters = new ArrayList<>();
+        waiters.add(message);
+        mAdnRecordCache.setAdnLikeWriters(efId, waiters);
+        mAdnRecordCache.requestLoadAllAdnLike(efId, 0, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertNull(ar);
+    }
+
+    @Test
+    public void requestLoadAllAdnLike_NotKnownEf() {
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.requestLoadAllAdnLike(EF_MBDN, -1, message);
+        mTestLooper.dispatchAll();
+
+        AsyncResult ar = (AsyncResult) message.obj;
+        Assert.assertTrue(ar.exception.toString().contains("EF is not known ADN-like EF:0x"));
+    }
+
+    @Test
+    public void requestLoadAllAdnLike() {
+                doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(2);
+                    AsyncResult.forMessage(response, null, new CommandException(
+                            CommandException.Error.REQUEST_NOT_SUPPORTED));
+                    response.sendToTarget();
+                    return response;
+                })
+                .when(mFhMock)
+                .loadEFLinearFixedAll(anyInt(), anyString(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mAdnRecordCache.requestLoadAllAdnLike(EF_ADN, 0x6FC8, message);
+        mTestLooper.dispatchAll();
+
+        verify(mFhMock, times(1)).loadEFLinearFixedAll(anyInt(), anyString(), any(Message.class));
+    }
+
+    private void setAdnLikeFiles(int ef) {
+        // test data to create mAdnLikeFiles
+        ArrayList<AdnRecord> adnRecordList = new ArrayList<>();
+        AdnRecord adnRecord = new AdnRecord("AlphaTag", "123456789");
+        adnRecordList.add(adnRecord);
+        mAdnRecordCache.setAdnLikeFiles(ef, adnRecordList);
+    }
+}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccFileHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccFileHandlerTest.java
new file mode 100644
index 0000000..63e68e2
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccFileHandlerTest.java
@@ -0,0 +1,537 @@
+/*
+ * 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.uicc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+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.os.test.TestLooper;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+
+public class IccFileHandlerTest {
+    CommandsInterface mCi;
+    IccFileHandler mIccFileHandler;
+    private TestLooper mTestLooper;
+    private Handler mTestHandler;
+
+    @Before
+    public void setUp() throws Exception {
+        mCi = mock(CommandsInterface.class);
+        mTestLooper = new TestLooper();
+        mTestHandler = new Handler(mTestLooper.getLooper());
+        mTestHandler.post(
+                () -> mIccFileHandler = new IccFileHandler(mCi) {
+                    @Override
+                    protected String getEFPath(int efid) {
+                        switch (efid) {
+                            case 0x4f30:
+                            case 0x4f3a:
+                                return "3F007F105F3A";
+                        }
+                        return "";
+                    }
+
+                    @Override
+                    protected void logd(String s) {
+                        Log.d("IccFileHandlerTest", s);
+                    }
+
+                    @Override
+                    protected void loge(String s) {
+                        Log.d("IccFileHandlerTest", s);
+                    }
+                });
+
+
+        mTestLooper.dispatchAll();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestLooper != null) {
+            mTestLooper.dispatchAll();
+            mTestLooper = null;
+        }
+        mTestHandler.removeCallbacksAndMessages(null);
+        mTestHandler = null;
+        mIccFileHandler = null;
+        mCi = null;
+    }
+
+    @Test
+    public void loadEFLinearFixed_WithNullPath() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixed(0, "", 0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFLinearFixed() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixed(0, 0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFImgLinearFixed() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFImgLinearFixed(0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void getEFLinearRecordSize_WithNullPath() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.getEFLinearRecordSize(0, "", message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void getEFLinearRecordSize() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.getEFLinearRecordSize(0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void getEFTransparentRecordSize() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.getEFTransparentRecordSize(0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_FileNotFoundAtGetRecord() throws InterruptedException {
+        int efId = 0x4f30;
+        final CountDownLatch latch = new CountDownLatch(1);
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    IccIoResult iir = new IccIoResult(0x94, 0x00,
+                            IccUtils.hexStringToBytes(null));
+                    AsyncResult.forMessage(response, iir, null);
+                    mTestHandler.postDelayed(latch::countDown, 100);
+                    response.sendToTarget();
+                    return null;
+                }).when(mCi).iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(),
+                anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(efId, null, message);
+        mTestLooper.startAutoDispatch();
+        latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertNotNull(ar);
+        assertTrue(ar.exception instanceof IccFileNotFound);
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_FileNotFoundAtReadRecord() throws InterruptedException {
+        int efid = 0x4f30;
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    IccIoResult iir = null;
+                    if (response.what == 6) {
+                        iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(
+                                "000000454F30040000FFFF01020145"));
+                        latch.countDown();
+                    } else if (response.what == 7) {
+                        iir = new IccIoResult(0x94, 0x00, IccUtils.hexStringToBytes(null));
+                        mTestHandler.postDelayed(latch::countDown, 100);
+                    }
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                }).when(mCi).iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(),
+                anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(efid, null, message);
+        mTestLooper.startAutoDispatch();
+        latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertNotNull(ar);
+        assertTrue(ar.exception instanceof IccFileNotFound);
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_ExceptionAtGetRecord() throws InterruptedException {
+        int efid = 0x4f30;
+        final CountDownLatch latch = new CountDownLatch(1);
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, null, new CommandException(
+                            CommandException.Error.OPERATION_NOT_ALLOWED));
+                    response.sendToTarget();
+                    mTestHandler.postDelayed(latch::countDown, 100);
+                    return null;
+                }).when(mCi).iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(),
+                anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(efid, null, message);
+        mTestLooper.startAutoDispatch();
+        latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertSame(CommandException.Error.OPERATION_NOT_ALLOWED,
+                ((CommandException) ar.exception).getCommandError());
+        assertNull(ar.result);
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_ExceptionAtReadRecord() throws InterruptedException {
+        int efid = 0x4f30;
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    String hexString = null;
+                    IccIoResult iir = null;
+                    if (response.what == 6) {
+                        hexString = "000000454F30040000FFFF01020145";
+                        iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
+                        AsyncResult.forMessage(response, iir, null);
+                        latch.countDown();
+                    } else if (response.what == 7) {
+                        AsyncResult.forMessage(response, null, new CommandException(
+                                CommandException.Error.OPERATION_NOT_ALLOWED));
+                        mTestHandler.postDelayed(latch::countDown, 100);
+                    }
+                    response.sendToTarget();
+                    mTestHandler.postDelayed(latch::countDown, 100);
+                    return null;
+                }).when(mCi).iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(),
+                anyInt(),
+                isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(efid, null, message);
+        mTestLooper.startAutoDispatch();
+        latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertSame(CommandException.Error.OPERATION_NOT_ALLOWED,
+                ((CommandException) ar.exception).getCommandError());
+        assertNull(ar.result);
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_FullLoop() throws InterruptedException {
+        int efid = 0x4f30;
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    String hexString = null;
+                    if (response.what == 6) {
+                        hexString = "000000454F30040000FFFF01020145";
+                        latch.countDown();
+                    } else if (response.what == 7) {
+                        try {
+                            IccFileHandler.LoadLinearFixedContext lc =
+                                    (IccFileHandler.LoadLinearFixedContext) response.obj;
+                            if (mIccFileHandler.getEfid(lc) == efid) {
+                                hexString =
+                                        "A814C0034F3A01C1034F3202C5034F0904C9034F2109A90FC3034F611"
+                                                + "5C4034F1108CA034F5017AA0FC2034F4A03C7034F4B06CB"
+                                                + "034F4F16FFFFFFFFFFFFFFFFFFFFFFFFFF";
+                            }
+                            mTestHandler.postDelayed(latch::countDown, 100);
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            Log.e("UsimFH", e.getMessage());
+                        }
+
+                    }
+                    IccIoResult iir = new IccIoResult(0x90, 0x00,
+                            IccUtils.hexStringToBytes(hexString));
+                    AsyncResult.forMessage(response, iir, null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(efid, null, message);
+        mTestLooper.startAutoDispatch();
+        latch.await(5, java.util.concurrent.TimeUnit.SECONDS);
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertNotNull(ar);
+        ArrayList<byte[]> results = (ArrayList<byte[]>) ar.result;
+        assertEquals(
+                "A814C0034F3A01C1034F3202C5034F0904C9034F2109A90FC3034F6115C4034F1108CA03"
+                        + "4F5017AA0FC2034F4A03C7034F4B06CB034F4F16FFFFFFFFFFFFFFFFFFFFFFFFFF",
+                IccUtils.bytesToHexString(results.get(0)));
+        verify(mCi, times(2)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFLinearFixedAll_WithNullPath() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(0, "", message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFLinearFixedAll() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFLinearFixedAll(0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFTransparent() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFTransparent(0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFTransparent_WithZeroSize() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFTransparent(0, 0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void loadEFImgTransparent() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        isNull(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.loadEFImgTransparent(0, 0, 0, 0, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), isNull(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void updateEFLinearFixed_WithNullPath() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        anyString(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.updateEFLinearFixed(0, "", 0, new byte[10], null, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), anyString(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void updateEFLinearFixed() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        anyString(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.updateEFLinearFixed(0, 0, new byte[10], null, message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), anyString(), isNull(), isNull(), any(Message.class));
+    }
+
+    @Test
+    public void updateEFTransparent() {
+        doAnswer(
+                invocation -> {
+                    Message response = invocation.getArgument(9);
+                    AsyncResult.forMessage(response, "Success", null);
+                    response.sendToTarget();
+                    return null;
+                })
+                .when(mCi)
+                .iccIOForApp(anyInt(), anyInt(), anyString(), anyInt(), anyInt(), anyInt(),
+                        anyString(), isNull(), isNull(), any(Message.class));
+
+        Message message = Message.obtain(mTestHandler);
+        mIccFileHandler.updateEFTransparent(0, new byte[10], message);
+        verify(mCi, times(1)).iccIOForApp(anyInt(), anyInt(), anyString(),
+                anyInt(), anyInt(), anyInt(), anyString(), isNull(), isNull(), any(Message.class));
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccIoResultTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccIoResultTest.java
new file mode 100644
index 0000000..b3e0a85
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccIoResultTest.java
@@ -0,0 +1,452 @@
+/*
+ * 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.uicc;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class IccIoResultTest {
+
+    @Test
+    public void check0x90_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x90, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(resultStr != null && (!resultStr.contains("Error")));
+    }
+
+    @Test
+    public void check0x91_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x91, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(resultStr != null && (!resultStr.contains("Error")));
+    }
+
+    @Test
+    public void check0x9E_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x9E, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(resultStr != null && (!resultStr.contains("Error")));
+    }
+
+    @Test
+    public void check0x9F_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x9F, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(resultStr != null && (!resultStr.contains("Error")));
+    }
+
+    @Test
+    public void check0x94_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x94, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(resultStr != null && (resultStr.contains("no EF selected")));
+
+        iccIoResult = new IccIoResult(0x94, 0x02, new byte[10]);
+        resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("out f range (invalid address)")));
+
+        iccIoResult = new IccIoResult(0x94, 0x04, new byte[10]);
+        resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("file ID not found/pattern not found")));
+
+        iccIoResult = new IccIoResult(0x94, 0x08, new byte[10]);
+        resultStr = iccIoResult.toString();
+
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("file is inconsistent with the command")));
+    }
+
+    @Test
+    public void check0x98_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x98, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x98, 0x02, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("no CHV initialized")));
+
+        iccIoResult = new IccIoResult(0x98, 0x04, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("access condition not fulfilled")));
+
+        iccIoResult = new IccIoResult(0x98, 0x08, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("in contradiction with CHV status")));
+
+        iccIoResult = new IccIoResult(0x98, 0x10, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "in contradiction with invalidation status")));
+
+        iccIoResult = new IccIoResult(0x98, 0x40, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "unsuccessful CHV verification, no attempt left")));
+
+        iccIoResult = new IccIoResult(0x98, 0x50, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "increase cannot be performed, Max value reached")));
+
+        iccIoResult = new IccIoResult(0x98, 0x62, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "authentication error, application specific")));
+
+        iccIoResult = new IccIoResult(0x98, 0x64, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "authentication error, security context not supported")));
+
+        iccIoResult = new IccIoResult(0x98, 0x65, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("key freshness failure")));
+
+        iccIoResult = new IccIoResult(0x98, 0x66, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "authentication error, no memory space available")));
+
+        iccIoResult = new IccIoResult(0x98, 0x67, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "authentication error, no memory space available in EF_MUK")));
+    }
+
+    @Test
+    public void check0x61_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x61, 0x20, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("more response bytes available")));
+    }
+
+    @Test
+    public void check0x62_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x62, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("no information given")));
+
+        iccIoResult = new IccIoResult(0x62, 0x81, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains(
+                        "part of returned data may be corrupted")));
+
+        iccIoResult = new IccIoResult(0x62, 0x82, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "end of file/record reached before reading Le bytes")));
+
+        iccIoResult = new IccIoResult(0x62, 0x83, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("selected file invalidated")));
+
+        iccIoResult = new IccIoResult(0x62, 0x84, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("selected file in termination state")));
+
+        iccIoResult = new IccIoResult(0x62, 0xF1, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("more data available")));
+
+        iccIoResult = new IccIoResult(0x62, 0xF2, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "more data available and proactive command pending")));
+
+        iccIoResult = new IccIoResult(0x62, 0xF3, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("response data available")));
+
+        iccIoResult = new IccIoResult(0x62, 0xF4, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+    }
+
+    @Test
+    public void check0x63_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x63, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains(
+                        "command successful but after using an internal update retry routine 0 "
+                                + "times")));
+
+        iccIoResult = new IccIoResult(0x63, 0xF1, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("more data expected")));
+
+        iccIoResult = new IccIoResult(0x63, 0xF2, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains(
+                        "more data expected and proactive command pending")));
+
+        iccIoResult = new IccIoResult(0x63, 0xF3, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("unknown")));
+    }
+
+    @Test
+    public void check0x64_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x64, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x64, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("no information given")));
+    }
+
+    @Test
+    public void check0x65_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x65, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x65, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue((resultStr != null) && (resultStr.contains(
+                "no information given, state of non-volatile memory changed")));
+
+        iccIoResult = new IccIoResult(0x65, 0x81, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("memory problem")));
+    }
+
+    @Test
+    public void check0x67_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x67, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "the interpretation of this status word is command dependent")));
+
+        iccIoResult = new IccIoResult(0x67, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "incorrect parameter P3")));
+    }
+
+    @Test
+    public void check0x68_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x68, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x68, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("no information given")));
+
+        iccIoResult = new IccIoResult(0x68, 0x81, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("logical channel not supported")));
+
+        iccIoResult = new IccIoResult(0x68, 0x82, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("secure messaging not supported")));
+    }
+
+    @Test
+    public void check0x69_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x69, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x69, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("no information given")));
+
+        iccIoResult = new IccIoResult(0x69, 0x81, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains(
+                        "command incompatible with file structure")));
+
+        iccIoResult = new IccIoResult(0x69, 0x82, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("security status not satisfied")));
+
+        iccIoResult = new IccIoResult(0x69, 0x83, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("authentication/PIN method blocked")));
+
+        iccIoResult = new IccIoResult(0x69, 0x84, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("referenced data invalidated")));
+
+        iccIoResult = new IccIoResult(0x69, 0x85, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("conditions of use not satisfied")));
+
+        iccIoResult = new IccIoResult(0x69, 0x86, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue((resultStr != null) && (resultStr.contains(
+                "command not allowed (no EF selected)")));
+
+        iccIoResult = new IccIoResult(0x69, 0x89, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue((resultStr != null) && (resultStr.contains(
+                "command not allowed - secure channel - security not satisfied")));
+    }
+
+    @Test
+    public void check0x6A_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6A, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("unknown")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x80, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "incorrect parameters in the data field")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x81, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("function not supported")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x82, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("file not found")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x83, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("record not found")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x84, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("not enough memory space")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x86, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                (resultStr != null) && (resultStr.contains("incorrect parameters P1 to P2")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x87, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue((resultStr != null) && (resultStr.contains(
+                "lc inconsistent with P1 to P2")));
+
+        iccIoResult = new IccIoResult(0x6A, 0x88, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue((resultStr != null) && (resultStr.contains(
+                "referenced data not found")));
+    }
+
+    @Test
+    public void check0x6B_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6B, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(
+                resultStr != null && (resultStr.contains("incorrect parameter P1 or P2")));
+    }
+
+    @Test
+    public void check0x6C_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6C, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains("wrong length, retry with ")));
+    }
+
+    @Test
+    public void check0x6D_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6D, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "unknown instruction code given in the command")));
+    }
+
+    @Test
+    public void check0x6E_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6E, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "wrong instruction class given in the command")));
+    }
+
+    @Test
+    public void check0x6F_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x6F, 0xC0, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "the interpretation of this status word is command dependent")));
+
+        iccIoResult = new IccIoResult(0x6F, 0x00, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "technical problem with no diagnostic given")));
+    }
+
+    @Test
+    public void check0x92_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x92, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "command successful but after using an internal update retry routine")));
+
+        iccIoResult = new IccIoResult(0x92, 0x40, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "memory problem")));
+
+        iccIoResult = new IccIoResult(0x92, 0x41, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "unknown")));
+    }
+
+    @Test
+    public void check0x93_ErrorCodeParsing() {
+        IccIoResult iccIoResult = new IccIoResult(0x93, 0x00, new byte[10]);
+        String resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "SIM Application Toolkit is busy. Command cannot be executed"
+                        + " at present, further normal commands are allowed")));
+
+        iccIoResult = new IccIoResult(0x93, 0x41, new byte[10]);
+        resultStr = iccIoResult.toString();
+        Assert.assertTrue(resultStr != null && (resultStr.contains(
+                "unknown")));
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
old mode 100755
new mode 100644
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 8324a5b..6f4666c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java
@@ -303,4 +303,77 @@
         assertTrue(((CommandException) ar.exception).getCommandError() ==
                 CommandException.Error.OPERATION_NOT_ALLOWED);
     }
-}
+
+    @Test
+    public void testGetSimServiceTable() {
+        // reading sim service table successfully case
+        byte[] sst = new byte[9];
+        for (int i = 0; i < sst.length; i++) {
+            if (i % 2 == 0) {
+                sst[i] = 0;
+            } else {
+                sst[i] = 1;
+            }
+        }
+        Message message = mIsimUiccRecordsUT.obtainMessage(
+                IccRecords.EVENT_GET_ICC_RECORD_DONE, mIsimUiccRecordsUT.getIsimIstObject());
+        AsyncResult ar = AsyncResult.forMessage(message, sst, null);
+        mIsimUiccRecordsUT.handleMessage(message);
+        String mockSst = IccUtils.bytesToHexString(sst);
+        String resultSst = mIsimUiccRecordsUT.getIsimIst();
+        assertEquals(mockSst, resultSst);
+    }
+
+    @Test
+    public void testGetSimServiceTableException() {
+        // sim service table exception handling case
+        Message message = mIsimUiccRecordsUT.obtainMessage(
+                IccRecords.EVENT_GET_ICC_RECORD_DONE, mIsimUiccRecordsUT.getIsimIstObject());
+        AsyncResult ar = AsyncResult.forMessage(message,  null, new CommandException(
+                CommandException.Error.OPERATION_NOT_ALLOWED));
+        mIsimUiccRecordsUT.handleMessage(message);
+        String resultSst = mIsimUiccRecordsUT.getIsimIst();
+        assertEquals(null, resultSst);
+    }
+
+    @Test
+    public void testGetSsimServiceTableLessTableSize() {
+        // The less IST table size will not give any problem
+        byte[] sst = new byte[5];
+        for (int i = 0; i < sst.length; i++) {
+            if (i % 2 == 0) {
+                sst[i] = 0;
+            } else {
+                sst[i] = 1;
+            }
+        }
+        Message message = mIsimUiccRecordsUT.obtainMessage(
+                IccRecords.EVENT_GET_ICC_RECORD_DONE, mIsimUiccRecordsUT.getIsimIstObject());
+        AsyncResult ar = AsyncResult.forMessage(message, sst, null);
+        mIsimUiccRecordsUT.handleMessage(message);
+        String mockSst = IccUtils.bytesToHexString(sst);
+        String resultSst = mIsimUiccRecordsUT.getIsimIst();
+        assertEquals(mockSst, resultSst);
+    }
+
+    @Test
+    public void testGetSsimServiceTableLargeTableSize() {
+        // The Big IST table size will not give any problem [ in feature the table may grows]
+        byte[] sst = new byte[99];
+        for (int i = 0; i < sst.length; i++) {
+            if (i % 2 == 0) {
+                sst[i] = 0;
+            } else {
+                sst[i] = 1;
+            }
+        }
+        Message message = mIsimUiccRecordsUT.obtainMessage(
+                IccRecords.EVENT_GET_ICC_RECORD_DONE, mIsimUiccRecordsUT.getIsimIstObject());
+        AsyncResult ar = AsyncResult.forMessage(message, sst, null);
+        mIsimUiccRecordsUT.handleMessage(message);
+        String mockSst = IccUtils.bytesToHexString(sst);
+        String resultSst = mIsimUiccRecordsUT.getIsimIst();
+        assertEquals(mockSst, resultSst);
+    }
+
+}
\ No newline at end of file
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..ea6c778 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
@@ -19,8 +19,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
@@ -29,6 +32,7 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -44,6 +48,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -58,19 +64,38 @@
     private int mBootCount;
     private int mSimulatedRebootsCount;
     private PinStorage mPinStorage;
+    private PersistableBundle mBundle;
+
+    // mocks
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private void simulateReboot() {
         mSimulatedRebootsCount++;
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.BOOT_COUNT, mBootCount + mSimulatedRebootsCount);
 
+        createPinStorageAndCaptureListener();
+    }
+
+    private void createPinStorageAndCaptureListener() {
+        // Capture listener to emulate the carrier config change notification used later
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mPinStorage = new PinStorage(mContext);
         mPinStorage.mShortTermSecretKeyDurationMinutes = 0;
+        verify(mCarrierConfigManager, atLeastOnce()).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
     }
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
+        mCarrierConfigChangeListener = Mockito.mock(
+                CarrierConfigManager.CarrierConfigChangeListener.class);
+
+        mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
 
         // Store boot count, so that correct value can be restored at the end.
         mBootCount = Settings.Global.getInt(
@@ -89,8 +114,7 @@
         when(mKeyguardManager.isDeviceSecure()).thenReturn(false);
         when(mKeyguardManager.isDeviceLocked()).thenReturn(false);
 
-        mPinStorage = new PinStorage(mContext);
-        mPinStorage.mShortTermSecretKeyDurationMinutes = 0;
+        createPinStorageAndCaptureListener();
     }
 
     @After
@@ -341,7 +365,7 @@
         PersistableBundle carrierConfigs = new PersistableBundle();
         carrierConfigs.putBoolean(
                 CarrierConfigManager.KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, false);
-        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(carrierConfigs);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(carrierConfigs);
 
         mPinStorage.storePin("1234", 0);
 
@@ -362,10 +386,10 @@
         PersistableBundle carrierConfigs = new PersistableBundle();
         carrierConfigs.putBoolean(
                 CarrierConfigManager.KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, false);
-        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(carrierConfigs);
-        final Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
-        mContext.sendBroadcast(intent);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(carrierConfigs);
+        mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/PortUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/PortUtilsTest.java
new file mode 100644
index 0000000..69d9a7d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/PortUtilsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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 org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+
+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 PortUtilsTest extends TelephonyTest {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        doReturn(IccSlotStatus.MultipleEnabledProfilesMode.NONE)
+                .when(mUiccController).getSupportedMepMode(anyInt());
+        processAllMessages();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testConvertToHalPortIndex() {
+        assertEquals(0, PortUtils.convertToHalPortIndex(0, 0));
+        doReturn(IccSlotStatus.MultipleEnabledProfilesMode.MEP_A1)
+                .when(mUiccController).getSupportedMepMode(anyInt());
+        assertEquals(1, PortUtils.convertToHalPortIndex(0, 0));
+    }
+
+    @Test
+    public void testConvertFromHalPortIndex() {
+        assertEquals(0, PortUtils.convertFromHalPortIndex(0, 1,
+                IccCardStatus.CardState.CARDSTATE_PRESENT,
+                IccSlotStatus.MultipleEnabledProfilesMode.MEP_A1));
+        assertEquals(1, PortUtils.convertFromHalPortIndex(0, 1,
+                IccCardStatus.CardState.CARDSTATE_PRESENT,
+                IccSlotStatus.MultipleEnabledProfilesMode.MEP_B));
+        assertEquals(1, PortUtils.convertFromHalPortIndex(0, 1,
+                IccCardStatus.CardState.CARDSTATE_ABSENT,
+                IccSlotStatus.MultipleEnabledProfilesMode.MEP_A1));
+        doReturn(IccSlotStatus.MultipleEnabledProfilesMode.MEP_A1)
+                .when(mUiccController).getSupportedMepMode(anyInt());
+        assertEquals(0, PortUtils.convertFromHalPortIndex(0, 1,
+                IccCardStatus.CardState.CARDSTATE_ABSENT,
+                IccSlotStatus.MultipleEnabledProfilesMode.NONE));
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java
old mode 100755
new mode 100644
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 3d6f770..e109ebb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java
@@ -22,9 +22,11 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
@@ -32,6 +34,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.test.TestLooper;
+import android.util.Log;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -41,6 +44,7 @@
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.uicc.IccRecords.OperatorPlmnInfo;
 import com.android.internal.telephony.uicc.IccRecords.PlmnNetworkName;
+import com.android.telephony.Rlog;
 
 import org.junit.After;
 import org.junit.Before;
@@ -50,6 +54,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
 public class SIMRecordsTest extends TelephonyTest {
@@ -59,6 +66,7 @@
     private static final List<String> EMPTY_FPLMN_LIST = new ArrayList<>();
     private static final int EF_SIZE = 12;
     private static final int MAX_NUM_FPLMN = 4;
+    private static final int SET_VOICE_MAIL_TIMEOUT = 1000;
 
     // Mocked classes
     private IccFileHandler mFhMock;
@@ -597,7 +605,6 @@
         data[5] = (byte) (lacTacEnd >>> 8);
         data[6] = (byte) lacTacEnd;
         data[7] = (byte) pnnIndex;
-
         return data;
     }
 
@@ -668,4 +675,300 @@
         assertEquals(null, mSIMRecordsUT.getSmscIdentity());
         assertTrue(ar.exception instanceof CommandException);
     }
+
+    @Test
+    public void testGetSimServiceTable() {
+        // reading sim service table successfully case
+        byte[] sst = new byte[111];
+        for (int i = 0; i < sst.length; i++) {
+            if (i % 2 == 0) {
+                sst[i] = 0;
+            } else {
+                sst[i] = 1;
+            }
+        }
+        Message message = mSIMRecordsUT.obtainMessage(SIMRecords.EVENT_GET_SST_DONE);
+        AsyncResult ar = AsyncResult.forMessage(message, sst, null);
+        mSIMRecordsUT.handleMessage(message);
+        String mockSst = IccUtils.bytesToHexString(sst);
+        String resultSst = mSIMRecordsUT.getSimServiceTable();
+        assertEquals(mockSst, resultSst);
+    }
+
+    @Test
+    public void testGetSimServiceTableException() {
+        // sim service table exception handling case
+        Message message = mSIMRecordsUT.obtainMessage(SIMRecords.EVENT_GET_SST_DONE);
+        AsyncResult ar = AsyncResult.forMessage(message, null, new CommandException(
+                CommandException.Error.OPERATION_NOT_ALLOWED));
+        mSIMRecordsUT.handleMessage(message);
+        String resultSst = mSIMRecordsUT.getSimServiceTable();
+        assertEquals(null, resultSst);
+    }
+
+    @Test
+    public void testGetSsimServiceTableLessTableSize() {
+        // sim service table reading case
+        byte[] sst = new byte[12];
+        for (int i = 0; i < sst.length; i++) {
+            if (i % 2 == 0) {
+                sst[i] = 0;
+            } else {
+                sst[i] = 1;
+            }
+        }
+        Message message = mSIMRecordsUT.obtainMessage(SIMRecords.EVENT_GET_SST_DONE);
+        AsyncResult ar = AsyncResult.forMessage(message, sst, null);
+        mSIMRecordsUT.handleMessage(message);
+        String mockSst = IccUtils.bytesToHexString(sst);
+        String resultSst = mSIMRecordsUT.getSimServiceTable();
+        assertEquals(mockSst, resultSst);
+    }
+
+    @Test
+    public void testSetVoiceMailNumber() throws InterruptedException {
+        String voiceMailNumber = "1234567890";
+        String alphaTag = "Voicemail";
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the first invocation");
+            Message response = invocation.getArgument(2);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the second invocation");
+            Message response = invocation.getArgument(5);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).updateEFLinearFixed(anyInt(), eq(null), anyInt(), any(byte[].class),
+                eq(null), any(Message.class));
+
+        mSIMRecordsUT.setMailboxIndex(1);
+        Message message = Message.obtain(mTestHandler);
+        mSIMRecordsUT.setVoiceMailNumber(alphaTag, voiceMailNumber, message);
+        latch.await(5, TimeUnit.SECONDS);
+        mTestLooper.startAutoDispatch();
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+        verify(mFhMock, times(1)).updateEFLinearFixed(anyInt(), eq(null), anyInt(),
+                any(byte[].class), eq(null), any(Message.class));
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return true;
+            }
+
+            @Override
+            public Object actual() {
+                return mSIMRecordsUT.getVoiceMailNumber() != null;
+            }
+        });
+        assertEquals(voiceMailNumber, mSIMRecordsUT.getVoiceMailNumber());
+        assertEquals(alphaTag, mSIMRecordsUT.getVoiceMailAlphaTag());
+    }
+
+    @Test
+    public void testSetVoiceMailNumberBigAlphatag() throws InterruptedException {
+        String voiceMailNumber = "1234567890";
+        String alphaTag = "VoicemailAlphaTag-VoicemailAlphaTag";
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the first invocation");
+            Message response = invocation.getArgument(2);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the second invocation");
+            Message response = invocation.getArgument(5);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).updateEFLinearFixed(anyInt(), eq(null), anyInt(), any(byte[].class),
+                eq(null), any(Message.class));
+
+        mSIMRecordsUT.setMailboxIndex(1);
+        Message message = Message.obtain(mTestHandler);
+        mSIMRecordsUT.setVoiceMailNumber(alphaTag, voiceMailNumber, message);
+        latch.await(8, TimeUnit.SECONDS);
+        mTestLooper.startAutoDispatch();
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+        verify(mFhMock, times(1)).updateEFLinearFixed(anyInt(), eq(null), anyInt(),
+                any(byte[].class), eq(null), any(Message.class));
+        //if attempt to save bugAlphatag which sim don't support so we will make it null
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return true;
+            }
+
+            @Override
+            public Object actual() {
+                return mSIMRecordsUT.getVoiceMailNumber() != null;
+            }
+        });
+        assertEquals(null, mSIMRecordsUT.getVoiceMailAlphaTag());
+        assertEquals(voiceMailNumber, mSIMRecordsUT.getVoiceMailNumber());
+    }
+
+    @Test
+    public void testSetVoiceMailNumberUtf16Alphatag() throws InterruptedException {
+        String voiceMailNumber = "1234567890";
+        String alphaTag = "หมายเลขข้อความเสียง"; // Messagerie vocale
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the first invocation");
+            Message response = invocation.getArgument(2);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the second invocation");
+            Message response = invocation.getArgument(5);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).updateEFLinearFixed(anyInt(), eq(null), anyInt(), any(byte[].class),
+                eq(null), any(Message.class));
+
+        mSIMRecordsUT.setMailboxIndex(1);
+        Message message = Message.obtain(mTestHandler);
+        mSIMRecordsUT.setVoiceMailNumber(alphaTag, voiceMailNumber, message);
+        latch.await(5, TimeUnit.SECONDS);
+
+        mTestLooper.startAutoDispatch();
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+        verify(mFhMock, times(1)).updateEFLinearFixed(anyInt(), eq(null), anyInt(),
+                any(byte[].class), eq(null), any(Message.class));
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return true;
+            }
+
+            @Override
+            public Object actual() {
+                return mSIMRecordsUT.getVoiceMailNumber() != null;
+            }
+        });
+        assertEquals(voiceMailNumber, mSIMRecordsUT.getVoiceMailNumber());
+        //if attempt to save bugAlphatag which sim don't support so we will make it null
+        assertEquals(null, mSIMRecordsUT.getVoiceMailAlphaTag());
+    }
+
+    @Test
+    public void testSetVoiceMailNullNumber() throws InterruptedException {
+        String voiceMailNumber = null;
+        String alphaTag = "VoicemailAlphaTag"; // Messagerie vocale
+        final CountDownLatch latch = new CountDownLatch(2);
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the first invocation");
+            Message response = invocation.getArgument(2);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+
+        doAnswer(invocation -> {
+            int[] result = new int[3];
+            result[0] = 32;
+            result[1] = 32;
+            result[2] = 1;
+            Rlog.d("SIMRecordsTest", "Executing the second invocation");
+            Message response = invocation.getArgument(5);
+            AsyncResult.forMessage(response, result, null);
+            response.sendToTarget();
+            latch.countDown();
+            return null;
+        }).when(mFhMock).updateEFLinearFixed(anyInt(), eq(null), anyInt(), any(byte[].class),
+                eq(null), any(Message.class));
+
+        mSIMRecordsUT.setMailboxIndex(1);
+        Message message = Message.obtain(mTestHandler);
+        mSIMRecordsUT.setVoiceMailNumber(alphaTag, voiceMailNumber, message);
+        latch.await(5, TimeUnit.SECONDS);
+        mTestLooper.startAutoDispatch();
+        verify(mFhMock, times(1)).getEFLinearRecordSize(anyInt(), isNull(), any(Message.class));
+        verify(mFhMock, times(1)).updateEFLinearFixed(anyInt(), eq(null), anyInt(),
+                any(byte[].class), eq(null), any(Message.class));
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return true;
+            }
+
+            @Override
+            public Object actual() {
+                return mSIMRecordsUT.getVoiceMailAlphaTag() != null;
+            }
+        });
+        assertEquals(null, mSIMRecordsUT.getVoiceMailNumber());
+        assertEquals(alphaTag, mSIMRecordsUT.getVoiceMailAlphaTag());
+    }
+
+    public interface Condition {
+        Object expected();
+
+        Object actual();
+    }
+
+    protected void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (Exception e) {
+            Log.d(TAG, "InterruptedException");
+        }
+    }
+
+    protected void waitUntilConditionIsTrueOrTimeout(Condition condition) {
+        final long start = System.currentTimeMillis();
+        while (!Objects.equals(condition.expected(), condition.actual())
+                && System.currentTimeMillis() - start
+                < (long) SIMRecordsTest.SET_VOICE_MAIL_TIMEOUT) {
+            sleep(50);
+        }
+        assertEquals("Service Unbound", condition.expected(), condition.actual());
+    }
 }
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..e4fabc5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
@@ -61,7 +61,7 @@
         mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
         mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
         mUiccCard = new UiccCard(mContext, mSimulatedCommands, mIccCardStatus, 0 /* phoneId */,
-            new Object(), false);
+            new Object(), IccSlotStatus.MultipleEnabledProfilesMode.NONE);
         processAllMessages();
         logd("create UiccCard");
     }
@@ -97,4 +97,10 @@
         assertNull(mUiccCard.getUiccPort(INVALID_PORT_ID));
         assertNotNull(mUiccCard.getUiccPort(TelephonyManager.DEFAULT_PORT_INDEX));
     }
+
+    @Test
+    @SmallTest
+    public void testGetCardId() {
+        assertNull(mUiccCard.getCardId());
+    }
 }
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 3deb501..143d7c9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
@@ -85,7 +85,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
                 AsyncResult ar = new AsyncResult(null, iir, null);
                 message.obj = ar;
@@ -93,16 +93,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                anyInt(), anyInt(), anyString(), any(Message.class));
+                anyInt(), anyInt(), anyString(), eq(false) /*isEs10Command*/, any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -327,7 +327,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
                 AsyncResult ar = new AsyncResult(null, iir, null);
                 message.obj = ar;
@@ -335,16 +335,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                anyInt(), anyInt(), anyString(), any(Message.class));
+                anyInt(), anyInt(), anyString(), eq(false) /*isEs10Command*/, any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
@@ -388,7 +388,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
                 AsyncResult ar = new AsyncResult(null, iir, null);
                 message.obj = ar;
@@ -396,16 +396,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                anyInt(), anyInt(), anyString(), any(Message.class));
+                anyInt(), anyInt(), anyString(), eq(false) /*isEs10Command*/, any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -445,7 +445,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
                 AsyncResult ar = new AsyncResult(null, iir, null);
                 message.obj = ar;
@@ -453,16 +453,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                anyInt(), anyInt(), anyString(), any(Message.class));
+                anyInt(), anyInt(), anyString(), eq(false /*isEs10Command*/), any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -509,11 +509,11 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -569,14 +569,14 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 currentFileId.set((String) invocation.getArguments()[6]);
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 AsyncResult ar = new AsyncResult(null, new int[]{2}, null);
                 message.obj = ar;
                 message.sendToTarget();
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), eq(0x00), eq(0xA4), eq(0x00),
-                eq(0x04), eq(0x02), anyString(), any(Message.class));
+                eq(0x04), eq(0x02), anyString(), eq(false /*isEs10Command*/), any(Message.class));
 
         // Read binary - since params are identical across files, we need to keep track of which
         // file was selected most recently and give back that content.
@@ -597,7 +597,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir =
                         new IccIoResult(0x90, 0x00,
                                 IccUtils.hexStringToBytes(binaryContent.get(currentFileId.get())));
@@ -607,16 +607,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), eq(0x00), eq(0xB0), eq(0x00),
-                eq(0x00), eq(0x00), eq(""), any(Message.class));
+                eq(0x00), eq(0x00), eq(""), eq(false /*isEs10Command*/), any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -667,14 +667,14 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 currentFileId.set((String) invocation.getArguments()[6]);
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 AsyncResult ar = new AsyncResult(null, new int[]{2}, null);
                 message.obj = ar;
                 message.sendToTarget();
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), eq(0x00), eq(0xA4), eq(0x00),
-                eq(0x04), eq(0x02), anyString(), any(Message.class));
+                eq(0x04), eq(0x02), anyString(), eq(false /*isEs10Command*/), any(Message.class));
 
         // Read binary - since params are identical across files, we need to keep track of which
         // file was selected most recently and give back that content.
@@ -690,7 +690,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir =
                         new IccIoResult(0x90, 0x00,
                                 IccUtils.hexStringToBytes(binaryContent.get(currentFileId.get())));
@@ -700,16 +700,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), eq(0x00), eq(0xB0), eq(0x00),
-                eq(0x00), eq(0x00), eq(""), any(Message.class));
+                eq(0x00), eq(0x00), eq(""), eq(false /*isEs10Command*/), any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
@@ -766,7 +766,7 @@
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00,
                         IccUtils.hexStringToBytes(hexString1));
                 AsyncResult ar = new AsyncResult(null, iir, null);
@@ -775,12 +775,12 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                eq(P2), anyInt(), anyString(), any(Message.class));
+                eq(P2), anyInt(), anyString(), eq(false), any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[7];
+                Message message = (Message) invocation.getArguments()[8];
                 IccIoResult iir = new IccIoResult(0x90, 0x00,
                         IccUtils.hexStringToBytes(hexString2));
                 AsyncResult ar = new AsyncResult(null, iir, null);
@@ -789,16 +789,16 @@
                 return null;
             }
         }).when(mUiccProfile).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
-                eq(P2_EXTENDED_DATA), anyInt(), anyString(), any(Message.class));
+                eq(P2_EXTENDED_DATA), anyInt(), anyString(), eq(false), any(Message.class));
 
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
-                Message message = (Message) invocation.getArguments()[1];
+                Message message = (Message) invocation.getArguments()[2];
                 message.sendToTarget();
                 return null;
             }
-        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), any(Message.class));
+        }).when(mUiccProfile).iccCloseLogicalChannel(anyInt(), eq(false), any(Message.class));
 
         mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(mUiccProfile, null);
         processAllMessages();
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..2ab23f3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -104,6 +104,8 @@
 
         doReturn(PHONE_COUNT).when(mTelephonyManager).getPhoneCount();
         doReturn(PHONE_COUNT).when(mTelephonyManager).getSimCount();
+        doReturn(IccSlotStatus.MultipleEnabledProfilesMode.NONE)
+                .when(mMockSlot).getSupportedMepMode();
         // set number of slots to 1
         mContextFixture.putIntResource(com.android.internal.R.integer.config_num_physical_slots, 1);
 
@@ -114,6 +116,8 @@
         mIccCardStatus.mCdmaSubscriptionAppIndex =
                 mIccCardStatus.mImsSubscriptionAppIndex =
                         mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
+        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        mIccCardStatus.mSupportedMepMode = IccSlotStatus.MultipleEnabledProfilesMode.NONE;
         mSimulatedCommands.setIccCardStatus(mIccCardStatus);
         // for testing we pretend slotIndex is set. In reality it would be invalid on older versions
         // (before 1.2) of hal
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
index bddb044..14e95f1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
@@ -140,7 +140,7 @@
 
         record = mUiccPort.getOpenLogicalChannelRecord(CHANNEL_ID);
         assertThat(record).isNull();
-        verify(mUiccProfile).iccCloseLogicalChannel(eq(CHANNEL_ID), eq(null));
+        verify(mUiccProfile).iccCloseLogicalChannel(eq(CHANNEL_ID), eq(false), eq(null));
     }
 
     private IccLogicalChannelRequest getIccLogicalChannelRequest() {
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 e139e95..a9034eb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.atLeast;
@@ -32,8 +32,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Message;
@@ -41,6 +41,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -50,6 +51,7 @@
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.cat.CatService;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
 
 import org.junit.After;
@@ -70,6 +72,8 @@
     }
 
     private IccIoResult mIccIoResult;
+    private PersistableBundle mBundle;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
 
     private static final int UICCPROFILE_CARRIER_PRIVILEGE_LOADED_EVENT = 3;
 
@@ -118,8 +122,18 @@
                         mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
         mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
         mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
+        mBundle = mContextFixture.getCarrierConfigBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
+
+        // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mUiccProfile = new UiccProfile(mContext, mSimulatedCommands, mIccCardStatus,
               0 /* phoneId */, mUiccCard, new Object());
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
+
         processAllMessages();
         logd("Create UiccProfile");
 
@@ -130,6 +144,7 @@
     public void tearDown() throws Exception {
         mUiccProfile = null;
         mIccIoResult = null;
+        mBundle = null;
         super.tearDown();
     }
 
@@ -212,7 +227,7 @@
                 anyInt(), isA(Message.class));
         verify(mSimulatedCommandsVerifier, times(2)).iccTransmitApduLogicalChannel(
                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyString(),
-                isA(Message.class)
+                anyBoolean(), isA(Message.class)
         );
     }
 
@@ -535,8 +550,9 @@
         carrierConfigBundle.putString(CarrierConfigManager.KEY_CARRIER_NAME_STRING,
                 fakeCarrierName);
 
-        // broadcast CARRIER_CONFIG_CHANGED
-        mContext.sendBroadcast(new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        // send carrier config change
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mPhone.getPhoneId(), mPhone.getSubId(),
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
         processAllMessages();
 
         // verify that setSimOperatorNameForPhone() is called with fakeCarrierName
@@ -561,15 +577,17 @@
 
         mUiccProfile.getApplicationIndex(0).getIccRecords().mIccId = fakeIccId;
 
-        doReturn(false).when(mSubscriptionController)
-                .checkPhoneIdAndIccIdMatch(anyInt(), anyString());
+        doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1)
+                .setIccId("98765").build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(anyInt());
         mUiccProfile.setOperatorBrandOverride(fakeBrand);
         String brandInSharedPreference = mContext.getSharedPreferences("file name", 0)
                 .getString("operator_branding_" + fakeIccId, null);
         assertNotEquals(fakeBrand, brandInSharedPreference);
 
-        doReturn(true).when(mSubscriptionController)
-                .checkPhoneIdAndIccIdMatch(anyInt(), anyString());
+        doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1)
+                .setIccId(fakeIccId).build()).when(mSubscriptionManagerService)
+                .getSubscriptionInfoInternal(anyInt());
         mUiccProfile.setOperatorBrandOverride(fakeBrand);
         brandInSharedPreference = mContext.getSharedPreferences("file name", 0)
                 .getString("operator_branding_" + fakeIccId, null);
@@ -585,8 +603,6 @@
 
         mUiccProfile.getApplicationIndex(0).getIccRecords().mIccId = fakeIccId1;
         doReturn(fakeIccId2).when(mSubscriptionInfo).getIccId();
-        doReturn(mSubscriptionInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfoForSimSlotIndex(eq(0), any(), any());
 
         mUiccProfile.setOperatorBrandOverride(fakeBrand);
         String brandInSharedPreference = mContext.getSharedPreferences("file name", 0)
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..230f147 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -158,8 +158,7 @@
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-        verify(mSubInfoRecordUpdater).updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
     }
 
     @Test
@@ -380,8 +379,7 @@
         // Make sure when received CARDSTATE_ABSENT state in the first time,
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
         mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
-        verify(mSubInfoRecordUpdater).updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
         assertNull(mUiccSlot.getUiccCard());
     }
@@ -414,8 +412,9 @@
         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(mUiccController).updateSimStateForInactivePort(
+                activeIss.mSimPortInfos[0].mLogicalSlotIndex,
+                inactiveIss.mSimPortInfos[0].mIccId);
     }
 
     @Test
@@ -434,12 +433,10 @@
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
         assertNotNull(mUiccSlot.getUiccCard());
 
-        // Simulate when SIM is removed, UiccCard and UiccProfile should be disposed and ABSENT
-        // state is sent to SubscriptionInfoUpdater.
+        // Simulate when SIM is removed
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
         mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
-        verify(mSubInfoRecordUpdater).updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
         verify(mUiccProfile).dispose();
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
         assertNull(mUiccSlot.getUiccCard());
@@ -462,9 +459,7 @@
         // radio state unavailable
         mUiccSlot.onRadioStateUnavailable(phoneId);
 
-        // Verify that UNKNOWN state is sent to SubscriptionInfoUpdater in this case.
-        verify(mSubInfoRecordUpdater).updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, phoneId);
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.UNKNOWN, null);
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
         assertNull(mUiccSlot.getUiccCard());
 
@@ -472,9 +467,7 @@
         mIccCardStatus.mCardState = CardState.CARDSTATE_ABSENT;
         mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
 
-        // Verify that ABSENT state is sent to SubscriptionInfoUpdater in this case.
-        verify(mSubInfoRecordUpdater).updateInternalIccState(
-                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
         assertNull(mUiccSlot.getUiccCard());
     }
@@ -511,4 +504,79 @@
         assertTrue("EuiccCard should be removable", mUiccSlot.isRemovable());
     }
 
+    @Test
+    @SmallTest
+    public void testMultipleEnabledProfilesData() {
+        IccSlotStatus iss = new IccSlotStatus();
+        IccSimPortInfo simPortInfo1 = new IccSimPortInfo();
+        simPortInfo1.mPortActive = false;
+        simPortInfo1.mLogicalSlotIndex = -1;
+        simPortInfo1.mIccId = "fake-iccid";
+
+        IccSimPortInfo simPortInfo2 = new IccSimPortInfo();
+        simPortInfo2.mPortActive = true;
+        simPortInfo2.mLogicalSlotIndex = 0;
+        simPortInfo2.mIccId = "fake-iccid";
+
+        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1, simPortInfo2};
+        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        iss.atr = "3B9F97C00AB1FE453FC6838031E073FE211F65D002341569810F21";
+        iss.setMultipleEnabledProfilesMode(3);
+
+
+        // initial state
+        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertEquals(IccSlotStatus.MultipleEnabledProfilesMode.NONE,
+                mUiccSlot.getSupportedMepMode());
+        assertFalse(mUiccSlot.isMultipleEnabledProfileSupported());
+
+        // update slot to inactive
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
+
+        // assert on updated values
+        assertNull(mUiccSlot.getUiccCard());
+        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
+        assertTrue(mUiccSlot.isMultipleEnabledProfileSupported());
+        assertEquals(IccSlotStatus.MultipleEnabledProfilesMode.MEP_B,
+                mUiccSlot.getSupportedMepMode());
+
+        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1};
+        iss.setMultipleEnabledProfilesMode(1); // Set MEP mode to MEP-A1
+
+        // update port info and MEP mode
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
+
+        // assert on updated values
+        assertTrue(mUiccSlot.isMultipleEnabledProfileSupported());
+        assertEquals(IccSlotStatus.MultipleEnabledProfilesMode.MEP_A1,
+                mUiccSlot.getSupportedMepMode());
+
+        //update port info and MEP mode to test HAL version 2.0
+        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1, simPortInfo2};
+        iss.setMultipleEnabledProfilesMode(0); // Set MEP mode to NONE(assume modem sends)
+
+        // update port info and MEP mode
+        mUiccSlot.update(null, iss, 0 /* slotIndex */);
+        assertTrue(mUiccSlot.isMultipleEnabledProfileSupported());
+        assertEquals(IccSlotStatus.MultipleEnabledProfilesMode.MEP_B,
+                mUiccSlot.getSupportedMepMode());
+    }
+
+    @Test
+    @SmallTest
+    public void testSimStateUnknown() {
+        int phoneId = 0;
+        int slotIndex = 0;
+        // Initially state is unknown
+        assertTrue(mUiccSlot.isStateUnknown());
+        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
+        mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
+        assertNull(mUiccSlot.getUiccCard());
+        // As CardState is absent, state should not be unknown
+        assertFalse(mUiccSlot.isStateUnknown());
+        // radio state unavailable
+        mUiccSlot.onRadioStateUnavailable(phoneId);
+        // When radio is not available, state is unknown
+        assertTrue(mUiccSlot.isStateUnknown());
+    }
 }
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..7e51bad 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
@@ -99,7 +99,8 @@
 
         // 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(),
+                IccSlotStatus.MultipleEnabledProfilesMode.NONE);
         when(UiccController.getInstance().getUiccCardForPhone(0)).thenReturn(card);
         uiccLauncher.handleMessage(msg);
 
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..b6dd7bd 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
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -34,6 +35,7 @@
 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.IccSlotStatus;
 import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker;
 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
 
@@ -94,7 +96,7 @@
 
         mEuiccCard =
             new EuiccCard(mContext, mMockCi, mMockIccCardStatus,
-                0 /* phoneId */, new Object(), false) {
+                0 /* phoneId */, new Object(), IccSlotStatus.MultipleEnabledProfilesMode.NONE) {
 
                 @Override
                 protected void loadEidAndNotifyRegistrants() {}
@@ -133,7 +135,8 @@
     public void testPassEidInConstructor() {
         mMockIccCardStatus.eid = "1A2B3C4D";
         mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
-                mMockIccCardStatus, 0 /* phoneId */, new Object(), false);
+                mMockIccCardStatus, 0 /* phoneId */, new Object(),
+                IccSlotStatus.MultipleEnabledProfilesMode.NONE);
 
         final int eventEidReady = 0;
         Handler handler = new Handler(Looper.myLooper()) {
@@ -154,7 +157,8 @@
         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
         mHandler.post(() -> {
             mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
-                    mMockIccCardStatus, 0 /* phoneId */, new Object(), false);
+                    mMockIccCardStatus, 0 /* phoneId */, new Object(),
+                    IccSlotStatus.MultipleEnabledProfilesMode.NONE);
         });
         processAllMessages();
 
@@ -188,7 +192,7 @@
     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());
+                        eq(0), eq(command.length() / 2), eq(command), anyBoolean(), any());
     }
 
     private int mockLogicalChannelResponses(Object... responses) {
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
index 90163cf..d140ca8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
@@ -22,6 +22,7 @@
 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.eq;
 import static org.mockito.Mockito.mock;
@@ -49,6 +50,8 @@
 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.IccSlotStatus;
+import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode;
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.asn1.Asn1Node;
 import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
@@ -118,7 +121,8 @@
         mMockIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
         mEuiccPort =
             new EuiccPort(mContext, mMockCi, mMockIccCardStatus,
-                0 /* phoneId */, new Object(), mEuiccCard, false) {
+                0 /* phoneId */, new Object(), mEuiccCard,
+                    IccSlotStatus.MultipleEnabledProfilesMode.NONE) {
                 @Override
                 protected byte[] getDeviceId() {
                     return IccUtils.bcdToBytes("987654321012345");
@@ -171,7 +175,7 @@
                 "BF2D14A012E3105A0A896700000000004523019F7001019000");
 
         ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
+        mEuiccPort.mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B; // MEP capable
         mEuiccPort.getAllProfiles(resultCaptor, mHandler);
         processAllMessages();
 
@@ -180,7 +184,7 @@
         assertEquals(1, profiles.length);
         assertEquals("98760000000000543210", profiles[0].getIccid());
         assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F20");
+        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
     }
 
     @Test
@@ -203,10 +207,10 @@
     @Test
     public void testEnabledOnEsimPort_GetAllProfiles() {
         int channel = mockLogicalChannelResponses(
-                "BF2D18A016E3145A0A896700000000004523019F7001009F2001019000");
+                "BF2D18A016E3145A0A896700000000004523019F7001009F2401019000");
 
         ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
+        mEuiccPort.mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B; // MEP capable
         mEuiccPort.getAllProfiles(resultCaptor, mHandler);
         processAllMessages();
 
@@ -218,7 +222,7 @@
         // 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, "BF2D0F5C0D5A909192B79F709599BF769F20");
+        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
     }
 
     @Test
@@ -228,14 +232,14 @@
                 "BF2D14A012E3105A0A896700000000004523FF9F7001009000");
 
         ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
+        mEuiccPort.mSupportedMepMode = MultipleEnabledProfilesMode.MEP_B; // 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, "BF2D0F5C0D5A909192B79F709599BF769F20");
+        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
     }
 
     @Test
@@ -375,6 +379,22 @@
     }
 
     @Test
+    public void testSwitchToProfile_MepA1() {
+        int channel = mockLogicalChannelResponses("BF31038001039000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mMockIccCardStatus.mSlotPortMapping.mPortIndex = 1;
+        mEuiccPort.updateSupportedMepMode(MultipleEnabledProfilesMode.MEP_A1);
+        mEuiccPort.update(mContext, mMockCi, mMockIccCardStatus, mEuiccCard);
+        mEuiccPort.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        // In case of MEP-A1, verify portIndex is shifted or not.
+        verifyStoreData(channel, "BF3114A00C5A0A896700000000004523018101FF820102");
+    }
+
+    @Test
     public void testGetEid() {
         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
 
@@ -884,7 +904,7 @@
         verify(mMockCi, never())
                 .iccTransmitApduLogicalChannel(
                         eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
-                        any());
+                        anyBoolean(), any());
     }
 
     @Test
@@ -917,7 +937,7 @@
         verify(mMockCi, never())
                 .iccTransmitApduLogicalChannel(
                         eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
-                        any());
+                        anyBoolean(), any());
     }
 
     @Test
@@ -1175,7 +1195,7 @@
     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());
+                        eq(0), eq(command.length() / 2), eq(command), anyBoolean(), any());
     }
 
     private int mockLogicalChannelResponses(Object... responses) {
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..b073c6a 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
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 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.Mockito.mock;
@@ -119,7 +120,7 @@
         assertNull(mResponseCaptor.response);
         assertNull(mResponseCaptor.exception);
         verify(mMockCi).iccOpenLogicalChannel(eq(AID), anyInt(), any());
-        verify(mMockCi).iccCloseLogicalChannel(eq(channel), any());
+        verify(mMockCi).iccCloseLogicalChannel(eq(channel), eq(true /*isEs10*/), any());
     }
 
     @Test
@@ -149,7 +150,7 @@
 
         assertEquals("A1A1A1", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
     }
 
     @Test
@@ -169,13 +170,13 @@
 
         assertEquals("A4", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(1), eq("ab"), any());
+                eq(3), eq(1), eq("ab"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq(""), any());
+                eq(3), eq(0), eq(""), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x91),
-                eq(0), eq(2), eq("abcd"), any());
+                eq(0), eq(2), eq("abcd"), anyBoolean(), any());
     }
 
     @Test
@@ -196,11 +197,11 @@
 
         assertEquals("A3", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(1), eq("ab"), any());
+                eq(3), eq(1), eq("ab"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq(""), any());
+                eq(3), eq(0), eq(""), anyBoolean(), any());
     }
 
     @Test
@@ -216,11 +217,11 @@
 
         assertEquals("A1A1A1B2B2B2B2C3C3", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel), eq(0xC0), eq(0),
-                eq(0), eq(4), eq(""), any());
+                eq(0), eq(4), eq(""), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel), eq(0xC0), eq(0),
-                eq(0), eq(2), eq(""), any());
+                eq(0), eq(2), eq(""), anyBoolean(), any());
     }
 
     @Test
@@ -244,15 +245,15 @@
 
         assertEquals("C3", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("b"), any());
+                eq(3), eq(0), eq("b"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x11),
-                eq(0), eq(0xFF), eq(s1), any());
+                eq(0), eq(0xFF), eq(s1), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x11),
-                eq(1), eq(0xFF), eq(s2), any());
+                eq(1), eq(0xFF), eq(s2), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x91),
-                eq(2), eq(16), eq(s3), any());
+                eq(2), eq(16), eq(s3), anyBoolean(), any());
     }
 
     @Test
@@ -272,9 +273,9 @@
 
         assertEquals("B2222B", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x11),
-                eq(0), eq(0xFF), eq(s1), any());
+                eq(0), eq(0xFF), eq(s1), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x91),
-                eq(1), eq(0xFF), eq(s2), any());
+                eq(1), eq(0xFF), eq(s2), anyBoolean(), any());
     }
 
     @Test
@@ -290,7 +291,7 @@
 
         assertEquals("B2222B", IccUtils.bytesToHexString(mResponseCaptor.response));
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x91),
-                eq(0), eq(0), eq(""), any());
+                eq(0), eq(0), eq(""), anyBoolean(), any());
     }
 
     @Test
@@ -313,13 +314,13 @@
 
         assertEquals(0x6985, ((ApduException) mResponseCaptor.exception).getApduStatus());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(channel | 10), eq(1), eq(2),
-                eq(3), eq(0), eq("a"), any());
+                eq(3), eq(0), eq("a"), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x11),
-                eq(0), eq(0xFF), eq(s1), any());
+                eq(0), eq(0xFF), eq(s1), anyBoolean(), any());
         verify(mMockCi).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2), eq(0x11),
-                eq(1), eq(0xFF), eq(s2), any());
+                eq(1), eq(0xFF), eq(s2), anyBoolean(), any());
         verify(mMockCi, never()).iccTransmitApduLogicalChannel(eq(channel), eq(0x81), eq(0xE2),
-                eq(0x91), eq(2), eq(16), eq(s3), any());
+                eq(0x91), eq(2), eq(16), eq(s3), anyBoolean(), any());
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/LogicalChannelMocker.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/LogicalChannelMocker.java
index e9796a1..27f743f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/LogicalChannelMocker.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/LogicalChannelMocker.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc.euicc.apdu;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -64,32 +65,39 @@
     public static void mockSendToLogicalChannel(CommandsInterface mockCi, int channel,
             Object... responseObjects) {
         ArgumentCaptor<Message> response = ArgumentCaptor.forClass(Message.class);
+
         doAnswer(new Answer() {
             private int mIndex = 0;
 
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
                 Object responseObject = responseObjects[mIndex++];
-                boolean isException = responseObject instanceof Throwable;
-                int sw1 = 0;
-                int sw2 = 0;
-                String hex = responseObject.toString();
-                if (!isException) {
-                    int l = hex.length();
-                    sw1 = Integer.parseInt(hex.substring(l - 4, l - 2), 16);
-                    sw2 = Integer.parseInt(hex.substring(l - 2), 16);
-                    hex = hex.substring(0, l - 4);
-                }
-                IccIoResult result = isException ? null : new IccIoResult(sw1, sw2, hex);
-                Throwable exception = isException ? (Throwable) responseObject : null;
-
-                Message msg = response.getValue();
-                AsyncResult.forMessage(msg, result, exception);
-                msg.sendToTarget();
+                mockIccTransmitApduLogicalChannelResponse(response, responseObject);
                 return null;
             }
         }).when(mockCi).iccTransmitApduLogicalChannel(eq(channel), anyInt(), anyInt(), anyInt(),
-                anyInt(), anyInt(), anyString(), response.capture());
+                anyInt(), anyInt(), anyString(), anyBoolean(), response.capture());
+    }
+
+    private static void mockIccTransmitApduLogicalChannelResponse(ArgumentCaptor<Message> response,
+            Object responseObject) throws Throwable {
+
+        boolean isException = responseObject instanceof Throwable;
+        int sw1 = 0;
+        int sw2 = 0;
+        String hex = responseObject.toString();
+        if (!isException) {
+            int l = hex.length();
+            sw1 = Integer.parseInt(hex.substring(l - 4, l - 2), 16);
+            sw2 = Integer.parseInt(hex.substring(l - 2), 16);
+            hex = hex.substring(0, l - 4);
+        }
+        IccIoResult result = isException ? null : new IccIoResult(sw1, sw2, hex);
+        Throwable exception = isException ? (Throwable) responseObject : null;
+
+        Message msg = response.getValue();
+        AsyncResult.forMessage(msg, result, exception);
+        msg.sendToTarget();
     }
 
     public static void mockCloseLogicalChannel(CommandsInterface mockCi, int channel) {
@@ -99,7 +107,8 @@
             AsyncResult.forMessage(msg);
             msg.sendToTarget();
             return null;
-        }).when(mockCi).iccCloseLogicalChannel(eq(channel), response.capture());
+        }).when(mockCi).iccCloseLogicalChannel(eq(channel),
+                eq(true /*isEs10*/), response.capture());
     }
 
     private static int[] getSelectResponse(String responseHex) {
