diff --git a/Android.bp b/Android.bp
index c636ade..892a48a 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 de9ceed..35f2818 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/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index fc6afc0..ab7ebc4 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -78,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;
@@ -563,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);
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 bb5b6c0..6b44998 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -383,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/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 8850f93..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 onUiccApplicationsEnabledChanged(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
@@ -4256,6 +4493,12 @@
                         + ")");
         pw.println(" mUiccApplicationsEnabled=" + mUiccApplicationsEnabled);
         pw.flush();
+        try {
+            mCallWaitingController.dump(pw);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        pw.flush();
     }
 
     @Override
@@ -4374,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) {
@@ -4480,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
@@ -4654,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);
 
@@ -4770,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:"
@@ -4857,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
@@ -4867,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 7e87b5f..0acae4b 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -120,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.
@@ -129,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.
@@ -206,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);
             }
@@ -218,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.
@@ -346,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);
         }
     }
 
@@ -376,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);
     }
 
     /**
@@ -457,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) {
@@ -529,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.
@@ -564,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
@@ -594,12 +553,7 @@
             onRoamingDataEnabled(refSubId, enable);
         }
 
-        if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService.syncGroupedSetting(refSubId);
-        } else {
-            // Sync settings in subscription database..
-            mSubController.syncGroupedSetting(refSubId);
-        }
+        mSubscriptionManagerService.syncGroupedSetting(refSubId);
     }
 
     /**
@@ -621,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);
@@ -665,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;
         }
@@ -682,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);
@@ -771,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) {
@@ -890,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.
@@ -925,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
@@ -959,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());
     }
 
     /**
@@ -981,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());
         }
 
@@ -1002,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) {
@@ -1029,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) {
@@ -1094,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;
 
@@ -1142,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/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 4093015..beebf22 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;
@@ -53,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;
@@ -84,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";
@@ -118,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;
@@ -144,9 +140,22 @@
         }
     };
 
-    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;
@@ -154,10 +163,10 @@
     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;
@@ -169,6 +178,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.
      *
@@ -181,14 +194,22 @@
         mDisplayInfoController = displayInfoController;
         mOverrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
         mIsPhysicalChannelConfigOn = true;
+        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);
     }
 
@@ -201,10 +222,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;
     }
 
@@ -215,35 +247,30 @@
                 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() {
@@ -276,11 +303,10 @@
             mNrAdvancedCapableByPcoChangedCallback =
                     new DataNetworkControllerCallback(getHandler()::post) {
                         @Override
-                        public void onNrAdvancedCapableByPcoChanged(
-                                boolean nrAdvancedCapable) {
+                        public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {
                             log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
                             mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
-                            sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE);
+                            sendMessage(EVENT_UPDATE);
                         }
                     };
             mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
@@ -324,7 +350,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;
@@ -351,7 +377,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;
@@ -377,7 +403,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);
@@ -419,7 +445,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
@@ -450,7 +476,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);
@@ -480,9 +506,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()) {
@@ -496,8 +522,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()) {
@@ -517,8 +543,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;
@@ -535,20 +559,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;
@@ -590,6 +604,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();
@@ -636,11 +664,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);
@@ -653,21 +689,10 @@
                     }
                     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()) {
@@ -675,8 +700,6 @@
                             resetAllTimers();
                         }
                     }
-                    // Update in case of LTE/LTE+ switch
-                    updateOverrideNetworkType();
                     break;
                 case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
@@ -723,52 +746,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:
@@ -807,52 +830,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:
@@ -876,28 +899,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);
@@ -905,34 +935,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;
@@ -945,37 +962,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) {
@@ -1011,22 +1087,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();
@@ -1073,12 +1150,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();
+                }
             }
         }
     }
@@ -1175,17 +1257,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;
     }
 
     /**
@@ -1200,7 +1280,7 @@
 
         // 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;
         }
 
@@ -1214,6 +1294,7 @@
                     .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) {
@@ -1226,18 +1307,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;
@@ -1256,19 +1334,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];
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 5ce33c2..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);
@@ -2479,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?");
         }
     }
 
@@ -2979,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);
     }
 
@@ -2988,6 +2996,9 @@
      * emergency operator.
      */
     public boolean isInEcm() {
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            return EmergencyStateTracker.getInstance().isInEcm();
+        }
         return mIsPhoneInEcmState;
     }
 
@@ -2996,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());
     }
@@ -4081,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);
     }
 
     /**
@@ -4387,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));
         }
     }
@@ -4406,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
@@ -4750,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;
     }
@@ -4897,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) {
@@ -4926,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 bea2c2a..aff62ae 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -141,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
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 69f4da7..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;
@@ -180,6 +180,7 @@
     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();
 
@@ -217,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();
 
@@ -321,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;
@@ -347,8 +343,6 @@
 
     @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 =
@@ -386,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
@@ -395,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;
         }
     };
 
@@ -560,8 +545,12 @@
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             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);
@@ -623,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())
@@ -652,12 +647,7 @@
         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);
@@ -670,7 +660,7 @@
 
         mAccessNetworksManager = mPhone.getAccessNetworksManager();
         mOutOfServiceSS = new ServiceState();
-        mOutOfServiceSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mOutOfServiceSS.setOutOfService(false);
 
         for (int transportType : mAccessNetworksManager.getAvailableTransports()) {
             mRegStateManagers.append(transportType, new NetworkRegistrationManager(
@@ -693,7 +683,7 @@
                 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);
@@ -735,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
@@ -770,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;
@@ -873,13 +880,20 @@
             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;
@@ -1069,7 +1083,7 @@
      * @return the current reasons for which the radio is off.
      */
     public Set<Integer> getRadioPowerOffReasons() {
-        return mRadioPowerOffReasons;
+        return Set.copyOf(mRadioPowerOffReasons);
     }
 
     /**
@@ -1095,7 +1109,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);
     }
 
     /**
@@ -1136,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
@@ -1651,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;
 
@@ -1660,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;
@@ -1673,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);
@@ -1753,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();
@@ -2091,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;
     }
@@ -2131,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;
@@ -2505,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);
@@ -2541,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);
@@ -2728,7 +2778,7 @@
 
     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
@@ -2758,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();
@@ -3093,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);
         }
@@ -3110,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();
@@ -3260,7 +3300,6 @@
                 + " mImsRegistrationOnOff=" + mImsRegistrationOnOff
                 + "}");
 
-
         if (mImsRegistrationOnOff && !registered) {
             // moving to deregistered, only send this event if we need to re-evaluate
             if (getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
@@ -3273,6 +3312,9 @@
             }
         }
         mImsRegistrationOnOff = registered;
+
+        // It's possible ServiceState changes did not trigger SPN display update; we update it here.
+        updateSpnDisplay();
     }
 
     public void onImsCapabilityChanged() {
@@ -3309,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);
@@ -3326,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);
@@ -3421,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(
@@ -3453,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 =
@@ -3557,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;
@@ -3603,7 +3638,6 @@
                     + " hasCssIndicatorChanged = " + hasCssIndicatorChanged
                     + " hasNrFrequencyRangeChanged = " + hasNrFrequencyRangeChanged
                     + " hasNrStateChanged = " + hasNrStateChanged
-                    + " hasBandwidthChanged = " + hasBandwidthChanged
                     + " hasAirplaneModeOnlChanged = " + hasAirplaneModeOnChanged);
         }
 
@@ -3650,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) {
@@ -3696,10 +3730,6 @@
             mCssIndicatorChangedRegistrants.notifyRegistrants();
         }
 
-        if (hasBandwidthChanged) {
-            mBandwidthChangedRegistrants.notifyRegistrants();
-        }
-
         if (hasRejectCauseChanged) {
             setNotification(CS_REJECT_CAUSE_ENABLED);
         }
@@ -4500,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?
@@ -5304,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);
 
@@ -5529,8 +5546,7 @@
     }
 
     /**
-     * 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) {
@@ -5544,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()
@@ -5554,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
@@ -5574,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);
-            }
-        }
     }
 
     /**
@@ -5856,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 150df57..8c35e57 100644
--- a/src/java/com/android/internal/telephony/SignalStrengthController.java
+++ b/src/java/com/android/internal/telephony/SignalStrengthController.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -347,16 +349,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) {
@@ -420,7 +415,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) {
@@ -477,6 +472,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);
@@ -510,7 +517,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,
@@ -543,6 +550,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);
@@ -571,12 +584,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());
@@ -587,6 +602,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();
@@ -1125,6 +1260,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 b05e600..0000000
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ /dev/null
@@ -1,5020 +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.annotation.RequiresPermission;
-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.Bundle;
-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.
-     */
-    public void 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);
-
-            mContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId(subId),
-                    value, null, null);
-
-            // Refresh the Cache of Active Subscription Info List
-            refreshCachedActiveSubscriptionInfoList();
-
-            notifyUiccAppsEnableChanged();
-            notifySubscriptionInfoChanged();
-        } 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)
-    @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.
-     */
-    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;
-    }
-
-    /**
-     * 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.
-     */
-    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    @Override
-    public void restoreAllSimSpecificSettingsFromBackup(@NonNull byte[] data) {
-        enforceModifyPhoneState("restoreAllSimSpecificSettingsFromBackup");
-
-        long token = Binder.clearCallingIdentity();
-        try {
-            Bundle bundle = new Bundle();
-            bundle.putByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA, data);
-            mContext.getContentResolver().call(
-                    SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
-                    SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
-                    null, bundle);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * @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 ea49d73..0000000
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ /dev/null
@@ -1,1358 +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) {
-        sContext.getContentResolver().call(
-                SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
-                SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
-                sIccId[phoneId], null);
-    }
-
-    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 6974837..267f70b 100644
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
@@ -19,19 +19,19 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.StringDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+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.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
@@ -52,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;
@@ -77,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.
@@ -190,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() {
@@ -312,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}.
      */
