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

Commit 663017ce authored by Hwangoo Park's avatar Hwangoo Park Committed by Android (Google) Code Review
Browse files

Merge "Use the stored emergency registration result instead of an unknown one" into main

parents f71d6785 0fff4b1a
Loading
Loading
Loading
Loading
+43 −11
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ public class EmergencyStateTracker {
    private int mOngoingCallProperties;
    private boolean mSentEmergencyCallState;
    private android.telecom.Connection mNormalRoutingEmergencyConnection;
    private boolean mIsEmergencyCallWaitingForEmergencyModeCompletion;

    /** For emergency SMS */
    private final Set<String> mOngoingEmergencySmsIds = new ArraySet<>();
@@ -370,6 +371,14 @@ public class EmergencyStateTracker {
                                }
                            } else {
                                completeEmergencyMode(emergencyType);

                                // Emergency SMS is being started
                                // while DDS switch condition is being checked.
                                if (mIsEmergencyCallWaitingForEmergencyModeCompletion) {
                                    mIsEmergencyCallWaitingForEmergencyModeCompletion = false;
                                    setIsInEmergencyCall(true);
                                    completeEmergencyMode(EMERGENCY_TYPE_CALL);
                                }
                            }
                        } else {
                            completeEmergencyMode(emergencyType);
@@ -380,6 +389,14 @@ public class EmergencyStateTracker {
                                        STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED);
                                turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL,
                                        mIsTestEmergencyNumber);
                            } else if (mPhone != null) {
                                // Emergency SMS is being started
                                // while DDS switch condition is being checked.
                                if (mIsEmergencyCallWaitingForEmergencyModeCompletion) {
                                    mIsEmergencyCallWaitingForEmergencyModeCompletion = false;
                                    setIsInEmergencyCall(true);
                                    completeEmergencyMode(EMERGENCY_TYPE_CALL);
                                }
                            }
                        }
                    }
@@ -670,11 +687,10 @@ public class EmergencyStateTracker {
                            MSG_SET_EMERGENCY_MODE_DONE);
                    return mCallEmergencyModeFuture;
                }
                // Ensure that domain selector requests scan.
                mLastEmergencyRegistrationResult = new EmergencyRegistrationResult(
                        AccessNetworkConstants.AccessNetworkType.UNKNOWN,
                        NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN,
                        NetworkRegistrationInfo.DOMAIN_UNKNOWN, false, false, 0, 0, "", "", "");
                // If the last emergency registration result is available, it's used for initial
                // domain selection. Otherwise, an unknown emergency registration result is created,
                // prompting the domain selector to request a network scan.
                setUnknownEmergencyRegistrationResultIfNotAvailable();
                return CompletableFuture.completedFuture(DisconnectCause.NOT_DISCONNECTED);
            }

