Merge "Update EmergencyNumber for redial via emergency routing" into 24D1-dev am: 0f7ebebae1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/27512054

Change-Id: I97f1784c31128e4d5a5d31ecd22d7bef532c27a9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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/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/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
 }