@@ -346,36 +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};
-
-            // 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();
-        }
+        // 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.
@@ -403,6 +386,8 @@
                             mApnTypeToQnsChangeNetworkCounter.clear();
                         }
                     });
+            mPhone.registerForEmergencyDomainSelected(
+                    this, EVENT_GUIDE_TRANSPORT_TYPE_FOR_EMERGENCY, null);
         });
     }
 
@@ -478,8 +463,7 @@
     /**
      * 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
@@ -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 4e165f7..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;
@@ -923,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);
 
@@ -1336,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();
         }
@@ -1594,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) {
@@ -2298,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
@@ -2572,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);
         }
@@ -2609,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 fb06e14..2ee1ffd 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;
     }
@@ -2095,6 +2087,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;
@@ -2814,6 +2808,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
@@ -3165,6 +3185,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)) {
@@ -3469,9 +3499,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/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 f5b60e1..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;
 
@@ -267,7 +268,7 @@
 
                     @Override
                     public void onInternetDataNetworkConnected(
-                            @NonNull List<DataProfile> dataProfiles) {
+                            @NonNull List<DataNetwork> internetNetworks) {
                         mIsInternetNetworkConnected = true;
                         logl("onInternetDataNetworkConnected");
                     }
@@ -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 8bc1dfa..9b44001 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -19,14 +19,16 @@
 import android.content.BroadcastReceiver;
 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;
@@ -35,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;
@@ -67,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;
 
 /**
@@ -95,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
@@ -160,8 +176,10 @@
     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) {
@@ -178,6 +196,12 @@
                 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.");
             }
@@ -265,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
@@ -285,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)
@@ -408,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.");
@@ -449,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<>();
@@ -467,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));
                     }
                 }
             }
@@ -483,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<>();
@@ -529,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));
                     }
                 }
             }
@@ -547,6 +632,8 @@
                 && mCurrentDatabaseVersion < otaDatabaseVersion) {
             mCurrentDatabaseVersion = otaDatabaseVersion;
             mEmergencyNumberListFromDatabase = updatedOtaEmergencyNumberList;
+            mNormalRoutedNumbers.clear();
+            mNormalRoutedNumbers = otaNormalRoutedNumbers;
         }
         return otaDatabaseVersion;
     }
@@ -595,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);
@@ -626,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(
@@ -691,7 +779,11 @@
         }
         mergedEmergencyNumberList.addAll(mEmergencyNumberListWithPrefix);
         mergedEmergencyNumberList.addAll(mEmergencyNumberListFromTestMode);
-        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        if (shouldDeterminingOfUrnsAndCategoriesWhileMergingIgnored()) {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        } else {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList, true);
+        }
         mEmergencyNumberList = mergedEmergencyNumberList;
     }
 
@@ -702,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;
     }
 
     /**
@@ -714,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;
         }
@@ -730,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
@@ -844,6 +998,10 @@
         return mCurrentDatabaseVersion;
     }
 
+    public int getEmergencyNumberOtaDbVersion() {
+        return mCurrentOtaDatabaseVersion;
+    }
+
     private synchronized void updateEmergencyCountryIso(String countryIso) {
         mCountryIso = countryIso;
         if (!TextUtils.isEmpty(mCountryIso)) {
@@ -859,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));
         }
@@ -890,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()));
                     }
                 }
             }
@@ -917,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);
@@ -940,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, "", "",
@@ -956,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;
 
@@ -980,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.");
@@ -1042,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;
             }
         }
 
@@ -1111,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) {
@@ -1138,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);
@@ -1146,7 +1213,12 @@
                     mEmergencyNumberListFromDatabase));
         }
         mergedEmergencyNumberList.addAll(getEmergencyNumberListTestMode());
-        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+
+        if (shouldDeterminingOfUrnsAndCategoriesWhileMergingIgnored()) {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList);
+        } else {
+            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(mergedEmergencyNumberList, true);
+        }
         return mergedEmergencyNumberList;
     }
 
@@ -1162,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(
@@ -1186,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
@@ -1194,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(" ========================================= ");
 
@@ -1233,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 7b19bc9..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;
+            }
+        }
     }
 
     /**
@@ -488,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;
 
@@ -559,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();
@@ -613,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}.
@@ -992,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)
@@ -1040,6 +1234,7 @@
             return (first == null ? 0 : first.hashCode());
         }
     }
+
     //***** Events
 
 
@@ -1111,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);
     }
 
     /**
@@ -1191,6 +1391,8 @@
         // For compatibility with apps that still use deprecated intent
         sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_UP);
         mCurrentlyConnectedSubId = Optional.of(subId);
+
+        initializeTerminalBasedCallWaiting();
     }
 
     /**
@@ -1251,6 +1453,7 @@
             mUtInterface = null;
         }
         mCurrentlyConnectedSubId = Optional.empty();
+        mMediaThreshold = null;
         resetImsCapabilities();
         hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
         // For compatibility with apps that still use deprecated intent
@@ -1291,6 +1494,7 @@
         // above. Remove all references to it.
         mPendingMO = null;
         updatePhoneState();
+        mImsCallInfoTracker.clearAllOrphanedConnections();
     }
 
     /**
@@ -1335,6 +1539,8 @@
                 (NetworkStatsManager) mPhone.getContext().getSystemService(
                         Context.NETWORK_STATS_SERVICE);
         statsManager.unregisterNetworkStatsProvider(mVtDataUsageProvider);
+
+        mPhone.unregisterForConnectionSetupFailure(this);
     }
 
     @Override
@@ -1526,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(
@@ -1543,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();
@@ -1637,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();
@@ -1677,6 +1888,8 @@
         logi("updateCarrierConfiguration: Updating ImsService configs.");
         mCarrierConfigLoadedForSubscription = true;
         updateImsServiceConfig();
+        updateMediaThreshold(
+                mThresholdRtpPacketLoss, mThresholdRtpJitter, mThresholdRtpInactivityTime);
     }
 
     /**
@@ -1725,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)) {
@@ -1771,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)
@@ -1873,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);
 
@@ -1894,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);
@@ -2615,6 +2876,7 @@
                 + System.identityHashCode(conn));
 
         call.onHangupLocal();
+        mImsCallInfoTracker.updateImsCallStatus(conn);
 
         try {
             if (imsCall != null) {
@@ -2815,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
@@ -2852,6 +3126,7 @@
         }
 
         if (changed) {
+            mImsCallInfoTracker.updateImsCallStatus(conn);
             if (conn.getCall() == mHandoverCall) return;
             updatePhoneState();
             mPhone.notifyPreciseCallStateChanged();
@@ -2883,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);
     }
@@ -2904,7 +3179,7 @@
         if (reason == null) {
             reason = "";
         } else {
-            reason = reason.toLowerCase();
+            reason = reason.toLowerCase(Locale.ROOT);
         }
         log("maybeRemapReasonCode : fromCode = " + reasonInfo.getCode() + " ; message = "
                 + reason);
@@ -3114,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:
@@ -3266,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
@@ -3273,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
@@ -3304,6 +3609,7 @@
                 if (conn != null) {
                     mForegroundCall.detach(conn);
                     removeConnection(conn);
+                    mImsCallInfoTracker.updateImsCallStatus(conn);
                 }
                 updatePhoneState();
                 mPhone.initiateSilentRedial(reasonInfo.getExtraCode() ==
@@ -3393,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;
 
@@ -3423,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,
@@ -3722,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(
@@ -4132,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);
+        }
     };
 
     /**
@@ -4269,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);
             }
         }
     };
@@ -4349,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;
         }
     }
 
@@ -4494,6 +4879,7 @@
                 try {
                     ImsFeature.Capabilities capabilities = (ImsFeature.Capabilities) args.arg1;
                     handleFeatureCapabilityChanged(capabilities);
+                    updateImsRegistrationInfo();
                 } finally {
                     args.recycle();
                 }
@@ -4576,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;
+            }
         }
     }
 
@@ -4750,6 +5185,7 @@
                         + mSupportSdpForRtpHeaderExtensions);
             }
         }
+        pw.println(" mSrvccTypeSupported=" + mSrvccTypeSupported);
         pw.println(" Event Log:");
         pw.increaseIndent();
         mOperationLocalLog.dump(pw);
@@ -5393,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);
@@ -5521,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 7d68ae1..ba07fa0 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -46,6 +46,7 @@
 import android.telephony.Annotation.NetworkType;
 import android.telephony.AnomalyReporter;
 import android.telephony.DisconnectCause;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsReasonInfo;
@@ -63,6 +64,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.AudioCodec;
@@ -155,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;
@@ -366,9 +370,8 @@
                     proto.srvccCompleted = true;
                     proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
                     // Call RAT may have changed (e.g. IWLAN -> UMTS) due to bearer change
-                    proto.ratAtEnd =
-                            ServiceStateStats.getVoiceRat(
-                                    mPhone, mPhone.getServiceState(), proto.bearerAtEnd);
+                    updateRatAtEnd(proto, getVoiceRatWithVoNRFix(
+                            mPhone, mPhone.getServiceState(), proto.bearerAtEnd));
                 }
                 break;
             case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
@@ -422,8 +425,7 @@
         }
         int bearer = getBearer(conn);
         ServiceState serviceState = getServiceState();
-        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, serviceState, bearer);
-
+        @NetworkType int rat = getVoiceRatWithVoNRFix(mPhone, serviceState, bearer);
         VoiceCallSession proto = new VoiceCallSession();
 
         proto.bearerAtStart = bearer;
@@ -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;
@@ -512,15 +514,10 @@
         }
 
         // Update end RAT
-        @NetworkType
-        int rat = ServiceStateStats.getVoiceRat(mPhone, getServiceState(), proto.bearerAtEnd);
-        if (proto.ratAtEnd != rat) {
-            proto.ratSwitchCount++;
-            proto.ratAtEnd = rat;
-            if (rat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-                proto.lastKnownRat = rat;
-            }
-        }
+        updateRatAtEnd(proto, getVoiceRatWithVoNRFix(mPhone, getServiceState(), proto.bearerAtEnd));
+
+        // Set device fold state
+        proto.foldState = mDeviceStateHelper.getFoldState();
 
         mAtomsStorage.addVoiceCallSession(proto);
 
@@ -581,8 +578,7 @@
             proto.setupFailed = false;
             // Track RAT when voice call is connected.
             ServiceState serviceState = getServiceState();
-            proto.ratAtConnected =
-                    ServiceStateStats.getVoiceRat(mPhone, serviceState, proto.bearerAtEnd);
+            proto.ratAtConnected = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd);
             // Reset list of codecs with the last codec at the present time. In this way, we
             // track codec quality only after call is connected and not while ringing.
             resetCodecList(conn);
@@ -593,19 +589,14 @@
         // RAT usage is not broken down by bearer. In case a CS call is made while there is IMS
         // voice registration, this may be inaccurate (i.e. there could be multiple RAT in use, but
         // we only pick the most feasible one).
-        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, state);
+        @NetworkType int rat = getVoiceRatWithVoNRFix(mPhone, state,
+                VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_UNKNOWN);
         mRatUsage.add(mPhone.getCarrierId(), rat, getTimeMillis(), getConnectionIds());
 
         for (int i = 0; i < mCallProtos.size(); i++) {
             VoiceCallSession proto = mCallProtos.valueAt(i);
-            rat = ServiceStateStats.getVoiceRat(mPhone, state, proto.bearerAtEnd);
-            if (proto.ratAtEnd != rat) {
-                proto.ratSwitchCount++;
-                proto.ratAtEnd = rat;
-                if (rat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-                    proto.lastKnownRat = rat;
-                }
-            }
+            rat = getVoiceRatWithVoNRFix(mPhone, state, proto.bearerAtEnd);
+            updateRatAtEnd(proto, rat);
             proto.bandAtEnd = (rat == TelephonyManager.NETWORK_TYPE_IWLAN)
                             ? 0
                             : ServiceStateStats.getBand(state);
@@ -613,6 +604,16 @@
         }
     }
 
+    private void updateRatAtEnd(VoiceCallSession proto, @NetworkType int rat) {
+        if (proto.ratAtEnd != rat) {
+            proto.ratSwitchCount++;
+            proto.ratAtEnd = rat;
+            if (rat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+                proto.lastKnownRat = rat;
+            }
+        }
+    }
+
     private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) {
         VoiceCallSession proto = mCallProtos.get(id);
         proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
@@ -679,6 +680,43 @@
         return mPhone.getSignalStrength().getLevel();
     }
 
+    /**
+     * This is a copy of ServiceStateStats.getVoiceRat(Phone, ServiceState, int) with minimum fix
+     * required for tracking EPSFB correctly.
+     */
+    @VisibleForTesting private static @NetworkType int getVoiceRatWithVoNRFix(
+            Phone phone, @Nullable ServiceState state, int bearer) {
+        if (state == null) {
+            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
+        if (bearer != VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS && imsPhone != null) {
+            @NetworkType int imsVoiceRat = imsPhone.getImsStats().getImsVoiceRadioTech();
+            @NetworkType int wwanPsRat =
+                    ServiceStateStats.getRat(state, NetworkRegistrationInfo.DOMAIN_PS);
+            if (imsVoiceRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+                // If IMS is registered over WWAN but WWAN PS is not in service,
+                // fallback to WWAN CS RAT
+                boolean isImsVoiceRatValid =
+                        (imsVoiceRat == TelephonyManager.NETWORK_TYPE_IWLAN
+                                || wwanPsRat != TelephonyManager.NETWORK_TYPE_UNKNOWN);
+                if (isImsVoiceRatValid) {
+                    // Fix for VoNR and EPSFB, b/277906557
+                    @NetworkType int oldRat = ServiceStateStats.getVoiceRat(phone, state, bearer),
+                            rat = imsVoiceRat == TelephonyManager.NETWORK_TYPE_IWLAN
+                                    ? imsVoiceRat : wwanPsRat;
+                    logd("getVoiceRatWithVoNRFix: oldRat=%d, newRat=%d", oldRat, rat);
+                    return rat;
+                }
+            }
+        }
+        if (bearer == VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS) {
+            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        } else {
+            return ServiceStateStats.getRat(state, NetworkRegistrationInfo.DOMAIN_CS);
+        }
+    }
+
     /** Resets the list of codecs used for the connection with only the codec currently in use. */
     private void resetCodecList(Connection conn) {
         int id = getConnectionId(conn);
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 087aee6..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,
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
index d7b5725..b917698 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
@@ -1200,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
@@ -1243,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(
@@ -1261,7 +1241,7 @@
                 + " wifiCallingModeForRoaming="
                 + ImsMmTelManager.wifiCallingModeToString(mWifiCallingModeForRoaming)
                 + " enabledMobileDataPolicies=" + mEnabledMobileDataPolicies
-                + " imsi=" + givePrintableId(mImsi)
+                + " imsi=" + SubscriptionInfo.getPrintableId(mImsi)
                 + " rcsUceEnabled=" + mIsRcsUceEnabled
                 + " crossSimCallingEnabled=" + mIsCrossSimCallingEnabled
                 + " rcsConfig=" + IccUtils.bytesToHexString(mRcsConfig)
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 2765ca4..c56ee04 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -46,6 +46,7 @@
 import android.os.RemoteException;
 import android.os.TelephonyServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Telephony.SimInfo;
 import android.service.carrier.CarrierIdentifier;
@@ -90,7 +91,6 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ProxyController;
 import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.data.PhoneSwitcher;
@@ -548,7 +548,6 @@
         });
 
         SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
-        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
 
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
@@ -997,8 +996,7 @@
 
         int subId = mSubscriptionDatabaseManager.insertSubscriptionInfo(builder.build());
         logl("insertSubscriptionInfo: Inserted a new subscription. subId=" + subId
-                + ", slotIndex=" + slotIndex + ", iccId="
-                + SubscriptionInfo.givePrintableIccid(iccId)
+                + ", slotIndex=" + slotIndex + ", iccId=" + SubscriptionInfo.getPrintableId(iccId)
                 + ", displayName=" + displayName + ", type="
                 + SubscriptionManager.subscriptionTypeToString(subscriptionType));
         return subId;
@@ -1089,9 +1087,11 @@
                     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());
