Merge "Check WWAN is in service before exiting hysteresis timeout." into main
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 68fd6ab..82b4c2b8e 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -33,6 +33,7 @@
 
 import com.android.ims.internal.ConferenceParticipant;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
@@ -634,7 +635,7 @@
      *
      * @hide
      */
-    public void setEmergencyCallInfo(CallTracker ct) {
+    public void setEmergencyCallInfo(CallTracker ct, Phone.DialArgs dialArgs) {
         if (ct != null) {
             Phone currentPhone = ct.getPhone();
             if (currentPhone != null) {
@@ -677,20 +678,52 @@
         } else {
             Rlog.e(TAG, "setEmergencyCallInfo: call tracker is null");
         }
+
+        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+            if (mEmergencyNumberInfo == null) {
+                Rlog.d(TAG, "setEmergencyCallInfo: create EmergencyNumber");
+                setNonDetectableEmergencyCallInfo((dialArgs != null) ? dialArgs.eccCategory
+                        : EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                        new ArrayList<String>());
+            }
+            if (dialArgs != null && dialArgs.intentExtras != null
+                    && dialArgs.intentExtras.getBoolean(
+                            PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, false)
+                    && mEmergencyNumberInfo.getEmergencyCallRouting()
+                        != EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY) {
+                int eccCategory = dialArgs.intentExtras.getInt(
+                        PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                        mEmergencyNumberInfo.getEmergencyServiceCategoryBitmask());
+                Rlog.d(TAG, "setEmergencyCallInfo: enforce emergency routing eccCategory="
+                        + eccCategory);
+                List<String> emergencyUrns = dialArgs.intentExtras.getStringArrayList(
+                        PhoneConstants.EXTRA_EMERGENCY_URNS);
+                if (emergencyUrns == null || emergencyUrns.isEmpty()) {
+                    emergencyUrns = mEmergencyNumberInfo.getEmergencyUrns();
+                }
+                mEmergencyNumberInfo = new EmergencyNumber(mEmergencyNumberInfo.getNumber(),
+                        mEmergencyNumberInfo.getCountryIso(),
+                        mEmergencyNumberInfo.getMnc(),
+                        eccCategory,
+                        emergencyUrns,
+                        mEmergencyNumberInfo.getEmergencyNumberSourceBitmask(),
+                        EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+            }
+        }
     }
 
     /**
      * Set the non-detectable emergency number information.
      */
-    public void setNonDetectableEmergencyCallInfo(int eccCategory) {
-        if (!mIsEmergencyCall) {
-            mIsEmergencyCall = true;
-            mEmergencyNumberInfo = new EmergencyNumber(mAddress, ""/*countryIso*/,
-                                    ""/*mnc*/, eccCategory,
-                                    new ArrayList<String>(),
-                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
-                                    EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
-        }
+    public void setNonDetectableEmergencyCallInfo(int eccCategory,
+            @NonNull List<String> emergencyUrns) {
+        Rlog.d(TAG, "setNonDetectableEmergencyCallInfo: eccCategory=" + eccCategory
+                + ", emergencyUrns=" + emergencyUrns);
+        mIsEmergencyCall = true;
+        mEmergencyNumberInfo = new EmergencyNumber(mAddress, ""/*countryIso*/, ""/*mnc*/,
+                                eccCategory, emergencyUrns,
+                                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index e06520a..cc07047 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -139,7 +139,7 @@
         mHandler = new MyHandler(mOwner.getLooper());
 
         mAddress = dc.number;
-        setEmergencyCallInfo(mOwner);
+        setEmergencyCallInfo(mOwner, null);
 
         String forwardedNumber = TextUtils.isEmpty(dc.forwardedNumber) ? null : dc.forwardedNumber;
         Rlog.i(LOG_TAG, "create, forwardedNumber=" + Rlog.pii(LOG_TAG, forwardedNumber));
@@ -186,13 +186,13 @@
 
         mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
         if (dialArgs.isEmergency) {
-            setEmergencyCallInfo(mOwner);
+            setEmergencyCallInfo(mOwner, 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.
             if (getEmergencyNumberInfo() == null) {
-                setNonDetectableEmergencyCallInfo(dialArgs.eccCategory);
+                setNonDetectableEmergencyCallInfo(dialArgs.eccCategory, new ArrayList<String>());
             }
         }
 
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index a9e21a3..aa62acb 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -150,10 +150,10 @@
  */
 
 public abstract class Phone extends Handler implements PhoneInternalInterface {
-    private static final String LOG_TAG = "Phone";
 
     protected final static Object lockForRadioTechnologyChange = new Object();
 
+    private final String mLogTag;
     protected final int USSD_MAX_QUEUE = 10;
 
     // Key used to read and write the saved network selection numeric value
@@ -597,6 +597,7 @@
                     boolean unitTestMode, int phoneId,
                     TelephonyComponentFactory telephonyComponentFactory,
                     FeatureFlags featureFlags) {
+        mLogTag = "Phone-" + phoneId;
         mPhoneId = phoneId;
         mName = name;
         mNotifier = notifier;
@@ -638,10 +639,10 @@
          */
         mDoesRilSendMultipleCallRing = TelephonyProperties.ril_sends_multiple_call_ring()
                 .orElse(true);
-        Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
+        Rlog.d(mLogTag, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
 
         mCallRingDelay = TelephonyProperties.call_ring_delay().orElse(3000);
-        Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
+        Rlog.d(mLogTag, "mCallRingDelay=" + mCallRingDelay);
 
         // Initialize SMS stats
         mSmsStats = new SmsStats(this);
@@ -785,7 +786,7 @@
 
         switch(msg.what) {
             case EVENT_CALL_RING:
-                Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
+                Rlog.d(mLogTag, "Event EVENT_CALL_RING Received state=" + getState());
                 ar = (AsyncResult)msg.obj;
                 if (ar.exception == null) {
                     PhoneConstants.State state = getState();
@@ -801,7 +802,7 @@
                 break;
 
             case EVENT_CALL_RING_CONTINUE:
-                Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
+                Rlog.d(mLogTag, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
                 if (getState() == PhoneConstants.State.RINGING) {
                     sendIncomingCallRingNotification(msg.arg1);
                 }
@@ -814,7 +815,7 @@
             case EVENT_INITIATE_SILENT_REDIAL:
                 // This is an ImsPhone -> GsmCdmaPhone redial
                 // See ImsPhone#initiateSilentRedial
-                Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
+                Rlog.d(mLogTag, "Event EVENT_INITIATE_SILENT_REDIAL Received");
                 ar = (AsyncResult) msg.obj;
                 if ((ar.exception == null) && (ar.result != null)) {
                     SilentRedialParam result = (SilentRedialParam) ar.result;
@@ -828,13 +829,13 @@
                         // one with a callback registered to TelephonyConnection. Notify the
                         // redial happened over that Phone so that it can be replaced with the
                         // new GSM/CDMA Connection.
-                        Rlog.d(LOG_TAG, "Notify redial connection changed cn: " + cn);
+                        Rlog.d(mLogTag, "Notify redial connection changed cn: " + cn);
                         if (mImsPhone != null) {
                             // Don't care it is null or not.
                             mImsPhone.notifyRedialConnectionChanged(cn);
                         }
                     } catch (CallStateException e) {
-                        Rlog.e(LOG_TAG, "silent redial failed: " + e);
+                        Rlog.e(mLogTag, "silent redial failed: " + e);
                         if (mImsPhone != null) {
                             mImsPhone.notifyRedialConnectionChanged(null);
                         }
@@ -847,7 +848,7 @@
                 if (ar.exception == null) {
                     handleSrvccStateChanged((int[]) ar.result);
                 } else {
-                    Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
+                    Rlog.e(mLogTag, "Srvcc exception: " + ar.exception);
                 }
                 break;
 
@@ -866,7 +867,7 @@
                     try {
                         mUsageSettingFromModem = ((int[]) ar.result)[0];
                     } catch (NullPointerException | ClassCastException e) {
-                        Rlog.e(LOG_TAG, "Invalid response for usage setting " + ar.result);
+                        Rlog.e(mLogTag, "Invalid response for usage setting " + ar.result);
                         break;
                     }
 
@@ -881,9 +882,9 @@
                         if (ce.getCommandError() == CommandException.Error.REQUEST_NOT_SUPPORTED) {
                             mIsUsageSettingSupported = false;
                         }
-                        Rlog.w(LOG_TAG, "Unexpected failure to retrieve usage setting " + ce);
+                        Rlog.w(mLogTag, "Unexpected failure to retrieve usage setting " + ce);
                     } catch (ClassCastException unused) {
-                        Rlog.e(LOG_TAG, "Invalid Exception for usage setting " + ar.exception);
+                        Rlog.e(mLogTag, "Invalid Exception for usage setting " + ar.exception);
                         break; // technically extraneous, but good hygiene
                     }
                 }
@@ -896,9 +897,9 @@
                         if (ce.getCommandError() == CommandException.Error.REQUEST_NOT_SUPPORTED) {
                             mIsUsageSettingSupported = false;
                         }
-                        Rlog.w(LOG_TAG, "Unexpected failure to set usage setting " + ce);
+                        Rlog.w(mLogTag, "Unexpected failure to set usage setting " + ce);
                     } catch (ClassCastException unused) {
-                        Rlog.e(LOG_TAG, "Invalid Exception for usage setting " + ar.exception);
+                        Rlog.e(mLogTag, "Invalid Exception for usage setting " + ar.exception);
                         break; // technically extraneous, but good hygiene
                     }
                 }
@@ -932,7 +933,7 @@
     }
 
     private void handleSrvccStateChanged(int[] ret) {
-        Rlog.d(LOG_TAG, "handleSrvccStateChanged");
+        Rlog.d(mLogTag, "handleSrvccStateChanged");
 
         ArrayList<Connection> conn = null;
         Phone imsPhone = mImsPhone;
@@ -949,7 +950,7 @@
                         conn = imsPhone.getHandoverConnection();
                         migrateFrom(imsPhone);
                     } else {
-                        Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
+                        Rlog.d(mLogTag, "HANDOVER_STARTED: mImsPhone null");
                     }
                     break;
                 case TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED:
@@ -1187,7 +1188,7 @@
                     to.add((Registrant) from.get(i));
                 }
             } else {
-                Rlog.d(LOG_TAG, "msg is null");
+                Rlog.d(mLogTag, "msg is null");
             }
         }
     }
@@ -1484,7 +1485,7 @@
      */
     @UnsupportedAppUsage
     public void setNetworkSelectionModeAutomatic(Message response) {
-        Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
+        Rlog.d(mLogTag, "setNetworkSelectionModeAutomatic, querying current mode");
         // 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
@@ -1519,11 +1520,11 @@
         nsm.operatorAlphaShort = "";
 
         if (doAutomatic) {
-            Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - set network selection auto");
+            Rlog.d(mLogTag, "setNetworkSelectionModeAutomatic - set network selection auto");
             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
             mCi.setNetworkSelectionModeAutomatic(msg);
         } else {
-            Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring");
+            Rlog.d(mLogTag, "setNetworkSelectionModeAutomatic - already auto, ignoring");
             // let the calling application know that the we are ignoring automatic mode switch.
             if (nsm.message != null) {
                 nsm.message.arg1 = ALREADY_IN_AUTO_SELECTION;
@@ -1617,10 +1618,10 @@
 
             // commit and log the result.
             if (!editor.commit()) {
-                Rlog.e(LOG_TAG, "failed to commit network selection preference");
+                Rlog.e(mLogTag, "failed to commit network selection preference");
             }
         } else {
-            Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
+            Rlog.e(mLogTag, "Cannot update network selection preference due to invalid subId " +
                     subId);
         }
     }
@@ -1631,7 +1632,7 @@
      * @param nsm PLMN info of the selected network
      */
     protected void updateManualNetworkSelection(NetworkSelectMessage nsm)  {
-        Rlog.e(LOG_TAG, "updateManualNetworkSelection() should be overridden");
+        Rlog.e(mLogTag, "updateManualNetworkSelection() should be overridden");
     }
 
     /**
@@ -1641,7 +1642,7 @@
         // look for our wrapper within the asyncresult, skip the rest if it
         // is null.
         if (!(ar.userObj instanceof NetworkSelectMessage)) {
-            Rlog.e(LOG_TAG, "unexpected result from user object.");
+            Rlog.e(mLogTag, "unexpected result from user object.");
             return;
         }
 
@@ -1705,12 +1706,12 @@
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
         editor.putInt(CLIR_KEY + getSubId(), commandInterfaceCLIRMode);
-        Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getSubId() + "="
+        Rlog.i(mLogTag, "saveClirSetting: " + CLIR_KEY + getSubId() + "="
                 + commandInterfaceCLIRMode);
 
         // Commit and log the result.
         if (!editor.commit()) {
-            Rlog.e(LOG_TAG, "Failed to commit CLIR preference");
+            Rlog.e(mLogTag, "Failed to commit CLIR preference");
         }
     }
 
@@ -1932,13 +1933,13 @@
         IccFileHandler fh;
 
         if (uiccApplication == null) {
-            Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
+            Rlog.d(mLogTag, "getIccFileHandler: uiccApplication == null, return null");
             fh = null;
         } else {
             fh = uiccApplication.getIccFileHandler();
         }
 
-        Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
+        Rlog.d(mLogTag, "getIccFileHandler: fh=" + fh);
         return fh;
     }
 
@@ -2025,7 +2026,7 @@
      * Retrieves the SignalStrengthController of the phone instance.
      */
     public SignalStrengthController getSignalStrengthController() {
-        Log.wtf(LOG_TAG, "getSignalStrengthController return null.");
+        Log.wtf(mLogTag, "getSignalStrengthController return null.");
         return null;
     }
 
@@ -2059,7 +2060,7 @@
      * Update voice mail count related fields and notify listeners
      */
     public void updateVoiceMail() {
-        Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden");
+        Rlog.e(mLogTag, "updateVoiceMail() should be overridden");
     }
 
     public AppType getCurrentUiccAppType() {
@@ -2185,7 +2186,7 @@
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
             status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN);
-            Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
+            Rlog.d(mLogTag, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
                     status);
             // Check for old preference if status is UNKNOWN for current subId. This part of the
             // code is needed only when upgrading from M to N.
@@ -2199,9 +2200,9 @@
                         status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
                         setCallForwardingIndicatorInSharedPref(
                                 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false);
-                        Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status);
+                        Rlog.d(mLogTag, "getCallForwardingIndicatorFromSharedPref: " + status);
                     } else {
-                        Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " +
+                        Rlog.d(mLogTag, "getCallForwardingIndicatorFromSharedPref: returning " +
                                 "DISABLED as status for matching subscriberId not found");
                     }
 
@@ -2213,7 +2214,7 @@
                 }
             }
         } else {
-            Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
+            Rlog.e(mLogTag, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
         }
         return status;
     }
