Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7832332 authored by Hunsuk Choi's avatar Hunsuk Choi Committed by Jongduck You
Browse files

Update EmergencyNumber for redial via emergency routing

When redialing is required via emergency routing, the emergency number information is updated.
The eccCategory and emergencyUrns information provided through DialArgs are updated, and the routing information is updated to emergency routing.

Bug: 336759603
Test: atest FrameworksTelephonyTests
Test: build and manual test

Change-Id: Ib404d1e41633df7f834792ba1156296dd4ad91f6
parent 9b00d030
Loading
Loading
Loading
Loading
+43 −10
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.Log;

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 @@ public abstract class Connection {
     *
     * @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,21 +678,53 @@ public abstract class Connection {
        } 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) {
    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,
                                    new ArrayList<String>(),
        mEmergencyNumberInfo = new EmergencyNumber(mAddress, ""/*countryIso*/, ""/*mnc*/,
                                eccCategory, emergencyUrns,
                                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
                                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
    }
    }

    /**
     * Set if we have known the user's intent for the call is emergency.
+3 −3
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ public class GsmCdmaConnection extends Connection {
        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 @@ public class GsmCdmaConnection extends Connection {

        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>());
            }
        }

+8 −3
Original line number Diff line number Diff line
@@ -3553,8 +3553,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            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 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                // 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 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                    && 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;
+2 −2
Original line number Diff line number Diff line
@@ -277,13 +277,13 @@ public class ImsPhoneConnection extends Connection implements

        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>());
            }
        }

+44 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony;

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.doReturn;
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 @@ public class ConnectionTest extends TelephonyTest {
        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 @@ public class ConnectionTest extends TelephonyTest {
    @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 @@ public class ConnectionTest extends TelephonyTest {
                .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
}