@@ -1159,11 +1159,14 @@
             } 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();
-        }
     }
 
     /**
@@ -1274,7 +1277,7 @@
                 + TelephonyManager.simStateToString(simState));
         for (UiccSlot slot : mUiccController.getUiccSlots()) {
             if (slot != null) {
-                log("  " + slot.toString());
+                log("  " + slot);
             }
         }
 
@@ -1309,16 +1312,13 @@
                 log("updateSubscription: SIM_STATE_NOT_READY is not a final state. Will update "
                         + "subscription later.");
                 return;
-            }
-
-            if (!areUiccAppsEnabledOnCard(phoneId)) {
+            } else {
                 logl("updateSubscription: UICC app disabled on slot " + phoneId);
                 markSubscriptionsInactive(phoneId);
             }
         } else {
-
             String iccId = getIccId(phoneId);
-            log("updateSubscription: Found iccId=" + SubscriptionInfo.givePrintableIccid(iccId)
+            log("updateSubscription: Found iccId=" + SubscriptionInfo.getPrintableId(iccId)
                     + " on phone " + phoneId);
 
             // For eSIM switching, SIM absent will not happen. Below is to exam if we find ICCID
@@ -1953,7 +1953,6 @@
      * @see SubscriptionManager#requestEmbeddedSubscriptionInfoListRefresh
      */
     @Override
