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

Commit 9bbe74ba authored by Hwangoo Park's avatar Hwangoo Park
Browse files

Ignore ECBM enter/exit event on Phone when domain selection supports

Basically, the ImsService/modem should not be sending the ECBM enter
event when domain selection is enabled. However, if the ImsService/modem
sends the ECBM enter event, the framework may malfunction.
In order to avoid this unexpected behavior, the existing implementation
for ECBM enter/exit event handling will be ignored on
ImsPhone/GsmCdmaPhone when domain selection is enabled. Instead, this
ECBM enter/exit event will be handled by the EmergencyStateTracker when
domain selection is enabled.

Bug: 270674175
Test: atest GsmCdmaPhoneTest, ImsPhoneTest
Change-Id: I589bc27046e1b1633548e0f13c5c9efed88922aa
parent 22313bfc
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.emergency.EmergencyStateTracker;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.gsm.SsData;
import com.android.internal.telephony.gsm.SuppServiceNotification;
@@ -517,9 +518,13 @@ public class GsmCdmaPhone extends Phone {
            // This is needed to handle phone process crashes
            mIsPhoneInEcmState = getInEcmMode();
            if (mIsPhoneInEcmState) {
                if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
                    EmergencyStateTracker.getInstance().exitEmergencyCallbackMode();
                } else {
                    // Send a message which will invoke handleExitEmergencyCallbackMode
                    mCi.exitEmergencyCallbackMode(null);
                }
            }

            mCi.setPhoneType(PhoneConstants.PHONE_TYPE_CDMA);
            tm.setPhoneType(getPhoneId(), PhoneConstants.PHONE_TYPE_CDMA);