@@ -2222,7 +2223,7 @@
         int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
                 IccRecords.CALL_FORWARDING_STATUS_DISABLED;
         int subId = getSubId();
-        Rlog.i(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
+        Rlog.i(mLogTag, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
                 " in pref " + CF_STATUS + subId);
 
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
@@ -2265,7 +2266,7 @@
      */
     public boolean getCallForwardingIndicator() {
         if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
+            Rlog.e(mLogTag, "getCallForwardingIndicator: not possible in CDMA");
             return false;
         }
         IccRecords r = getIccRecords();
@@ -2276,7 +2277,7 @@
         if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
             callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
         }
-        Rlog.v(LOG_TAG, "getCallForwardingIndicator: iccForwardingFlag=" + (r != null
+        Rlog.v(mLogTag, "getCallForwardingIndicator: iccForwardingFlag=" + (r != null
                     ? r.getVoiceCallForwardingFlag() : "null") + ", sharedPrefFlag="
                     + getCallForwardingIndicatorFromSharedPref());
         return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
@@ -2473,7 +2474,7 @@
             for (String pair : result.trim().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);
+                    Rlog.e(mLogTag, "Invalid ALLOWED_NETWORK_TYPES from DB, value = " + pair);
                     continue;
                 }
                 int key = convertAllowedNetworkTypeDbNameToMapIndex(networkTypesValues[0]);
@@ -2493,7 +2494,7 @@
                 }
             }
         } catch (NumberFormatException e) {
-            Rlog.e(LOG_TAG, "allowedNetworkTypes NumberFormat exception" + e);
+            Rlog.e(mLogTag, "allowedNetworkTypes NumberFormat exception" + e);
         }
 
         for (int key : oldAllowedNetworkTypes.keySet()) {
@@ -2612,7 +2613,7 @@
     protected void updateAllowedNetworkTypes(Message response) {
         int modemRaf = getRadioAccessFamily();
         if (modemRaf == RadioAccessFamily.RAF_UNKNOWN) {
-            Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
+            Rlog.d(mLogTag, "setPreferredNetworkType: Abort, unknown RAF: "
                     + modemRaf);
             if (response != null) {
                 CommandException ex;
@@ -2721,7 +2722,7 @@
      * @param onComplete a callback message when the action is completed
      */
     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
-        Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
+        Rlog.d(mLogTag, "unexpected setUiTTYMode method call");
     }
 
     /**
@@ -2848,7 +2849,7 @@
     public boolean eraseDataInSharedPreferences() {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         SharedPreferences.Editor editor = sp.edit();
-        Rlog.d(LOG_TAG, "Erase all data saved in SharedPreferences");
+        Rlog.d(mLogTag, "Erase all data saved in SharedPreferences");
         editor.clear();
         return editor.commit();
     }
@@ -3094,7 +3095,7 @@
                     isVideoCallOrConference(mImsPhone.getBackgroundCall()) ||
                     isVideoCallOrConference(mImsPhone.getRingingCall());
         }
-        Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent);
+        Rlog.d(mLogTag, "isImsVideoCallOrConferencePresent: " + isPresent);
         return isPresent;
     }
 
@@ -3119,7 +3120,7 @@
         int subId = getSubId();
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
 
-            Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
+            Rlog.d(mLogTag, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
                     " for mVmCountKey = " + VM_COUNT + subId + " in preferences.");
 
             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
@@ -3127,16 +3128,16 @@
             editor.putInt(VM_COUNT + subId, countWaiting);
             editor.apply();
         } else {
-            Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
+            Rlog.e(mLogTag, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
         }
         // store voice mail count in SIM
         IccRecords records = UiccController.getInstance().getIccRecords(
                 mPhoneId, UiccController.APP_FAM_3GPP);
         if (records != null) {
-            Rlog.d(LOG_TAG, "setVoiceMessageCount: updating SIM Records");
+            Rlog.d(mLogTag, "setVoiceMessageCount: updating SIM Records");
             records.setVoiceMessageWaiting(1, countWaiting);
         } else {
-            Rlog.d(LOG_TAG, "setVoiceMessageCount: SIM Records not found");
+            Rlog.d(mLogTag, "setVoiceMessageCount: SIM Records not found");
         }
         // notify listeners of voice mail
         notifyMessageWaitingIndicator();
@@ -3152,7 +3153,7 @@
             int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount);
             if (countFromSP != invalidCount) {
                 countVoiceMessages = countFromSP;
-                Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId +
+                Rlog.d(mLogTag, "getStoredVoiceMessageCount: from preference for subId " + subId +
                         "= " + countVoiceMessages);
             } else {
                 // Check for old preference if count not found for current subId. This part of the
@@ -3165,10 +3166,10 @@
                         // get voice mail count from preferences
                         countVoiceMessages = sp.getInt(VM_COUNT, 0);
                         setVoiceMessageCount(countVoiceMessages);
-                        Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " +
+                        Rlog.d(mLogTag, "getStoredVoiceMessageCount: from preference = " +
                                 countVoiceMessages);
                     } else {
-                        Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " +
+                        Rlog.d(mLogTag, "getStoredVoiceMessageCount: returning 0 as count for " +
                                 "matching subscriberId not found");
 
                     }
@@ -3180,7 +3181,7 @@
                 }
             }
         } else {
-            Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId);
+            Rlog.e(mLogTag, "getStoredVoiceMessageCount: invalid subId " + subId);
         }
         return countVoiceMessages;
     }
@@ -3713,17 +3714,17 @@
                             }
                         }
                     } catch (NumberFormatException e) {
-                        Rlog.e(LOG_TAG, "Exception in getProvisioningUrlBaseFromFile: " + e);
+                        Rlog.e(mLogTag, "Exception in getProvisioningUrlBaseFromFile: " + e);
                     }
                 }
             }
             return null;
         } catch (FileNotFoundException e) {
-            Rlog.e(LOG_TAG, "Carrier Provisioning Urls file not found");
+            Rlog.e(mLogTag, "Carrier Provisioning Urls file not found");
         } catch (XmlPullParserException e) {
-            Rlog.e(LOG_TAG, "Xml parser exception reading Carrier Provisioning Urls file: " + e);
+            Rlog.e(mLogTag, "Xml parser exception reading Carrier Provisioning Urls file: " + e);
         } catch (IOException e) {
-            Rlog.e(LOG_TAG, "I/O exception reading Carrier Provisioning Urls file: " + e);
+            Rlog.e(mLogTag, "I/O exception reading Carrier Provisioning Urls file: " + e);
         }
         return null;
     }
@@ -3735,9 +3736,9 @@
         String url = getProvisioningUrlBaseFromFile();
         if (TextUtils.isEmpty(url)) {
             url = mContext.getResources().getString(R.string.mobile_provisioning_url);
-            Rlog.d(LOG_TAG, "getMobileProvisioningUrl: url from resource =" + url);
+            Rlog.d(mLogTag, "getMobileProvisioningUrl: url from resource =" + url);
         } else {
-            Rlog.d(LOG_TAG, "getMobileProvisioningUrl: url from File =" + url);
+            Rlog.d(mLogTag, "getMobileProvisioningUrl: url from File =" + url);
         }
         // Populate the iccid, imei and phone number in the provisioning url.
         if (!TextUtils.isEmpty(url)) {
@@ -3811,7 +3812,7 @@
      * version scoped to their packages
      */
     public void notifyNewRingingConnectionP(Connection cn) {
-        Rlog.i(LOG_TAG, String.format(
+        Rlog.i(mLogTag, String.format(
                 "notifyNewRingingConnection: phoneId=[%d], connection=[%s], registrants=[%s]",
                 getPhoneId(), cn, getNewRingingConnectionRegistrantsAsString()));
         if (!mIsVoiceCapable)
@@ -3867,12 +3868,12 @@
     private void sendIncomingCallRingNotification(int token) {
         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
                 (token == mCallRingContinueToken)) {
-            Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
+            Rlog.d(mLogTag, "Sending notifyIncomingRing");
             notifyIncomingRing();
             sendMessageDelayed(
                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
         } else {
-            Rlog.d(LOG_TAG, "Ignoring ring notification request,"
+            Rlog.d(mLogTag, "Ignoring ring notification request,"
                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
                     + " token=" + token
                     + " mCallRingContinueToken=" + mCallRingContinueToken
@@ -3912,7 +3913,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public IsimRecords getIsimRecords() {
-        Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
+        Rlog.e(mLogTag, "getIsimRecords() is only supported on LTE devices");
         return null;
     }
 
@@ -3945,7 +3946,7 @@
      */
     public void setVoiceMessageWaiting(int line, int countWaiting) {
         // This function should be overridden by class GsmCdmaPhone.
-        Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
+        Rlog.e(mLogTag, "Error! This function should never be executed, inactive Phone.");
     }
 
     /**
@@ -4204,7 +4205,7 @@
                 isImsRegistered = sst.isImsRegistered();
             }
         }
-        Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
+        Rlog.d(mLogTag, "isImsRegistered =" + isImsRegistered);
         return isImsRegistered;
     }
 
@@ -4218,7 +4219,7 @@
         if (imsPhone != null) {
             isWifiCallingEnabled = imsPhone.isWifiCallingEnabled();
         }
-        Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled);
+        Rlog.d(mLogTag, "isWifiCallingEnabled =" + isWifiCallingEnabled);
         return isWifiCallingEnabled;
     }
 
@@ -4232,7 +4233,7 @@
         if (imsPhone != null) {
             isAvailable = imsPhone.isImsCapabilityAvailable(capability, regTech);
         }
-        Rlog.d(LOG_TAG, "isImsCapabilityAvailable, capability=" + capability + ", regTech="
+        Rlog.d(mLogTag, "isImsCapabilityAvailable, capability=" + capability + ", regTech="
                 + regTech + ", isAvailable=" + isAvailable);
         return isAvailable;
     }
@@ -4256,7 +4257,7 @@
         if (imsPhone != null) {
             isVolteEnabled = imsPhone.isVoiceOverCellularImsEnabled();
         }
-        Rlog.d(LOG_TAG, "isVoiceOverCellularImsEnabled=" + isVolteEnabled);
+        Rlog.d(mLogTag, "isVoiceOverCellularImsEnabled=" + isVolteEnabled);
         return isVolteEnabled;
     }
 
@@ -4270,7 +4271,7 @@
         if (imsPhone != null) {
             regTech = imsPhone.getImsRegistrationTech();
         }
-        Rlog.d(LOG_TAG, "getImsRegistrationTechnology =" + regTech);
+        Rlog.d(mLogTag, "getImsRegistrationTechnology =" + regTech);
         return regTech;
     }
 
@@ -4852,7 +4853,7 @@
     public boolean isDeviceIdle() {
         DeviceStateMonitor dsm = getDeviceStateMonitor();
         if (dsm == null) {
-            Rlog.e(LOG_TAG, "isDeviceIdle: DeviceStateMonitor is null");
+            Rlog.e(mLogTag, "isDeviceIdle: DeviceStateMonitor is null");
             return false;
         }
         return !dsm.shouldEnableHighPowerConsumptionIndications();
@@ -4866,7 +4867,7 @@
     public void notifyDeviceIdleStateChanged(boolean isIdle) {
         SignalStrengthController ssc = getSignalStrengthController();
         if (ssc == null) {
-            Rlog.e(LOG_TAG, "notifyDeviceIdleStateChanged: SignalStrengthController is null");
+            Rlog.e(mLogTag, "notifyDeviceIdleStateChanged: SignalStrengthController is null");
             return;
         }
         ssc.onDeviceIdleStateChanged(isIdle);
@@ -5298,7 +5299,7 @@
      * @param type for callback mode entry.
      */
     public void startCallbackMode(@TelephonyManager.EmergencyCallbackModeType int type) {
-        Rlog.d(LOG_TAG, "startCallbackMode:type=" + type);
+        Rlog.d(mLogTag, "startCallbackMode:type=" + type);
         mNotifier.notifyCallbackModeStarted(this, type);
     }
 
@@ -5309,7 +5310,7 @@
      */
     public void stopCallbackMode(@TelephonyManager.EmergencyCallbackModeType int type,
             @TelephonyManager.EmergencyCallbackModeStopReason int reason) {
-        Rlog.d(LOG_TAG, "stopCallbackMode:type=" + type + ", reason=" + reason);
+        Rlog.d(mLogTag, "stopCallbackMode:type=" + type + ", reason=" + reason);
         mNotifier.notifyCallbackModeStopped(this, type, reason);
     }
 
@@ -5347,7 +5348,7 @@
         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
         pw.println(" getUnitTestMode()=" + getUnitTestMode());
         pw.println(" getState()=" + getState());
-        pw.println(" getIccSerialNumber()=" + Rlog.pii(LOG_TAG, getIccSerialNumber()));
+        pw.println(" getIccSerialNumber()=" + Rlog.pii(mLogTag, getIccSerialNumber()));
         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
@@ -5532,18 +5533,14 @@
     }
 
     private void logd(String s) {
-        Rlog.d(LOG_TAG, "[" + mPhoneId + "] " + s);
+        Rlog.d(mLogTag, "[" + mPhoneId + "] " + s);
     }
 
     private void logi(String s) {
-        Rlog.i(LOG_TAG, "[" + mPhoneId + "] " + s);
+        Rlog.i(mLogTag, "[" + mPhoneId + "] " + s);
     }
 
     private void loge(String s) {
-        Rlog.e(LOG_TAG, "[" + mPhoneId + "] " + s);
-    }
-
-    private static String pii(String s) {
-        return Rlog.pii(LOG_TAG, s);
+        Rlog.e(mLogTag, "[" + mPhoneId + "] " + s);
     }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index dcb3b20..e73eafd 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -3553,8 +3553,10 @@
             if (DBG) log("onCallStartFailed reasonCode=" + reasonInfo.getCode());
 
             int eccCategory = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+            List<String> emergencyUrns = new ArrayList<>();
             if (imsCall != null && imsCall.getCallProfile() != null) {
                 eccCategory = imsCall.getCallProfile().getEmergencyServiceCategories();
+                emergencyUrns = imsCall.getCallProfile().getEmergencyUrns();
             }
 
             if (mHoldSwitchingState == HoldSwapState.HOLDING_TO_ANSWER_INCOMING) {
@@ -3581,13 +3583,14 @@
                 // Since onCallInitiating and onCallProgressing reset mPendingMO,
                 // we can't depend on mPendingMO.
                 if (conn != null) {
-                    logi("onCallStartFailed eccCategory=" + eccCategory);
+                    logi("onCallStartFailed eccCategory=" + eccCategory + ", emergencyUrns="
+                            + emergencyUrns);
                     int reason = reasonInfo.getCode();
                     int extraCode = reasonInfo.getExtraCode();
                     if ((reason == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
                             && extraCode == ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY)
                             || (reason == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL)) {
-                        conn.setNonDetectableEmergencyCallInfo(eccCategory);
+                        conn.setNonDetectableEmergencyCallInfo(eccCategory, emergencyUrns);
                     }
                     conn.setImsReasonInfo(reasonInfo);
                     sendCallStartFailedDisconnect(imsCall, reasonInfo);
@@ -3765,11 +3768,13 @@
                     && DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
                 if (conn != null) {
                     int eccCategory = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+                    List<String> emergencyUrns = new ArrayList<>();
                     if (imsCall != null && imsCall.getCallProfile() != null) {
                         eccCategory = imsCall.getCallProfile().getEmergencyServiceCategories();
+                        emergencyUrns = imsCall.getCallProfile().getEmergencyUrns();
                         logi("onCallTerminated eccCategory=" + eccCategory);
                     }
-                    conn.setNonDetectableEmergencyCallInfo(eccCategory);
+                    conn.setNonDetectableEmergencyCallInfo(eccCategory, emergencyUrns);
                 }
                 processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
                 return;
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 aee8867..316f62a
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -286,13 +286,13 @@
 
         mIsEmergency = isEmergency;
         if (isEmergency) {
-            setEmergencyCallInfo(mOwner);
+            setEmergencyCallInfo(mOwner, dialArgs);
 
             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);
+                setNonDetectableEmergencyCallInfo(dialArgs.eccCategory, new ArrayList<String>());
             }
         }
 
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 21ae2c7..6cee1b2 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -318,6 +318,8 @@
     private final Object mIsSatelliteEnabledLock = new Object();
     @GuardedBy("mIsSatelliteEnabledLock")
     private Boolean mIsSatelliteEnabled = null;
+    private final Object mIsRadioOnLock = new Object();
+    @GuardedBy("mIsRadioOnLock")
     private boolean mIsRadioOn = false;
     private final Object mSatelliteViaOemProvisionLock = new Object();
     @GuardedBy("mSatelliteViaOemProvisionLock")
@@ -514,7 +516,10 @@
                 mContext, looper, mFeatureFlags, mPointingAppController);
 
         mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-        mIsRadioOn = phone.isRadioOn();
+        synchronized (mIsRadioOnLock) {
+            mIsRadioOn = phone.isRadioOn();
+        }
+
         registerForSatelliteProvisionStateChanged();
         registerForPendingDatagramCount();
         registerForSatelliteModemStateChanged();
@@ -1218,11 +1223,13 @@
             }
 
             case EVENT_RADIO_STATE_CHANGED: {
-                if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
-                    mIsRadioOn = true;
-                } else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) {
-                    mIsRadioOn = false;
-                    resetCarrierRoamingSatelliteModeParams();
+                synchronized (mIsRadioOnLock) {
+                    logd("EVENT_RADIO_STATE_CHANGED: radioState=" + mCi.getRadioState());
+                    if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
+                        mIsRadioOn = true;
+                    } else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) {
+                        resetCarrierRoamingSatelliteModeParams();
+                    }
                 }
 
                 if (mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE) {
@@ -1498,11 +1505,13 @@
         }
 
         if (enableSatellite) {
-            if (!mIsRadioOn) {
-                ploge("Radio is not on, can not enable satellite");
-                sendErrorAndReportSessionMetrics(
-                        SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result);
-                return;
+            synchronized (mIsRadioOnLock) {
+                if (!mIsRadioOn) {
+                    ploge("Radio is not on, can not enable satellite");
+                    sendErrorAndReportSessionMetrics(
+                            SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result);
+                    return;
+                }
             }
         } else {
             /* if disable satellite, always assume demo is also disabled */
@@ -2644,12 +2653,15 @@
      * modem. {@link SatelliteController} will then power off the satellite modem.
      */
     public void onCellularRadioPowerOffRequested() {
+        logd("onCellularRadioPowerOffRequested()");
         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
             plogd("onCellularRadioPowerOffRequested: oemEnabledSatelliteFlag is disabled");
             return;
         }
 
-        mIsRadioOn = false;
+        synchronized (mIsRadioOnLock) {
+            mIsRadioOn = false;
+        }
         requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                 false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */,
                 new IIntegerConsumer.Stub() {
@@ -2981,6 +2993,29 @@
     }
 
     /**
+     * Register the handler for SIM Refresh notifications.
+     * @param handler Handler for notification message.
+     * @param what User-defined message code.
+     */
+    public void registerIccRefresh(Handler handler, int what) {
+        for (Phone phone : PhoneFactory.getPhones()) {
+            CommandsInterface ci = phone.mCi;
+            ci.registerForIccRefresh(handler, what, null);
+        }
+    }
+
+    /**
+     * Unregister the handler for SIM Refresh notifications.
+     * @param handler Handler for notification message.
+     */
+    public void unRegisterIccRefresh(Handler handler) {
+        for (Phone phone : PhoneFactory.getPhones()) {
+            CommandsInterface ci = phone.mCi;
+            ci.unregisterForIccRefresh(handler);
+        }
+    }
+
+    /**
      * To use the satellite service, update the EntitlementStatus and the PlmnAllowedList after
      * receiving the satellite configuration from the entitlement server. If satellite
      * entitlement is enabled, enable satellite for the carrier. Otherwise, disable satellite.
@@ -4333,7 +4368,7 @@
                         sessionStats.onSignalStrength(phone);
                         if (!mWasSatelliteConnectedViaCarrier.get(subId)) {
                             // Log satellite connection start
-                            sessionStats.onConnectionStart();
+                            sessionStats.onConnectionStart(phone);
                         }
                     }
 
@@ -4404,7 +4439,7 @@
                 // Log satellite session start
                 CarrierRoamingSatelliteSessionStats sessionStats =
                         CarrierRoamingSatelliteSessionStats.getInstance(subId);
-                sessionStats.onSessionStart(phone.getCarrierId());
+                sessionStats.onSessionStart(phone.getCarrierId(), phone);
                 mCarrierRoamingSatelliteSessionStatsMap.put(subId, sessionStats);
             } else if (lastNotifiedNtnMode && !currNtnMode) {
                 // Log satellite session end
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 9172f9f..bc6a79c 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -198,8 +198,7 @@
      *                   call.
      */
     public void onEmergencyCallStarted(@NonNull Connection connection) {
-        if (!mSatelliteController.isSatelliteSupportedViaOem()
-                && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) {
+        if (!isSatelliteSupported()) {
             plogd("onEmergencyCallStarted: satellite is not supported");
             return;
         }
@@ -230,8 +229,7 @@
     public void onEmergencyCallConnectionStateChanged(
             String callId, @Connection.ConnectionState int state) {
         plogd("callId=" + callId + ", state=" + state);
-        if (!mSatelliteController.isSatelliteSupportedViaOem()
-                && !mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) {
+        if (!isSatelliteSupported()) {
             plogd("onEmergencyCallConnectionStateChanged: satellite is not supported");
             return;
         }
@@ -791,6 +789,19 @@
                 || SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false));
     }
 
+    private boolean isSatelliteSupported() {
+        if (mSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier()) return true;
+        if (mSatelliteController.isSatelliteSupportedViaOem() && isSatelliteViaOemProvisioned()) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isSatelliteViaOemProvisioned() {
+        Boolean provisioned = mSatelliteController.isSatelliteViaOemProvisioned();
+        return (provisioned != null) && provisioned;
+    }
+
     private static void logv(@NonNull String log) {
         Rlog.v(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteSessionStats.java b/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteSessionStats.java
index 0f88bd5..771432e 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteSessionStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteSessionStats.java
@@ -20,13 +20,18 @@
 import android.telephony.CellInfo;
 import android.telephony.CellSignalStrength;
 import android.telephony.CellSignalStrengthLte;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.metrics.SatelliteStats;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -36,6 +41,7 @@
     private static final String TAG = CarrierRoamingSatelliteSessionStats.class.getSimpleName();
     private static final SparseArray<CarrierRoamingSatelliteSessionStats>
             sCarrierRoamingSatelliteSessionStats = new SparseArray<>();
+    @NonNull private final SubscriptionManagerService mSubscriptionManagerService;
     private int mCarrierId;
     private boolean mIsNtnRoamingInHomeCountry;
     private int mCountOfIncomingSms;
@@ -53,6 +59,7 @@
     public CarrierRoamingSatelliteSessionStats(int subId) {
         logd("Create new CarrierRoamingSatelliteSessionStats. subId=" + subId);
         initializeParams();
+        mSubscriptionManagerService = SubscriptionManagerService.getInstance();
     }
 
     /** Gets a CarrierRoamingSatelliteSessionStats instance. */
@@ -67,21 +74,24 @@
     }
 
     /** Log carrier roaming satellite session start */
-    public void onSessionStart(int carrierId) {
+    public void onSessionStart(int carrierId, Phone phone) {
         mCarrierId = carrierId;
         mSessionStartTimeSec = getCurrentTimeInSec();
-        onConnectionStart();
+        mIsNtnRoamingInHomeCountry = false;
+        onConnectionStart(phone);
     }
 
     /** Log carrier roaming satellite connection start */
-    public void onConnectionStart() {
+    public void onConnectionStart(Phone phone) {
         mConnectionStartTimeList.add(getCurrentTime());
+        updateNtnRoamingInHomeCountry(phone);
     }
 
     /** Log carrier roaming satellite session end */
     public void onSessionEnd() {
         onConnectionEnd();
         reportMetrics();
+        mIsNtnRoamingInHomeCountry = false;
     }
 
     /** Log carrier roaming satellite connection end */
@@ -292,6 +302,41 @@
         return mSessionStartTimeSec != 0;
     }
 
+    private void updateNtnRoamingInHomeCountry(Phone phone) {
+        int subId = phone.getSubId();
+        ServiceState serviceState = phone.getServiceState();
+        if (serviceState == null) {
+            logd("ServiceState is null");
+            return;
+        }
+
+        String satelliteRegisteredPlmn = "";
+        for (NetworkRegistrationInfo nri
+                : serviceState.getNetworkRegistrationInfoList()) {
+            if (nri.isNonTerrestrialNetwork()) {
+                satelliteRegisteredPlmn = nri.getRegisteredPlmn();
+            }
+        }
+
+        SubscriptionInfoInternal subscriptionInfoInternal =
+                mSubscriptionManagerService.getSubscriptionInfoInternal(subId);
+        if (subscriptionInfoInternal == null) {
+            logd("SubscriptionInfoInternal is null");
+            return;
+        }
+        String simCountry = MccTable.countryCodeForMcc(subscriptionInfoInternal.getMcc());
+        String satelliteRegisteredCountry = MccTable.countryCodeForMcc(
+                satelliteRegisteredPlmn.substring(0, 3));
+        if (simCountry.equalsIgnoreCase(satelliteRegisteredCountry)) {
+            mIsNtnRoamingInHomeCountry = false;
+        } else {
+            // If device is connected to roaming non-terrestrial network, update to true.
+            mIsNtnRoamingInHomeCountry = true;
+        }
+        logd("updateNtnRoamingInHomeCountry: mIsNtnRoamingInHomeCountry="
+                + mIsNtnRoamingInHomeCountry);
+    }
+
     private void logd(@NonNull String log) {
         Log.d(TAG, log);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
index 0bce5cb..329b0b8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -25,9 +26,14 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.ArrayList;
+
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.telephony.emergency.EmergencyNumber;
 
+import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 
 import org.junit.After;
@@ -150,7 +156,7 @@
         assertNull(connection1.getEmergencyNumberInfo());
         assertFalse(connection1.hasKnownUserIntentEmergency());
 
-        connection2.setEmergencyCallInfo(mPhone.getCallTracker());
+        connection2.setEmergencyCallInfo(mPhone.getCallTracker(), null);
         connection2.setHasKnownUserIntentEmergency(true);
         connection1.migrateFrom(connection2);
 
@@ -164,7 +170,7 @@
     @Test
     public void testEmergencyCallParameters() {
         Connection connection = new TestConnection(TEST_PHONE_TYPE);
-        connection.setEmergencyCallInfo(mPhone.getCallTracker());
+        connection.setEmergencyCallInfo(mPhone.getCallTracker(), null);
         assertTrue(connection.isEmergencyCall());
         assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
         connection.setHasKnownUserIntentEmergency(true);
@@ -186,9 +192,44 @@
                 .thenReturn(getTestEmergencyNumber());
 
         //Ensure the connection is considered as an emergency call:
-        mTestConnection.setEmergencyCallInfo(mCT);
+        mTestConnection.setEmergencyCallInfo(mCT, null);
         assertTrue(mTestConnection.isEmergencyCall());
     }
 
+    @Test
+    public void testUpdateEmergencyRouting() {
+        DialArgs dialArgs = new DialArgs.Builder().build();
+        Connection connection = new TestConnection(TEST_PHONE_TYPE);
+        connection.setEmergencyCallInfo(mPhone.getCallTracker(), dialArgs);
+
+        // Not updated when DomainSelectionService is disabled.
+        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+
+        // Enable DomainSelectionService
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        connection = new TestConnection(TEST_PHONE_TYPE);
+        connection.setEmergencyCallInfo(mPhone.getCallTracker(), dialArgs);
+
+        // Not updated when IS_EMERGENCY_ROUTING is not specified.
+        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+
+        Bundle extras = new Bundle();
+        extras.putBoolean(PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, true);
+        extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
+        dialArgs = new DialArgs.Builder().setIntentExtras(extras).build();
+
+        connection = new TestConnection(TEST_PHONE_TYPE);
+        connection.setEmergencyCallInfo(mPhone.getCallTracker(), dialArgs);
+        EmergencyNumber expectedNumber = new EmergencyNumber("911", "us", "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(), EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        // Updated when DomainSelectionService is enabled.
+        assertNotEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
+        assertEquals(expectedNumber, connection.getEmergencyNumberInfo());
+    }
+
     // TODO Verify more methods in Connection
 }