-    // TODO: Remove this after SubscriptionController is removed.
     public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
         updateEmbeddedSubscriptions(List.of(cardId), null);
     }
@@ -1975,7 +1974,7 @@
     public int addSubInfo(@NonNull String iccId, @NonNull String displayName, int slotIndex,
             @SubscriptionType int subscriptionType) {
         enforcePermissions("addSubInfo", Manifest.permission.MODIFY_PHONE_STATE);
-        logl("addSubInfo: iccId=" + SubscriptionInfo.givePrintableIccid(iccId) + ", slotIndex="
+        logl("addSubInfo: iccId=" + SubscriptionInfo.getPrintableId(iccId) + ", slotIndex="
                 + slotIndex + ", displayName=" + displayName + ", type="
                 + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
                 + getCallingPackage());
@@ -2022,18 +2021,17 @@
      * 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.givePrintableIccid(uniqueId) + ", "
+        logl("removeSubInfo: uniqueId=" + SubscriptionInfo.getPrintableId(uniqueId) + ", "
                 + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", "
                 + getCallingPackage());
         final long identity = Binder.clearCallingIdentity();
@@ -2042,15 +2040,15 @@
                     .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);
         }
@@ -2956,9 +2954,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.
@@ -2968,7 +2963,7 @@
      */
     @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);
 
@@ -2989,7 +2984,6 @@
             }
 
             mSubscriptionDatabaseManager.setSubscriptionProperty(subId, columnName, value);
-            return 1;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -3579,12 +3573,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
@@ -3595,6 +3583,7 @@
             }
 
             UserHandle userHandle = UserHandle.of(subInfo.getUserId());
+            logv("getSubscriptionUserHandle subId = " + subId + " userHandle = " + userHandle);
             if (userHandle.getIdentifier() == UserHandle.USER_NULL) {
                 return null;
             }
@@ -3614,7 +3603,6 @@
      * 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
@@ -3632,6 +3620,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);
@@ -3661,7 +3656,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
@@ -3692,6 +3686,15 @@
                 }
             }
 
+            UserManager userManager = mContext.getSystemService(UserManager.class);
+            if ((userManager != null)
+                    && (userManager.isManagedProfile(userHandle.getIdentifier()))) {
+                // For work profile, return subscriptions associated only with work profile
+                return subscriptionsAssociatedWithUser;
+            }
+
+            // For all other profiles, if subscriptionsAssociatedWithUser is empty return all the
+            // subscriptionsWithNoAssociation.
             return subscriptionsAssociatedWithUser.isEmpty() ?
                     subscriptionsWithNoAssociation : subscriptionsAssociatedWithUser;
         } finally {
@@ -3700,16 +3703,6 @@
     }
 
     /**
-     * @return {@code true} if using {@link SubscriptionManagerService} instead of
-     * {@link SubscriptionController}.
-     */
-    //TODO: Removed before U AOSP public release.
-    @Override
-    public boolean isSubscriptionManagerServiceEnabled() {
-        return true;
-    }
-
-    /**
      * 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
@@ -3817,7 +3810,7 @@
     public void updateSimStateForInactivePort(int slotIndex, @NonNull String iccId) {
         mHandler.post(() -> {
             logl("updateSimStateForInactivePort: slotIndex=" + slotIndex + ", iccId="
-                    + SubscriptionInfo.givePrintableIccid(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)
@@ -3973,6 +3966,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
@@ -3981,79 +3983,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("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 + ": " + getIccId(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.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);
     }
 }
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 8623f0a..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;
@@ -722,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) {
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 9959d9b..fe19e99 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -60,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)
@@ -268,7 +271,7 @@
                 loge("Bogus facility lock response");
             }
             if (mIccFdnEnabled && mIccFdnAvailable) {
-                ((SIMRecords) mIccRecords).loadFdnRecords();
+                mIccRecords.loadFdnRecords();
             }
         }
     }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index ec4a51b..596ccf6 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -427,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");
@@ -484,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;
@@ -519,7 +519,7 @@
                     }
                 }
 
-                mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage(
+                mUiccProfile.iccCloseLogicalChannel(mChannelId, false /*isEs10*/, obtainMessage(
                         EVENT_CLOSE_LOGICAL_CHANNEL_DONE, 0, mAIDInUse));
                 mChannelId = -1;
                 break;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 6de9a65..9456467 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.
      *
@@ -989,7 +959,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;
             }
 
@@ -1061,10 +1031,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;
         }
@@ -1095,6 +1065,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) {
@@ -1756,6 +1734,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) {
@@ -1777,35 +1767,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 ad00066..d89eab1 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPort.java
@@ -217,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!");
         }
@@ -231,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!");
         }
@@ -365,7 +365,7 @@
         pw.increaseIndent();
         pw.println("mPortIdx=" + mPortIdx);
         pw.println("mCi=" + mCi);
-        pw.println("mIccid=" + SubscriptionInfo.givePrintableIccid(mIccid));
+        pw.println("mIccid=" + SubscriptionInfo.getPrintableId(mIccid));
         pw.println("mPhoneId=" + mPhoneId);
         pw.println("mPhysicalSlotIndex=" + mPhysicalSlotIndex);
         synchronized (mOpenChannelRecords) {
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 5809ff9..83db022 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -63,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;
@@ -81,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;
 
@@ -544,25 +544,15 @@
         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;
@@ -573,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);
         }
     }
 
@@ -836,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));
         }
     }
 
@@ -1443,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);
@@ -1473,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");
@@ -1633,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));
     }
 
