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

Commit b9f77946 authored by Jongduck You's avatar Jongduck You
Browse files

Redial CS calls via emergency routing

When a CODE_SIP_ALTERNATE_EMERGENCY_CALL is received after placing a
normal routing emergency call, the call should be retried using
emergency routing.
This functionality is already implemented for ImsPhoneConnection.
This modification updates GsmCdmaConnection to handle CS redial
scenarios.
For CS redials, emergency routing will be enforced only when the
emergency category is not EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED.

Flag: EXEMPT bugfix
Bug: 347269126
Test: atest FrameworksTelephonyTests
Test: Verification of scenarios that retry CS emergency calls or CS normal calls after receiving a 380 AS response
Test: Verification of scenarios that retry PS emergency calls after receiving a 380 AS response
Test: Verification of scenarios that initiate PS or CS emergency calls without regression
Change-Id: I1967bd7221ced0eb77bb2540146e7ea5b191d829
parent 6171d7ff
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -694,6 +694,16 @@ public abstract class Connection {
                int eccCategory = dialArgs.intentExtras.getInt(
                    PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
                    mEmergencyNumberInfo.getEmergencyServiceCategoryBitmask());
                // According to 3gpp 23.167 section 7.1.2, when CS domain is selected,
                // emergency routing is performed only if the emergency category is provided.
                if (this instanceof GsmCdmaConnection
                        && dialArgs.intentExtras.getInt(
                                PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
                                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)
                                == EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
                    Rlog.d(TAG, "setEmergencyCallInfo: specific eccCategory is required");
                    return;
                }
                Rlog.d(TAG, "setEmergencyCallInfo: enforce emergency routing eccCategory="
                        + eccCategory);
                List<String> emergencyUrns = dialArgs.intentExtras.getStringArrayList(
@@ -706,12 +716,31 @@ public abstract class Connection {
                        mEmergencyNumberInfo.getMnc(),
                        eccCategory,
                        emergencyUrns,
                        mEmergencyNumberInfo.getEmergencyNumberSourceBitmask(),
                        getEmergencyNumberSourceForEmergencyRouting(),
                        EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
            }
        }
    }

    /**
     * Get the emergency number source to be used for emergency routing calls.
     * This is not getting actual source, instead its forcing the source to
     * EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING.
     * Even when the source is EMERGENCY_NUMBER_SOURCE_DATABASE,
     * to allow the category information delivered by the network to be used,
     * the source is set to EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING.
     */
    private int getEmergencyNumberSourceForEmergencyRouting() {
        int source = mEmergencyNumberInfo.getEmergencyNumberSourceBitmask();
        Rlog.d(TAG, "getEmergencyNumberSourceForEmergencyRouting: source=" + source);

        if (source != EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST) {
            source = EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING;
        }

        return source;
    }

    /**
     * Set the non-detectable emergency number information.
     */
+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;

import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
@@ -186,7 +187,7 @@ public class GsmCdmaConnection extends Connection {

        mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
        if (dialArgs.isEmergency) {
            setEmergencyCallInfo(mOwner, null);
            setEmergencyCallInfo(mOwner, dialArgs);

            // 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
+50 −0
Original line number Diff line number Diff line
@@ -21,10 +21,12 @@ import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.emergency.EmergencyNumber;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

@@ -313,4 +315,52 @@ public class GsmCdmaConnectionTest extends TelephonyTest {
        assertEquals(DisconnectCause.OUT_OF_SERVICE,
                connection.disconnectCauseFromCode(CallFailCause.LOCAL_SERVICE_UNAVAILABLE));
    }

    @Test
    public void testUpdateEmergencyRouting() {
        Bundle extras = new Bundle();
        extras.putBoolean(PhoneConstants.EXTRA_USE_EMERGENCY_ROUTING, true);

        DialArgs dialArgs = new DialArgs.Builder()
                .setIsEmergency(true)
                .setIntentExtras(extras)
                .build();

        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();

        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, dialArgs);
        // Not updated when category is unset.
        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());

        extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);

        dialArgs = new DialArgs.Builder()
                .setIsEmergency(true)
                .setIntentExtras(extras)
                .build();

        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, dialArgs);
        // Not updated when category is EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED.
        assertEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());

        extras.putInt(PhoneConstants.EXTRA_EMERGENCY_SERVICE_CATEGORY,
                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);

        dialArgs = new DialArgs.Builder()
                .setIsEmergency(true)
                .setIntentExtras(extras)
                .build();

        connection = new GsmCdmaConnection(mPhone, "911", mCT, null, 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 category is not EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED.
        assertNotEquals(getTestEmergencyNumber(), connection.getEmergencyNumberInfo());
        assertEquals(expectedNumber, connection.getEmergencyNumberInfo());
    }
}