@@ -792,6 +808,7 @@ public class EmergencyStateTracker {
    }

    private void clearEmergencyCallInfo() {
        mIsEmergencyCallWaitingForEmergencyModeCompletion = false;
        mEmergencyCallDomain = NetworkRegistrationInfo.DOMAIN_UNKNOWN;
        mEmergencyCallPhoneType = PhoneConstants.PHONE_TYPE_NONE;
        mIsTestEmergencyNumber = false;
@@ -802,6 +819,15 @@ public class EmergencyStateTracker {
        mPhone = null;
    }

    private void setUnknownEmergencyRegistrationResultIfNotAvailable() {
        if (mLastEmergencyRegistrationResult == null) {
            mLastEmergencyRegistrationResult = new EmergencyRegistrationResult(
                    AccessNetworkConstants.AccessNetworkType.UNKNOWN,
                    NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN,
                    NetworkRegistrationInfo.DOMAIN_UNKNOWN, false, false, 0, 0, "", "", "");
        }
    }

    private void switchDdsAndSetEmergencyMode(Phone phone, @EmergencyType int emergencyType) {
        switchDdsDelayed(phone, result -> {
            Rlog.i(TAG, "switchDdsDelayed: result = " + result);
@@ -817,16 +843,21 @@ public class EmergencyStateTracker {
            if (mEmergencyMode != MODE_EMERGENCY_WWAN) {
                setEmergencyMode(phone, emergencyType, MODE_EMERGENCY_WWAN,
                        MSG_SET_EMERGENCY_MODE_DONE);
            } else {
                // Ensure that domain selector requests the network scan.
                mLastEmergencyRegistrationResult = new EmergencyRegistrationResult(
                        AccessNetworkConstants.AccessNetworkType.UNKNOWN,
                        NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN,
                        NetworkRegistrationInfo.DOMAIN_UNKNOWN, false, false, 0, 0, "", "", "");
            } else if (!isEmergencyModeInProgress()) {
                // If the last emergency registration result is available, it's used for initial
                // domain selection. Otherwise, an unknown emergency registration result is created,
                // prompting the domain selector to request a network scan.
                setUnknownEmergencyRegistrationResultIfNotAvailable();

                if (emergencyType == EMERGENCY_TYPE_CALL) {
                    setIsInEmergencyCall(true);
                }
                completeEmergencyMode(emergencyType);
            } else {
                // If emergency mode is set by SMS while the radio is ON and
                // the DDS switch condition is being checked, the emergency call should wait for
                // the emergency mode to be set.
                mIsEmergencyCallWaitingForEmergencyModeCompletion = true;
            }
        });
    }
@@ -1000,6 +1031,7 @@ public class EmergencyStateTracker {
        }
        mEmergencyMode = MODE_EMERGENCY_NONE;
        setEmergencyModeInProgress(true);
        mLastEmergencyRegistrationResult = null;

        Message m = mHandler.obtainMessage(
                MSG_EXIT_EMERGENCY_MODE_DONE, Integer.valueOf(emergencyType));
+131 −0
Original line number Diff line number Diff line
@@ -1906,6 +1906,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest {
        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
        assertTrue(emergencyStateTracker.isInEmergencyMode());
        assertTrue(emergencyStateTracker.isInEmergencyCall());
        assertEquals(E_REG_RESULT, emergencyStateTracker.getEmergencyRegistrationResult());
        // Expect: DisconnectCause#NOT_DISCONNECTED.
        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
@@ -1934,6 +1935,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest {

        assertFalse(smsFuture.isDone());
        assertFalse(callFuture.isDone());
        assertEquals(null, emergencyStateTracker.getEmergencyRegistrationResult());

        // Response message for setEmergencyMode by SMS.
        Message msg = smsCaptor.getValue();
@@ -1953,6 +1955,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest {
        msg.sendToTarget();
        processAllMessages();

        assertEquals(E_REG_RESULT, emergencyStateTracker.getEmergencyRegistrationResult());
        // Expect: DisconnectCause#NOT_DISCONNECTED
        assertEquals(smsFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
@@ -3695,6 +3698,134 @@ public class EmergencyStateTrackerTest extends TelephonyTest {
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
    }

    @Test
    @SmallTest
    public void testUseCachedEmergencyRegistrationResultForSmsFirstAndCall() {
        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
                /* isRadioOn= */ true);
        setUpAsyncResultForSetEmergencyMode(phone0, E_REG_RESULT);
        // Emergency SMS is being started.
        CompletableFuture<Integer> future = emergencyStateTracker.startEmergencySms(phone0,
                TEST_SMS_ID, false);
        processAllMessages();

        // SMS - Expect: DisconnectCause#NOT_DISCONNECTED.
        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));

        // Emergency call is being started.
        future = emergencyStateTracker.startEmergencyCall(phone0, mTestConnection1, false);
        assertFalse(future.isDone());

        processAllMessages();

        // Call - Expect: DisconnectCause#NOT_DISCONNECTED.
        assertEquals(future.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
        assertTrue(emergencyStateTracker.isInEmergencyCall());

        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
        assertEquals(E_REG_RESULT, emergencyStateTracker.getEmergencyRegistrationResult());
    }

    @Test
    @SmallTest
    public void testEmergencyCallWaitForEmergencyModeToComplete() {
        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
                /* isRadioOn= */ true);

        // Emergency call is being started.
        CompletableFuture<Integer> callFuture =
                emergencyStateTracker.startEmergencyCall(phone0, mTestConnection1, false);

        // Emergency SMS is being started.
        CompletableFuture<Integer> smsFuture = emergencyStateTracker.startEmergencySms(phone0,
                TEST_SMS_ID, false);

        assertFalse(callFuture.isDone());
        assertFalse(smsFuture.isDone());
        assertTrue(emergencyStateTracker.isInEmergencyMode());
        ArgumentCaptor<Message> smsCaptor = ArgumentCaptor.forClass(Message.class);
        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), smsCaptor.capture());

        // Waits for the response of emergency mode for both call and SMS.
        processAllMessages();

        assertFalse(emergencyStateTracker.isInEmergencyCall());

        // Response message for setEmergencyMode by SMS.
        Message msg = smsCaptor.getValue();
        AsyncResult.forMessage(msg, E_REG_RESULT, null);
        msg.sendToTarget();
        processAllMessages();

        // SMS - Expect: DisconnectCause#NOT_DISCONNECTED.
        assertTrue(smsFuture.isDone());
        assertEquals(smsFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));

        // Call - Expect: DisconnectCause#NOT_DISCONNECTED.
        assertTrue(callFuture.isDone());
        assertEquals(callFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
        assertTrue(emergencyStateTracker.isInEmergencyCall());

        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
        assertEquals(E_REG_RESULT, emergencyStateTracker.getEmergencyRegistrationResult());
    }

    @Test
    @SmallTest
    public void testEmergencyCallWaitForEmergencyModeToCompleteAndSmsEndedBeforeCompletion() {
        EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
                /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
        Phone phone0 = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
                /* isRadioOn= */ true);

        // Emergency call is being started.
        CompletableFuture<Integer> callFuture =
                emergencyStateTracker.startEmergencyCall(phone0, mTestConnection1, false);

        // Emergency SMS is being started.
        CompletableFuture<Integer> smsFuture = emergencyStateTracker.startEmergencySms(phone0,
                TEST_SMS_ID, false);

        assertFalse(callFuture.isDone());
        assertFalse(smsFuture.isDone());
        assertTrue(emergencyStateTracker.isInEmergencyMode());
        ArgumentCaptor<Message> smsCaptor = ArgumentCaptor.forClass(Message.class);
        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), smsCaptor.capture());

        // Waits for the response of emergency mode for both call and SMS.
        processAllMessages();

        assertFalse(emergencyStateTracker.isInEmergencyCall());

        emergencyStateTracker.endSms(TEST_SMS_ID, false, DOMAIN_PS, true);

        // Response message for setEmergencyMode by SMS.
        Message msg = smsCaptor.getValue();
        AsyncResult.forMessage(msg, E_REG_RESULT, null);
        msg.sendToTarget();
        processAllMessages();

        // SMS - Expect: Aborted.
        assertFalse(smsFuture.isDone());

        // Call - Expect: DisconnectCause#NOT_DISCONNECTED.
        assertTrue(callFuture.isDone());
        assertEquals(callFuture.getNow(DisconnectCause.ERROR_UNSPECIFIED),
                Integer.valueOf(DisconnectCause.NOT_DISCONNECTED));
        assertTrue(emergencyStateTracker.isInEmergencyCall());

        verify(phone0).setEmergencyMode(eq(MODE_EMERGENCY_WWAN), any(Message.class));
        assertEquals(E_REG_RESULT, emergencyStateTracker.getEmergencyRegistrationResult());
    }

    private EmergencyStateTracker setupEmergencyStateTracker(
            boolean isSuplDdsSwitchRequiredForEmergencyCall) {
        return setupEmergencyStateTracker(isSuplDdsSwitchRequiredForEmergencyCall, true, true);