@@ -1643,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));
     }
 
     /**
@@ -1739,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 =
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 fc74d29..698fbc8 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -29,6 +29,7 @@
 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;
@@ -45,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();
@@ -57,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());
             }
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/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 d2d8d96..f729b80 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
@@ -102,7 +102,6 @@
         super.setUp(getClass().getSimpleName());
 
         doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
-
         mBundle = mContextFixture.getCarrierConfigBundle();
         mSstHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
         mSstHandler.start();
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 b62d5f9..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.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,8 +1092,6 @@
                 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());
@@ -1064,7 +1099,6 @@
         // 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());
 
@@ -1087,7 +1121,6 @@
         assertEquals(true, mPhoneUT.getCallForwardingIndicator());
 
         // check for another subId
-        doReturn(subId2).when(mSubscriptionController).getSubId(anyInt());
         doReturn(subId2).when(mSubscriptionManagerService).getSubId(anyInt());
         assertEquals(false, mPhoneUT.getCallForwardingIndicator());
 
@@ -1097,7 +1130,6 @@
         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());
 
@@ -1260,7 +1292,6 @@
         processAllMessages();
 
         verify(mSubscriptionManagerService, never()).getAllSubInfoList(anyString(), anyString());
-        verify(mSubscriptionController, never()).getSubInfoForIccId(any());
 
         // Have IccId defined. But expected value and current value are the same. So no RIL command
         // should be sent.
@@ -1268,12 +1299,8 @@
         doReturn(iccId).when(mUiccSlot).getIccId(anyInt());
         Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
         processAllMessages();
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).getAllSubInfoList(anyString(),
-                    nullable(String.class));
-        } else {
-            verify(mSubscriptionController).getSubInfoForIccId(iccId);
-        }
+        verify(mSubscriptionManagerService).getAllSubInfoList(anyString(),
+                nullable(String.class));
         verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
     }
 
@@ -1309,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
@@ -1321,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
@@ -1442,8 +1470,6 @@
 
     @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());
 
@@ -1514,11 +1540,8 @@
     @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());
 
@@ -1531,11 +1554,8 @@
     @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);
@@ -1545,6 +1565,83 @@
         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.
@@ -1625,7 +1722,7 @@
 
         doReturn(true).when(mTelephonyManager).isEmergencyNumber(anyString());
         doReturn(isEmergencyPerDialedSim).when(mEmergencyNumberTracker).isEmergencyNumber(
-                anyString(), anyBoolean());
+                anyString());
 
         mPhoneUT.setImsPhone(mImsPhone);
     }
@@ -1706,8 +1803,6 @@
         final SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
                 false, SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
 
-        doReturn(si.toSubscriptionInfo()).when(mSubscriptionController)
-                .getSubscriptionInfo(anyInt());
         doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
@@ -1731,8 +1826,6 @@
 
         final SubscriptionInfoInternal si = makeSubscriptionInfoInternal(
                 true, SubscriptionManager.USAGE_SETTING_DEFAULT);
-        doReturn(si.toSubscriptionInfo()).when(mSubscriptionController)
-                .getSubscriptionInfo(anyInt());
         doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
@@ -1758,8 +1851,6 @@
                 false, SubscriptionManager.USAGE_SETTING_DEFAULT);
 
         assertNotNull(si);
-        doReturn(si.toSubscriptionInfo()).when(mSubscriptionController)
-                .getSubscriptionInfo(anyInt());
         doReturn(si).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
         mPhoneUT.updateUsageSetting();
@@ -2069,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();
@@ -2097,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());
         }
 
@@ -2105,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 29b128d..4012e98 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
@@ -22,6 +22,7 @@
 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;
@@ -33,6 +34,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -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 372733d..f4c19d9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -136,6 +136,7 @@
         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);
@@ -144,7 +145,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        enableSubscriptionManagerService(true);
         initializeSubs();
         mPhoneMock1 = mock(Phone.class);
         mPhoneMock2 = mock(Phone.class);
@@ -156,6 +156,9 @@
         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.
@@ -243,12 +246,10 @@
         }).when(mPhoneMock2).getSubId();
 
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
-
         // Capture listener to emulate the carrier config change notification used later
         ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
                 ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-        mMultiSimSettingControllerUT = new MultiSimSettingController(mContext,
-                mSubscriptionController);
+        mMultiSimSettingControllerUT = new MultiSimSettingController(mContext);
         processAllMessages();
         verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
                 listenerArgumentCaptor.capture());
@@ -463,15 +464,15 @@
         markSubscriptionInactive(1);
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         processAllMessages();
+        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());
 
-        sendCarrierConfigChanged(1, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        processAllMessages();
-
         // Verify intent sent to select sub 2 as default for all types.
         Intent intent = captureBroadcastIntent();
         assertEquals(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED, intent.getAction());
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 2b487f2..e171a5e 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,9 +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);
         mBundle.putInt(CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         replaceInstance(Handler.class, "mLooper", mDisplayInfoController, Looper.myLooper());
         doReturn(RadioAccessFamily.getRafFromNetworkType(
@@ -115,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
@@ -234,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());
@@ -259,8 +247,7 @@
     @Test
     public void testTransitionToCurrentStateLegacy() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+        mNetworkTypeController.sendMessage(3 /* EVENT_SERVICE_STATE_CHANGED */);
         processAllMessages();
         assertEquals("legacy", getCurrentState().getName());
     }
@@ -269,8 +256,7 @@
     public void testTransitionToCurrentStateRestricted() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
         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());
     }
@@ -279,9 +265,9 @@
     public void testTransitionToCurrentStateIdle() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
         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());
     }
@@ -296,8 +282,8 @@
 
         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());
     }
@@ -309,17 +295,15 @@
         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(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());
     }
 
@@ -327,9 +311,9 @@
     public void testTransitionToCurrentStateLteConnected() throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
         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());
     }
@@ -340,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(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());
     }
@@ -360,17 +344,15 @@
         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(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());
     }
 
@@ -379,7 +361,7 @@
         assertEquals("DefaultState", getCurrentState().getName());
         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());
     }
@@ -390,7 +372,7 @@
         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());
     }
@@ -410,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());
     }
@@ -432,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());
     }
@@ -444,10 +428,9 @@
         assertEquals("DefaultState", getCurrentState().getName());
         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());
     }
@@ -459,9 +442,14 @@
         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());
     }
@@ -473,10 +461,14 @@
         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());
     }
@@ -488,11 +480,14 @@
         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());
     }
@@ -502,7 +497,7 @@
         testTransitionToCurrentStateLegacy();
         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());
     }
@@ -512,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());
     }
@@ -523,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());
     }
 
@@ -535,9 +529,8 @@
         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());
     }
 
@@ -545,12 +538,11 @@
     public void testNrPhysicalChannelChangeFromNrConnectedMmwaveToLteConnected() throws Exception {
         testTransitionToCurrentStateNrConnectedMmwave();
         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());
     }
 
@@ -564,15 +556,13 @@
         testTransitionToCurrentStateNrConnectedMmwave();
         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 {
@@ -581,14 +571,13 @@
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
         processAllMessages();
         testTransitionToCurrentStateNrConnectedMmwave();
         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());
@@ -603,7 +592,8 @@
 
         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());
@@ -615,13 +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(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,
@@ -630,7 +620,8 @@
         // 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());
@@ -642,13 +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(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,
@@ -657,7 +648,8 @@
         // 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,7 +659,7 @@
     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();
@@ -684,8 +676,8 @@
         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());
     }
@@ -698,11 +690,11 @@
         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();
@@ -715,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,
@@ -729,8 +721,7 @@
                 mNetworkTypeController.getOverrideNetworkType());
 
         doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-
-        mNetworkTypeController.sendMessage(EVENT_RADIO_OFF_OR_UNAVAILABLE);
+        mNetworkTypeController.sendMessage(9 /* EVENT_RADIO_OFF_OR_UNAVAILABLE */);
         processAllMessages();
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
@@ -747,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());
@@ -758,7 +749,7 @@
         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,
@@ -766,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);
@@ -781,7 +772,7 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -789,14 +780,14 @@
         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,
@@ -804,13 +795,13 @@
 
         // 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
@@ -818,7 +809,7 @@
         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,
@@ -826,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);
@@ -846,7 +837,7 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -854,7 +845,7 @@
         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,
@@ -868,14 +859,14 @@
         // 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
@@ -884,7 +875,7 @@
         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,
@@ -892,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);
@@ -907,7 +898,7 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -916,7 +907,7 @@
         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,
@@ -924,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);
@@ -944,7 +935,7 @@
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -954,7 +945,7 @@
                 "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,
@@ -962,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);
@@ -978,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);
@@ -987,7 +978,7 @@
         assertEquals("legacy", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -997,7 +988,7 @@
                 "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,
@@ -1005,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);
@@ -1021,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);
@@ -1035,7 +1026,7 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -1046,7 +1037,7 @@
                 "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,
@@ -1054,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);
@@ -1070,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);
@@ -1079,7 +1070,7 @@
         assertEquals("connected", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -1090,7 +1081,7 @@
                 "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,
@@ -1098,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);
@@ -1114,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);
@@ -1128,7 +1119,7 @@
         assertEquals("connected_mmwave", getCurrentState().getName());
         assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
                 mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
+        assertFalse(mNetworkTypeController.areAnyTimersActive());
     }
 
     @Test
@@ -1139,7 +1130,7 @@
                 "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,
@@ -1147,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()
@@ -1162,13 +1153,89 @@
                 .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());
+    }
+
+    @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) {
@@ -1195,9 +1262,9 @@
         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());
     }
@@ -1207,14 +1274,9 @@
         assertEquals("DefaultState", getCurrentState().getName());
         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();
@@ -1241,7 +1303,7 @@
         mBundle.putBoolean(
                 CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
                 true);
-        broadcastCarrierConfigs();
+        sendCarrierConfigChanged();
 
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
@@ -1255,9 +1317,9 @@
         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 bac1adb..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,17 +220,9 @@
 
         // Verify clearSubInfoRecord() and onSlotActiveStatusChange() are called for second phone,
         // and not for the first one
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).markSubscriptionsInactive(1);
-        } else {
-            verify(mSubscriptionController).clearSubInfoRecord(1);
-        }
+        verify(mSubscriptionManagerService).markSubscriptionsInactive(1);
         verify(mMockCi1).onSlotActiveStatusChange(anyBoolean());
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).markSubscriptionsInactive(0);
-        } else {
-            verify(mSubscriptionController, never()).clearSubInfoRecord(0);
-        }
+        verify(mSubscriptionManagerService, never()).markSubscriptionsInactive(0);
         verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
 
         // Verify onPhoneRemoved() gets called on MultiSimSettingController phone