@@ -3135,6 +3140,9 @@ public class GsmCdmaPhone extends Phone {
                logd("Event EVENT_MODEM_RESET Received" + " isInEcm = " + isInEcm()
                        + " isPhoneTypeGsm = " + isPhoneTypeGsm() + " mImsPhone = " + mImsPhone);
                if (isInEcm()) {
                    if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
                        EmergencyStateTracker.getInstance().exitEmergencyCallbackMode();
                    } else {
                        if (isPhoneTypeGsm()) {
                            if (mImsPhone != null) {
                                mImsPhone.handleExitEmergencyCallbackMode();
@@ -3144,6 +3152,7 @@ public class GsmCdmaPhone extends Phone {
                        }
                    }
                }
            }
            break;

            case EVENT_RUIM_RECORDS_LOADED:
@@ -3913,6 +3922,10 @@ public class GsmCdmaPhone extends Phone {

    //CDMA
    private void handleEnterEmergencyCallbackMode(Message msg) {
        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
            Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM enter event.");
            return;
        }
        if (DBG) {
            Rlog.d(LOG_TAG, "handleEnterEmergencyCallbackMode, isInEcm()="
                    + isInEcm());
@@ -3936,6 +3949,10 @@ public class GsmCdmaPhone extends Phone {

    //CDMA
    private void handleExitEmergencyCallbackMode(Message msg) {
        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
            Rlog.d(LOG_TAG, "DomainSelection enabled: ignore ECBM exit event.");
            return;
        }
        AsyncResult ar = (AsyncResult)msg.obj;
        if (DBG) {
            Rlog.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , isInEcm="
+8 −0
Original line number Diff line number Diff line
@@ -2059,6 +2059,10 @@ public class ImsPhone extends ImsPhoneBase {

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private void handleEnterEmergencyCallbackMode() {
        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
            logd("DomainSelection enabled: ignore ECBM enter event.");
            return;
        }
        if (DBG) logd("handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= " + isInEcm());
        // if phone is not in Ecm mode, and it's changed to Ecm mode
        if (!isInEcm()) {
@@ -2080,6 +2084,10 @@ public class ImsPhone extends ImsPhoneBase {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    @Override
    protected void handleExitEmergencyCallbackMode() {
        if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
            logd("DomainSelection enabled: ignore ECBM exit event.");
            return;
        }
        if (DBG) logd("handleExitEmergencyCallbackMode: mIsPhoneInEcmState = " + isInEcm());

        if (isInEcm()) {
+95 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ import android.util.Log;
import androidx.test.filters.FlakyTest;

import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyStateTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -2479,4 +2480,98 @@ public class GsmCdmaPhoneTest extends TelephonyTest {
                nullable(Message.class));
        assertEquals(0, captureBitMask.getValue() & TelephonyManager.NETWORK_CLASS_BITMASK_2G);
    }

    @Test
    @SmallTest
    public void testEcbm() throws Exception {
        assertFalse(mPhoneUT.isInEcm());

        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));

        assertTrue(mPhoneUT.isInEcm());
        verifyEcbmIntentWasSent(1 /*times*/, true /*inEcm*/);
        // verify that wakeLock is acquired in ECM
        assertTrue(mPhoneUT.getWakeLock().isHeld());

        boolean isTestingEmergencyCallbackMode = true;
        replaceInstance(GsmCdmaPhone.class, "mIsTestingEmergencyCallbackMode", mPhoneUT,
                isTestingEmergencyCallbackMode);
        mPhoneUT.exitEmergencyCallbackMode();
        processAllMessages();

        assertFalse(mPhoneUT.isInEcm());
        verifyEcbmIntentWasSent(2/*times*/, false /*inEcm*/);
        // verify wakeLock released
        assertFalse(mPhoneUT.getWakeLock().isHeld());
    }

    private void verifyEcbmIntentWasSent(int times, boolean isInEcm) throws Exception {
        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, atLeast(times)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
                any());

        Intent intent = intentArgumentCaptor.getValue();
        assertNotNull(intent);
        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
        assertEquals(isInEcm, intent.getBooleanExtra(
                TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
    }

    @Test
    @SmallTest
    public void testEcbmWhenDomainSelectionEnabled() throws Exception {
        DomainSelectionResolver dsResolver = Mockito.mock(DomainSelectionResolver.class);
        doReturn(true).when(dsResolver).isDomainSelectionSupported();
        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);

        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));

        boolean isTestingEmergencyCallbackMode = true;
        replaceInstance(GsmCdmaPhone.class, "mIsTestingEmergencyCallbackMode", mPhoneUT,
                isTestingEmergencyCallbackMode);
        mPhoneUT.exitEmergencyCallbackMode();
        processAllMessages();

        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
    }

    @Test
    @SmallTest
    public void testEcbmOnModemResetForNonGsmPhone() throws Exception {
        switchToCdma();
        assertFalse(mPhoneUT.isInEcm());

        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(
                GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER));

        assertTrue(mPhoneUT.isInEcm());

        Message m = mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_MODEM_RESET);
        AsyncResult.forMessage(m);
        mPhoneUT.handleMessage(m);

        assertFalse(mPhoneUT.isInEcm());
        verifyEcbmIntentWasSent(2 /*times*/, false /*inEcm*/);
    }

    @Test
    @SmallTest
    public void testEcbmOnModemResetWhenDomainSelectionEnabled() throws Exception {
        DomainSelectionResolver dsResolver = Mockito.mock(DomainSelectionResolver.class);
        doReturn(true).when(dsResolver).isDomainSelectionSupported();
        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);

        EmergencyStateTracker est = Mockito.mock(EmergencyStateTracker.class);
        doReturn(true).when(est).isInEcm();
        replaceInstance(EmergencyStateTracker.class, "INSTANCE", null, est);

        GsmCdmaPhone spyPhone = spy(mPhoneUT);
        doReturn(true).when(spyPhone).isInEcm();
        mPhoneUT.handleMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_MODEM_RESET));

        verify(est).exitEmergencyCallbackMode();
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -646,6 +646,21 @@ public class ImsPhoneTest extends TelephonyTest {
                TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
    }

    @Test
    @SmallTest
    public void testEcbmWhenDomainSelectionEnabled() {
        DomainSelectionResolver dsResolver = mock(DomainSelectionResolver.class);
        doReturn(true).when(dsResolver).isDomainSelectionSupported();
        DomainSelectionResolver.setDomainSelectionResolver(dsResolver);

        ImsEcbmStateListener imsEcbmStateListener = mImsPhoneUT.getImsEcbmStateListener();
        imsEcbmStateListener.onECBMEntered();
        imsEcbmStateListener.onECBMExited();

        verify(mPhone, never()).setIsInEcm(anyBoolean());
        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
    }

    @Test
    @SmallTest
    public void testProcessDisconnectReason() throws Exception {