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

Commit cbdf4b37 authored by Malcolm Chen's avatar Malcolm Chen
Browse files

Switch to SIM with voice call on hold.

In DSDS mode, when a SIM is in voice call, we might switch data
to it if user wants to. There's an issue that we don't switch
if user places the call on hold, in which case the user actually
loses data connections. Here the fix is we also switch data if
there's a call on hold.

Bug: 136843023
Test: manual and unittest
Change-Id: I43e3423748dd6492c4961b08b4d8c4f99a9d75a4
parent 6ed38737
Loading
Loading
Loading
Loading
+10 −3
Original line number Original line Diff line number Diff line
@@ -321,7 +321,7 @@ public class PhoneSwitcher extends Handler {
        // subscription.
        // subscription.
        mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;
        mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;
        for (Phone phone : mPhones) {
        for (Phone phone : mPhones) {
            if (isCallActive(phone) || isCallActive(phone.getImsPhone())) {
            if (isPhoneInVoiceCall(phone) || isPhoneInVoiceCall(phone.getImsPhone())) {
                mPhoneIdInVoiceCall = phone.getPhoneId();
                mPhoneIdInVoiceCall = phone.getPhoneId();
                break;
                break;
            }
            }
@@ -1232,13 +1232,20 @@ public class PhoneSwitcher extends Handler {
                subId, needValidation ? 1 : 0, callback).sendToTarget();
                subId, needValidation ? 1 : 0, callback).sendToTarget();
    }
    }


    private boolean isCallActive(Phone phone) {
    private boolean isPhoneInVoiceCall(Phone phone) {
        if (phone == null) {
        if (phone == null) {
            return false;
            return false;
        }
        }


        // A phone in voice call might trigger data being switched to it.
        // We only report true if its precise call state is ACTIVE, ALERTING or HOLDING.
        // The reason is data switching is interrupting, so we only switch when necessary and
        // acknowledged by the users. For incoming call, we don't switch until answered
        // (RINGING -> ACTIVE), for outgoing call we don't switch until call is connected
        // in network (DIALING -> ALERTING).
        return (phone.getForegroundCall().getState() == Call.State.ACTIVE
        return (phone.getForegroundCall().getState() == Call.State.ACTIVE
                || phone.getForegroundCall().getState() == Call.State.ALERTING);
                || phone.getForegroundCall().getState() == Call.State.ALERTING
                || phone.getBackgroundCall().getState() == Call.State.HOLDING);
    }
    }


    private void updateHalCommandToUse() {
    private void updateHalCommandToUse() {
+16 −1
Original line number Original line Diff line number Diff line
@@ -91,6 +91,8 @@ public class PhoneSwitcherTest extends TelephonyTest {
    @Mock
    @Mock
    private GsmCdmaCall mActiveCall;
    private GsmCdmaCall mActiveCall;
    @Mock
    @Mock
    private GsmCdmaCall mHoldingCall;
    @Mock
    private GsmCdmaCall mInactiveCall;
    private GsmCdmaCall mInactiveCall;


    // The thread that mPhoneSwitcher will handle events in.
    // The thread that mPhoneSwitcher will handle events in.
@@ -116,6 +118,7 @@ public class PhoneSwitcherTest extends TelephonyTest {


        doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
        doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
        doReturn(Call.State.IDLE).when(mInactiveCall).getState();
        doReturn(Call.State.IDLE).when(mInactiveCall).getState();
        doReturn(Call.State.HOLDING).when(mHoldingCall).getState();
    }
    }


    @After
    @After
@@ -572,7 +575,6 @@ public class PhoneSwitcherTest extends TelephonyTest {
        notifyDataEnabled(false);
        notifyDataEnabled(false);
        notifyPhoneAsInCall(mPhone2);
        notifyPhoneAsInCall(mPhone2);
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
        waitABit();
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));


@@ -588,6 +590,13 @@ public class PhoneSwitcherTest extends TelephonyTest {
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        clearInvocations(mMockRadioConfig);

        // Phone2 has holding call, but data is turned off. So no data switching should happen.
        notifyPhoneAsInHoldingCall(mPhone2);
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));


        mHandlerThread.quit();
        mHandlerThread.quit();
    }
    }
@@ -878,6 +887,12 @@ public class PhoneSwitcherTest extends TelephonyTest {
        waitABit();
        waitABit();
    }
    }


    private void notifyPhoneAsInHoldingCall(Phone phone) {
        doReturn(mHoldingCall).when(phone).getBackgroundCall();
        mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);
        waitABit();
    }

    private void notifyPhoneAsInactive(Phone phone) {
    private void notifyPhoneAsInactive(Phone phone) {
        doReturn(mInactiveCall).when(phone).getForegroundCall();
        doReturn(mInactiveCall).when(phone).getForegroundCall();
        mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);
        mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);