@@ -240,12 +253,6 @@
         // setup mocks for  VOICE mSubscriptionManagerService. getter/setter
         doAnswer(invocation -> {
             Integer value = (Integer) invocation.getArguments()[0];
-            Mockito.when(mSubscriptionController.getDefaultVoiceSubId()).thenReturn(value);
-            return null;
-        }).when(mSubscriptionController).setDefaultVoiceSubId(anyInt());
-
-        doAnswer(invocation -> {
-            Integer value = (Integer) invocation.getArguments()[0];
             Mockito.when(mSubscriptionManagerService.getDefaultVoiceSubId()).thenReturn(value);
             return null;
         }).when(mSubscriptionManagerService).setDefaultVoiceSubId(anyInt());
@@ -254,30 +261,17 @@
         // start off the phone stat with 1 active sim. reset values for new test.
         init(1);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService.setDefaultVoiceSubId(startingDefaultSubscriptionId);
-            assertEquals(startingDefaultSubscriptionId,
-                    mSubscriptionManagerService.getDefaultVoiceSubId());
-        } else {
-            mSubscriptionController.setDefaultVoiceSubId(startingDefaultSubscriptionId);
-            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
-        if (isSubscriptionManagerServiceEnabled()) {
-            assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID /* No CALL Preference value */,
-                    mSubscriptionManagerService.getDefaultVoiceSubId());
-            // Now, when the user goes to place a CALL, they will be prompted on which sim to use.
-        } else {
-            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.
-        }
-
+        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID /* No CALL Preference value */,
+                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 b8fc609..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,22 +76,15 @@
         PropertyInvalidatedCache.disableForTestMode();
         /* mPhone -> PhoneId: 0 -> SubId:0
            mSecondPhone -> PhoneId:1 -> SubId: 1*/
-        doReturn(0).when(mSubscriptionController).getPhoneId(eq(0));
         doReturn(0).when(mSubscriptionManagerService).getPhoneId(eq(0));
-        doReturn(1).when(mSubscriptionController).getPhoneId(eq(1));
         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(mSubscriptionManagerService).isActiveSubId(0, TAG, FEATURE_ID);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(1, 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);
@@ -926,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 c0d497d..65ab664 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
@@ -19,10 +19,13 @@
 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;
@@ -97,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/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index fa48f97..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,6 +93,7 @@
 
 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;
@@ -106,6 +108,7 @@
 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;
@@ -263,7 +266,6 @@
 
         replaceInstance(ProxyController.class, "sProxyController", null, mProxyController);
         mBundle = mContextFixture.getCarrierConfigBundle();
-
         when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle);
         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
         mBundle.putStringArray(
@@ -276,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);
@@ -294,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,
@@ -358,6 +374,9 @@
                     15, /* SIGNAL_STRENGTH_GOOD */
                     30  /* SIGNAL_STRENGTH_GREAT */
                 });
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL,
+                true);
 
         sendCarrierConfigUpdate(PHONE_ID);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
@@ -487,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);
@@ -522,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);
@@ -850,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);
@@ -901,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
@@ -1083,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());
@@ -1207,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)
@@ -1215,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);
@@ -1317,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
@@ -1468,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(
@@ -1486,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);
@@ -1501,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);
@@ -1519,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);
@@ -1534,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);
@@ -1551,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);
@@ -1566,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);
@@ -1584,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);
@@ -2201,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
@@ -2222,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,
@@ -2250,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());
     }
 
     /**
@@ -2353,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);
@@ -2736,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
@@ -2771,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
@@ -3012,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();
@@ -3051,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 0391a81..e4617fe 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
@@ -18,7 +18,9 @@
 
 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;
 
@@ -27,6 +29,7 @@
 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;
@@ -110,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 */);
@@ -120,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 */);
@@ -130,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[] {
@@ -515,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(),
@@ -817,7 +1029,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);
         }
     }
@@ -864,4 +1076,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 2f8b1bb..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.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());
-        enableSubscriptionManagerService(false);
-        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();
-    }
-}
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 32fb56e..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ /dev/null
@@ -1,1123 +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.annotation.Nullable;
-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.Bundle;
-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);
-        }
-
-        @Override
-        public Bundle call(String method, @Nullable String args, @Nullable Bundle bundle) {
-            return new Bundle();
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        enableSubscriptionManagerService(false);
-        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 6bed1b6..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,17 @@
 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;
@@ -203,7 +208,6 @@
     protected GsmCdmaCall mGsmCdmaCall;
     protected ImsCall mImsCall;
     protected ImsEcbm mImsEcbm;
-    protected SubscriptionController mSubscriptionController;
     protected SubscriptionManagerService mSubscriptionManagerService;
     protected ServiceState mServiceState;
     protected IPackageManager.Stub mMockPackageManager;
@@ -232,6 +236,7 @@
     protected CarrierSignalAgent mCarrierSignalAgent;
     protected CarrierActionAgent mCarrierActionAgent;
     protected ImsExternalCallTracker mImsExternalCallTracker;
+    protected ImsNrSaModeHandler mImsNrSaModeHandler;
     protected AppSmsManager mAppSmsManager;
     protected IccSmsInterfaceManager mIccSmsInterfaceManager;
     protected SmsDispatchersController mSmsDispatchersController;
@@ -240,7 +245,6 @@
     protected IntentBroadcaster mIntentBroadcaster;
     protected NitzStateMachine mNitzStateMachine;
     protected RadioConfig mMockRadioConfig;
-    protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
     protected LocaleTracker mLocaleTracker;
     protected RestrictedState mRestrictedState;
     protected PhoneConfigurationManager mPhoneConfigurationManager;
@@ -266,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;
@@ -437,7 +444,6 @@
         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);
@@ -466,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);
@@ -474,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);
@@ -500,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();
@@ -525,7 +534,9 @@
 
         Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
 
-        enableSubscriptionManagerService(true);
+        mServiceManagerMockedServices.put("isub", mSubscriptionManagerService);
+        doReturn(mSubscriptionManagerService).when(mSubscriptionManagerService)
+                .queryLocalInterface(anyString());
 
         mPhone.mCi = mSimulatedCommands;
         mCT.mCi = mSimulatedCommands;
@@ -585,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)
@@ -716,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());
@@ -725,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);
@@ -734,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
@@ -815,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);
@@ -822,7 +845,6 @@
                 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);
@@ -843,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);
@@ -851,15 +872,10 @@
                 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);
-
-        if (!isSubscriptionManagerServiceEnabled()) {
-            assertNotNull("Failed to set up SubscriptionController singleton",
-                    SubscriptionController.getInstance());
-        }
+        replaceInstance(SatelliteController.class, "sInstance", null, mSatelliteController);
 
         setReady(false);
         // create default TestableLooper for test and add to list of monitored loopers
@@ -958,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");
@@ -977,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);
             }
@@ -1261,22 +1292,4 @@
             }
         }
     }
-
-    protected void enableSubscriptionManagerService(boolean enabled) throws Exception {
-        if (enabled) {
-            mServiceManagerMockedServices.put("isub", mSubscriptionManagerService);
-            doReturn(mSubscriptionManagerService).when(mIBinder)
-                    .queryLocalInterface(anyString());
-        }
-        replaceInstance(PhoneFactory.class, "sSubscriptionManagerServiceEnabled", null, enabled);
-        mContextFixture.putBooleanResource(com.android.internal.R.bool
-                .config_using_subscription_manager_service, enabled);
-        doReturn(enabled).when(mPhone).isSubscriptionManagerServiceEnabled();
-        doReturn(enabled).when(mPhone2).isSubscriptionManagerServiceEnabled();
-        doReturn(enabled).when(mImsPhone).isSubscriptionManagerServiceEnabled();
-    }
-
-    protected boolean isSubscriptionManagerServiceEnabled() {
-        return mPhone.isSubscriptionManagerServiceEnabled();
-    }
 }
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 b36a8d4..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;
@@ -33,8 +32,10 @@
 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;
@@ -120,7 +121,7 @@
         processAllMessages();
         replaceInstance(AccessNetworksManager.class, "mDataConfigManager",
                 mAccessNetworksManager, mMockedDataConfigManager);
-        assumeFalse(mAccessNetworksManager.isInLegacyMode());
+
         logd("-setUp");
     }
 
@@ -158,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 76a3d0a..428699f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
@@ -77,7 +77,6 @@
         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();
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 d8b93f5..808a15d 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;
 
@@ -142,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;
@@ -228,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)
@@ -319,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)
@@ -516,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);
@@ -548,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();
@@ -725,20 +771,12 @@
         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(0).when(mSubscriptionManagerService).getPhoneId(1);
-        doReturn(1).when(mSubscriptionController).getPhoneId(2);
         doReturn(1).when(mSubscriptionManagerService).getPhoneId(2);
 
         for (int transport : new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
@@ -830,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);
 
@@ -883,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();
@@ -897,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))
@@ -1257,12 +1295,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
@@ -1271,7 +1311,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();
 
@@ -1425,7 +1465,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
@@ -1480,7 +1521,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.
@@ -1585,9 +1626,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);
 
@@ -1637,6 +1676,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);
@@ -1673,7 +1720,6 @@
     @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(
@@ -1716,7 +1762,6 @@
         // 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
@@ -1746,9 +1791,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
@@ -1939,7 +1995,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();
@@ -1961,7 +2017,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*/);
@@ -1981,7 +2037,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();
@@ -2005,7 +2061,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*/);
@@ -2100,7 +2156,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();
 
@@ -2120,7 +2176,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();
 
@@ -2284,6 +2340,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();
@@ -2344,6 +2402,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),
@@ -2455,6 +2515,7 @@
     public void testHandoverDataNetworkRetryReachedMaximum() throws Exception {
         testSetupImsDataNetwork();
 
+        // 1. Normal case
         setFailedSetupDataResponse(mMockedWlanDataServiceManager,
                 DataFailCause.HANDOVER_FAILED, -1, true);
         updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
@@ -2475,6 +2536,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
@@ -2625,8 +2710,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));
     }
@@ -2776,7 +2862,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.
@@ -2799,8 +2885,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(
@@ -2881,6 +2967,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();
@@ -2893,7 +3008,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.
@@ -3115,6 +3230,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(
@@ -3181,9 +3363,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);
 
@@ -3203,9 +3389,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);
 
@@ -3216,9 +3406,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);
 
@@ -3398,11 +3592,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(
@@ -3574,38 +3768,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(),
@@ -3613,7 +3832,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();
     }
 
@@ -3685,9 +3904,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)
@@ -3748,9 +3971,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)
@@ -3808,9 +4035,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)
@@ -3876,9 +4107,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)
@@ -3923,9 +4158,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)
@@ -3961,7 +4200,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();
 
@@ -3977,9 +4216,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);
 
@@ -3991,9 +4234,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);
 
@@ -4003,7 +4250,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);
@@ -4019,16 +4266,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 1650148..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);
@@ -1366,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();
@@ -1376,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);
@@ -1754,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 7a1aeca..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;
@@ -64,9 +63,6 @@
         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());
 
@@ -108,13 +104,8 @@
         processAllMessages();
 
         ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, times(2))
-                    .setEnabledMobileDataPolicies(anyInt(), stringArgumentCaptor.capture());
-        } else {
-            verify(mSubscriptionController, times(2))
-                    .setEnabledMobileDataPolicies(anyInt(), stringArgumentCaptor.capture());
-        }
+        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 f0a73a9..bc691f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -199,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);
@@ -305,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
@@ -349,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
@@ -562,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.
@@ -590,10 +590,9 @@
 
     @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.
@@ -603,37 +602,59 @@
         setDefaultDataSubId(1);
 
         testAutoSwitchToSecondarySucceed();
-        clearInvocations(mSubscriptionController);
         clearInvocations(mSubscriptionManagerService);
         Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1, null,  null))
                 .sendToTarget();
         processAllMessages();
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).getSubscriptionInfo(2);
-        } else {
-            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();
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).getSubscriptionInfo(1);
-        } else {
-            verify(mSubscriptionController, never()).getSubscriptionInfo(1);
-        }
+        verify(mSubscriptionManagerService, never()).getSubscriptionInfo(1);
 
         Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, new AsyncResult(1, null,  null))
                 .sendToTarget();
         processAllMessages();
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).getSubscriptionInfo(2);
-        } else {
-            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
     }
 
     /**
@@ -732,7 +753,6 @@
         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);
@@ -779,7 +799,6 @@
         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);
 
@@ -836,7 +855,6 @@
         setDefaultDataSubId(1);
 
         clearInvocations(mCellularNetworkValidator);
-        doReturn(new int[1]).when(mSubscriptionController).getActiveSubIdList(true);
         doReturn(new int[1]).when(mSubscriptionManagerService).getActiveSubIdList(true);
         prepareIdealAutoSwitchCondition();
         processAllFutureMessages();
@@ -890,7 +908,6 @@
                 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);
@@ -952,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.
@@ -1514,8 +1529,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.
@@ -1677,7 +1690,6 @@
         setAllPhonesInactive();
         // Initialization done.
 
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
         doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
                 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
                 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
@@ -1719,7 +1731,6 @@
         setAllPhonesInactive();
         // Initialization done.
 
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
         doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
                 .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
                 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
@@ -1770,8 +1781,6 @@
         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();
@@ -1795,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() {
@@ -1962,9 +2001,9 @@
         initializeCommandInterfacesMock();
         initializeTelRegistryMock();
         initializeConnManagerMock();
+        initializeConfigMock();
 
         mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper());
-        processAllMessages();
 
         Field field = PhoneSwitcher.class.getDeclaredField("mDataSettingsManagerCallbacks");
         field.setAccessible(true);
@@ -1972,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());
     }
@@ -2068,25 +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];
@@ -2113,17 +2135,6 @@
         doAnswer(invocation -> {
             int subId = (int) invocation.getArguments()[0];
 
-            if (!SubscriptionManager.isUsableSubIdValue(subId)) return false;
-
-            for (int i = 0; i < mSlotIndexToSubId.length; i++) {
-                if (mSlotIndexToSubId[i][0] == subId) return true;
-            }
-            return false;
-        }).when(mSubscriptionController).isActiveSubId(anyInt());
-
-        doAnswer(invocation -> {
-            int subId = (int) invocation.getArguments()[0];
-
             if (!SubscriptionManager.isUsableSubIdValue(subId)) return null;
 
             int slotIndex = -1;
@@ -2134,15 +2145,21 @@
                     .setSimSlotIndex(slotIndex).setId(subId).build();
         }).when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
 
-        doReturn(new int[mSlotIndexToSubId.length]).when(mSubscriptionController)
-                .getActiveSubIdList(true);
         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(mSubscriptionManagerService).getDefaultDataSubId();
         if (defaultDataSub == 1) {
             doReturn(true).when(mPhone).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 0e0bda8..c47eb3b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
@@ -20,27 +20,38 @@
 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;
@@ -49,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;
@@ -74,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";
@@ -102,7 +116,7 @@
     private static final int INVALID_SLOT_INDEX_VALID = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
     private ParcelFileDescriptor mOtaParcelFileDescriptor = null;
     // Mocked classes
-    private SubscriptionController mSubControllerMock;
+    private CarrierConfigManager mCarrierConfigManagerMock;
 
     // mEmergencyNumberTrackerMock for mPhone
     private EmergencyNumberTracker mEmergencyNumberTrackerMock;
@@ -115,14 +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);
-        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();
@@ -141,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!");
     }
@@ -181,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() {
@@ -267,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);
     }
@@ -297,13 +332,6 @@
     @Test
     public void testIsSimAbsent() throws Exception {
         setDsdsPhones();
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubControllerMock);
-
-        // Both sim slots are active
-        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-        doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
         doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
                 eq(SUB_ID_PHONE_1));
         doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubscriptionManagerService).getSlotIndex(
@@ -311,10 +339,6 @@
         assertFalse(mEmergencyNumberTrackerMock.isSimAbsent());
 
         // One sim slot is active; the other one is not active
-        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
         doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubscriptionManagerService).getSlotIndex(
                 eq(SUB_ID_PHONE_1));
         doReturn(INVALID_SLOT_INDEX_VALID).when(mSubscriptionManagerService).getSlotIndex(
@@ -322,10 +346,6 @@
         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());
@@ -339,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");
@@ -347,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
@@ -376,18 +435,9 @@
 
     @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());
@@ -399,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");
@@ -416,30 +466,17 @@
     }
 
     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(
@@ -455,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());
@@ -495,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()));
     }
 
     /**
@@ -534,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();
@@ -597,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 7da20d8..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,20 +565,16 @@
         doReturn(mIsimUiccRecords).when(mPhone).getIccRecords();
         Message msg = mGsmSmsDispatcher.obtainMessage(17);
         mPhone.getIccRecords().setSmssTpmrValue(-1, msg);
-        if (isSubscriptionManagerServiceEnabled()) {
-            mSubscriptionManagerService.setLastUsedTPMessageReference(mPhone.getSubId(), -1);
-        } else {
-            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
@@ -571,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 906709a..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;
 
@@ -57,17 +74,20 @@
 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;
@@ -75,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;
@@ -90,15 +113,19 @@
 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;
 
@@ -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,8 @@
     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;
@@ -201,11 +234,13 @@
         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());
@@ -244,6 +279,9 @@
             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);
@@ -357,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();
@@ -382,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);
 
@@ -409,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
@@ -429,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);
 
@@ -450,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
@@ -474,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);
 
@@ -542,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());
@@ -694,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();
@@ -732,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();
@@ -924,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();
@@ -1397,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(
@@ -1439,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).
@@ -1589,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]);
     }
 
@@ -1699,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());
     }
@@ -1730,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());
     }
@@ -1742,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());
@@ -1753,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
@@ -1780,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());
@@ -1791,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.
@@ -1807,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);
@@ -1838,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);
@@ -1868,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;
@@ -1902,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.
@@ -1936,6 +2039,608 @@
         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() {
         mCarrierConfigChangeListener.onCarrierConfigChanged(mPhone.getPhoneId(), mPhone.getSubId(),
                 TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
@@ -2009,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 3c4c65d..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,14 +17,23 @@
 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;
@@ -66,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;
@@ -85,6 +95,7 @@
 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;
@@ -110,6 +121,7 @@
     private ImsPhoneCall mBackgroundCall;
     private ImsPhoneCall mRingingCall;
     private Handler mTestHandler;
+    private DomainSelectionResolver mDomainSelectionResolver;
     Connection mConnection;
     ImsUtInterface mImsUtInterface;
 
@@ -135,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;
@@ -178,6 +193,7 @@
     public void tearDown() throws Exception {
         mImsPhoneUT = null;
         mBundle = null;
+        DomainSelectionResolver.setDomainSelectionResolver(null);
         super.tearDown();
     }
 
@@ -631,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,
@@ -736,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();
 
@@ -764,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();
 
@@ -788,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());
@@ -1018,7 +970,6 @@
         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);
@@ -1030,12 +981,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539447777");
-        } else {
-            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[] {
@@ -1044,12 +990,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539446666");
-        } else {
-            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[] {
@@ -1059,12 +1000,7 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539446677");
-        } else {
-            verify(mSubscriptionController).setSubscriptionProperty(
-                    subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446677");
-        }
+        verify(mSubscriptionManagerService).setNumberFromIms(subId, "+447539446677");
 
         // Clean up
         mContextFixture.addCallingOrSelfPermission("");
@@ -1079,7 +1015,6 @@
         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);
@@ -1091,49 +1026,367 @@
         };
         mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
-        } else {
-            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);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
-        } else {
-            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);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
-        } else {
-            verify(mSubscriptionController, never()).setSubscriptionProperty(
-                    anyInt(), any(), any());
-        }
+        verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
 
         // 4. null pointer; do not set
         mImsPhoneUT.setPhoneNumberForSourceIms(null);
 
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mSubscriptionManagerService, never()).setNumberFromIms(anyInt(), anyString());
-        } else {
-            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 10151b8..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,7 +43,6 @@
 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;
@@ -84,26 +83,16 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("6506953210")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        doReturn("+16506953210")
                 .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);
@@ -133,32 +122,23 @@
         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)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("0123")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(2, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("16506950123")
-                .when(mSubscriptionController)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("16506950123")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(2, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506950123")
-                .when(mSubscriptionController)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_IMS, null, null);
-        doReturn("+16506950123")
                 .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);
@@ -210,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);
@@ -228,12 +209,12 @@
                 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);
@@ -248,26 +229,16 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("6506953210")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        doReturn("+16506953210")
                 .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);
@@ -286,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);
 
@@ -306,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
@@ -315,26 +288,16 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("6506953210")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        doReturn("+16506953210")
                 .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);
@@ -355,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);
 
@@ -375,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
@@ -384,26 +349,16 @@
         doReturn(1).when(mPhone).getSubId();
         doReturn(100).when(mPhone).getCarrierId();
         doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("6506953210")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
         doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("")
                 .when(mSubscriptionManagerService)
                 .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
         doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        doReturn("+16506953210")
                 .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);
@@ -420,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);
 
@@ -440,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 9e418d5..9898353 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
@@ -1226,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
@@ -1247,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
@@ -1363,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();
     }
 
 
@@ -1613,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
@@ -1635,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
@@ -1736,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
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 d61a57f..e03256b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
@@ -218,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 22e1067..cae9626 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -60,7 +60,6 @@
 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;
@@ -72,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;
@@ -161,7 +159,6 @@
     public void setUp() throws Exception {
         logd("SubscriptionManagerServiceTest +Setup!");
         super.setUp(getClass().getSimpleName());
-        enableSubscriptionManagerService(true);
 
         // Dual-SIM configuration
         mPhones = new Phone[] {mPhone, mPhone2};
@@ -195,6 +192,7 @@
 
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 Telephony.Carriers.CONTENT_URI.getAuthority(), mSubscriptionProvider);
+
         mSubscriptionManagerServiceUT = new SubscriptionManagerService(mContext, Looper.myLooper());
 
         monitorTestableLooper(new TestableLooper(getBackgroundHandler().getLooper()));
@@ -302,13 +300,6 @@
         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);
@@ -1057,7 +1048,6 @@
     @Test
     public void testSetGetSubscriptionUserHandle() {
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
-        enableGetSubscriptionUserHandle();
 
         // Should fail without MANAGE_SUBSCRIPTION_USER_ASSOCIATION
         assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
@@ -1091,7 +1081,6 @@
     @Test
     public void testIsSubscriptionAssociatedWithUser() {
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
-        enableGetSubscriptionUserHandle();
 
         // Should fail without MANAGE_SUBSCRIPTION_USER_ASSOCIATION
         assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
@@ -1810,9 +1799,9 @@
 
         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(
@@ -2157,8 +2146,13 @@
         insertSubscription(FAKE_SUBSCRIPTION_INFO1);
         insertSubscription(FAKE_SUBSCRIPTION_INFO2);
 
-        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         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);
@@ -2248,7 +2242,7 @@
                 SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
 
         assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_MAC_ADDRESS1,
-                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(0);
+                SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(true);
         assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(
                 CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
         assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
@@ -2363,6 +2357,19 @@
     }
 
     @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);
 
@@ -2438,4 +2445,62 @@
         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/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 4a3d4cf..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;
@@ -227,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)
         );
     }
 
@@ -577,8 +577,6 @@
 
         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());
@@ -587,8 +585,6 @@
                 .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());
@@ -607,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 6846b94..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,12 +158,7 @@
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
-        } else {
-            verify(mSubInfoRecordUpdater).updateInternalIccState(
-                    IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
-        }
+        verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
     }
 
     @Test
@@ -384,12 +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);
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
-        } else {
-            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());
     }
@@ -422,15 +412,9 @@
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
 
         // assert that we tried to update subscriptions
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimStateForInactivePort(
-                    activeIss.mSimPortInfos[0].mLogicalSlotIndex,
-                    inactiveIss.mSimPortInfos[0].mIccId);
-        } else {
-            verify(mSubInfoRecordUpdater).updateInternalIccStateForInactivePort(
-                    activeIss.mSimPortInfos[0].mLogicalSlotIndex,
-                    inactiveIss.mSimPortInfos[0].mIccId);
-        }
+        verify(mUiccController).updateSimStateForInactivePort(
+                activeIss.mSimPortInfos[0].mLogicalSlotIndex,
+                inactiveIss.mSimPortInfos[0].mIccId);
     }
 
     @Test
@@ -449,16 +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);
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
-        } else {
-            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());
@@ -481,13 +459,7 @@
         // radio state unavailable
         mUiccSlot.onRadioStateUnavailable(phoneId);
 
-        // Verify that UNKNOWN state is sent to SubscriptionInfoUpdater in this case.
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.UNKNOWN, null);
-        } else {
-            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());
 
@@ -495,13 +467,7 @@
         mIccCardStatus.mCardState = CardState.CARDSTATE_ABSENT;
         mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
 
-        // Verify that ABSENT state is sent to SubscriptionInfoUpdater in this case.
-        if (isSubscriptionManagerServiceEnabled()) {
-            verify(mUiccController).updateSimState(phoneId, IccCardConstants.State.ABSENT, null);
-        } else {
-            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());
     }
@@ -538,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) {
