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

Commit 27866ad9 authored by Ling Ma's avatar Ling Ma Committed by Jack Yu
Browse files

Evaluate auto data switch upon hangup voice call

Upon hangup voice call, reevalute whether we should auto data switch.
Also clean up the dataEnableChanged event interacting with voice call: Before the change, if data is disabled during call, the expected behavior is that user loses access to data immediately during call, but the previous behavior is that user still has data access.

Fix: 262335341
Test: atest + toggle mobile data during call

Merged-In: Iabfa73c70e344b4f49950a9a495edf6f00f8b144
Change-Id: Iabfa73c70e344b4f49950a9a495edf6f00f8b144
parent 21c9ea90
Loading
Loading
Loading
Loading
+32 −20
Original line number Diff line number Diff line
@@ -561,8 +561,7 @@ public class PhoneSwitcher extends Handler {
                            public void onDataEnabledChanged(boolean enabled,
                                    @TelephonyManager.DataEnabledChangedReason int reason,
                                    @NonNull String callingPackage) {
                                logl("user changed data settings");
                                evaluateIfAutoSwitchIsNeeded();
                                PhoneSwitcher.this.onDataEnabledChanged();
                            }});
                phone.getDataSettingsManager().registerCallback(
                        mDataSettingsManagerCallbacks.get(phoneId));
@@ -806,8 +805,14 @@ public class PhoneSwitcher extends Handler {
                        mEmergencyOverride.mPendingOriginatingCall = false;
                    }
                }
                // Always update data modem via data during call code path, because
                // mAutoSelectedDataSubId doesn't know about any data switch due to voice call
                evaluateIfImmediateDataSwitchIsNeeded("precise call state changed",
                        DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                if (!isAnyVoiceCallActiveOnDevice()) {
                    // consider auto switch on hang up all voice call
                    evaluateIfAutoSwitchIsNeeded();
                }
                break;
            }
            case EVENT_NETWORK_VALIDATION_DONE: {
@@ -974,10 +979,7 @@ public class PhoneSwitcher extends Handler {
                        public void onDataEnabledChanged(boolean enabled,
                                @TelephonyManager.DataEnabledChangedReason int reason,
                                @NonNull String callingPackage) {
                            logl("user changed data settings");
                            evaluateIfImmediateDataSwitchIsNeeded("user changed data settings",
                                    DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                            evaluateIfAutoSwitchIsNeeded();
                            PhoneSwitcher.this.onDataEnabledChanged();
                        }
                    });
            phone.getDataSettingsManager().registerCallback(
@@ -991,6 +993,23 @@ public class PhoneSwitcher extends Handler {
        }
    }

    /**
     * Called when
     * 1. user changed mobile data settings
     * 2. OR user changed auto data switch feature
     */
    private void onDataEnabledChanged() {
        logl("user changed data related settings");
        if (isAnyVoiceCallActiveOnDevice()) {
            // user changed data related settings during call, switch or turn off immediately
            evaluateIfImmediateDataSwitchIsNeeded(
                    "user changed data settings during call",
                    DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
        } else {
            evaluateIfAutoSwitchIsNeeded();
        }
    }

    private boolean isInEmergencyCallbackMode() {
        for (Phone p : PhoneFactory.getPhones()) {
            if (p == null) continue;
@@ -1131,14 +1150,6 @@ public class PhoneSwitcher extends Handler {
        if (mPreferredDataPhoneId == primaryPhoneId) {
            // on primary data sub

            if (isAnyVoiceCallActiveOnDevice()) {
                // if on voice call, switch immediately
                evaluateIfImmediateDataSwitchIsNeeded(
                        "user updates data settings during voice call",
                        DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                return;
            }

            int candidateSubId = getAutoSwitchTargetSubIdIfExists();
            if (candidateSubId != INVALID_SUBSCRIPTION_ID) {
                startAutoDataSwitchStabilityCheck(candidateSubId, true);
@@ -1357,7 +1368,7 @@ public class PhoneSwitcher extends Handler {
        if (hasAnyActiveSubscription) updatePreferredDataPhoneId();

        if (oldPreferredDataPhoneId != mPreferredDataPhoneId) {
            sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId)
            sb.append(" preferred data phoneId ").append(oldPreferredDataPhoneId)
                    .append("->").append(mPreferredDataPhoneId);
            diffDetected = true;
        } else if (oldPreferredDataSubId != mPreferredDataSubId.get()) {
@@ -1605,7 +1616,8 @@ public class PhoneSwitcher extends Handler {
            int imsRegTech = mImsRegTechProvider.get(mContext, mPhoneIdInVoiceCall);
            if (isAnyVoiceCallActiveOnDevice() && imsRegTech != REGISTRATION_TECH_IWLAN) {
                if (imsRegTech != REGISTRATION_TECH_CROSS_SIM) {
                    if (shouldSwitchDataDueToInCall()) mPreferredDataPhoneId = mPhoneIdInVoiceCall;
                    mPreferredDataPhoneId = shouldSwitchDataDueToInCall()
                            ? mPhoneIdInVoiceCall : getFallbackDataPhoneIdForInternetRequests();
                } else {
                    logl("IMS call on cross-SIM, skip switching data to phone "
                            + mPhoneIdInVoiceCall);
+66 −30
Original line number Diff line number Diff line
@@ -748,8 +748,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
     * The following events can set preferred data subId with priority in the order of
     * 1. Emergency call
     * 2. Voice call (when data during call feature is enabled).
     * 3. CBRS requests
     * 4. Auto switch requests
     * 3. CBRS requests OR Auto switch requests - only one case applies at a time
     */
    @Test
    @SmallTest
@@ -762,6 +761,8 @@ public class PhoneSwitcherTest extends TelephonyTest {
        // Both are active subscriptions are active sub, as they are in both active slots.
        setSlotIndexToSubId(0, 1);
        setSlotIndexToSubId(1, 2);
        // single visible sub, as the other one is CBRS
        doReturn(new int[1]).when(mSubscriptionController).getActiveSubIdList(true);
        setDefaultDataSubId(1);

        // Notify phoneSwitcher about default data sub and default network request.
@@ -1000,14 +1001,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mockImsRegTech(1, REGISTRATION_TECH_LTE);
        notifyPhoneAsInCall(mImsPhone);

        // Phone 0 should be the default data phoneId.
        assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId());

        // User turns on data on Phone 0
        doReturn(true).when(mPhone).isUserDataEnabled();
        notifyDataEnabled(true);

        // Phone 1 should become the default data phone.
        // Phone 1 should become the preferred data phone.
        assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId());
    }

@@ -1036,14 +1030,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mockImsRegTech(1, REGISTRATION_TECH_LTE);
        notifyPhoneAsInDial(mImsPhone);

        // Phone 0 should be the default data phoneId.
        assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId());

        // User turns on data on Phone 0
        doReturn(true).when(mPhone).isUserDataEnabled();
        notifyDataEnabled(true);

        // Phone 1 should become the default data phone.
        // Phone2 should be preferred data phone
        assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId());
    }
    @Test
@@ -1071,14 +1058,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mockImsRegTech(1, REGISTRATION_TECH_LTE);
        notifyPhoneAsInIncomingCall(mImsPhone);

        // Phone 0 should be the default data phoneId.
        assertEquals(0, mPhoneSwitcherUT.getPreferredDataPhoneId());

        // User turns on data on Phone 0
        doReturn(true).when(mPhone).isUserDataEnabled();
        notifyDataEnabled(true);

        // Phone 1 should become the default data phone.
        // Phone 1 should become the preferred data phone.
        assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId());
    }

@@ -1186,7 +1166,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
        clearInvocations(mMockRadioConfig);

        // Phone2(nDDS) call ended. But Phone1 having cross-SIM call. Don't switch.
        mockImsRegTech(1, REGISTRATION_TECH_CROSS_SIM);
        mockImsRegTech(0, REGISTRATION_TECH_CROSS_SIM);
        notifyPhoneAsInIncomingCall(mPhone);
        notifyPhoneAsInactive(mPhone2);
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
@@ -1195,17 +1175,28 @@ public class PhoneSwitcherTest extends TelephonyTest {
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));

        // Phone1(DDS) call ended. So data switch back to default data sub.
        mockImsRegTech(0, REGISTRATION_TECH_IWLAN);
        // Phone(DDS) call ended.
        // Honor auto data switch's suggestion: if DDS is OOS, auto switch to Phone2(nDDS).
        serviceStateChanged(1, NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
        serviceStateChanged(0, NetworkRegistrationInfo
                .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
        doReturn(null).when(mConnectivityManager).getNetworkCapabilities(any());
        notifyPhoneAsInactive(mPhone);

        // verify immediately switch back to DDS upon call ends
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
        clearInvocations(mMockRadioConfig);

        // verify the attempt to do auto data switch to Phone2(nDDS)
        processAllFutureMessages();
        verify(mCellularNetworkValidator).validate(eq(2), anyLong(), eq(false),
                eq(mPhoneSwitcherUT.mValidationCallback));

        // Phone2 has holding call on VoWifi, no need to switch data
        clearInvocations(mMockRadioConfig);
        mockImsRegTech(1, REGISTRATION_TECH_IWLAN);
        notifyPhoneAsInHoldingCall(mPhone2);
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
@@ -1215,6 +1206,43 @@ public class PhoneSwitcherTest extends TelephonyTest {
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
    }

    @Test
    @SmallTest
    public void testDataEnabledChangedDuringVoiceCall() throws Exception {
        doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
        initialize();
        // Phone 0 has sub 1, phone 1 has sub 2.
        // Sub 1 is default data sub.
        // Both are active subscriptions are active sub, as they are in both active slots.
        setSlotIndexToSubId(0, 1);
        setSlotIndexToSubId(1, 2);
        setDefaultDataSubId(1);
        NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
        clearInvocations(mMockRadioConfig);
        setAllPhonesInactive();
        // Initialization done.

        // Phone2 has active call and data is on. So switch to nDDS Phone2
        notifyDataEnabled(true);
        notifyPhoneAsInCall(mPhone2);
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));

        // During the active call, user turns off data, should immediately switch back to DDS
        notifyDataEnabled(false);
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
    }

    @Test
    @SmallTest
@@ -1810,6 +1838,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
    }

    private void notifyDataEnabled(boolean dataEnabled) {
        doReturn(true).when(mPhone).isUserDataEnabled();
        doReturn(dataEnabled).when(mDataSettingsManager).isDataEnabled();
        doReturn(dataEnabled).when(mPhone2).isDataAllowed();
        mDataSettingsManagerCallbacks.get(0).onDataEnabledChanged(dataEnabled, 123 , "");
@@ -2044,6 +2073,13 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mDefaultDataSub = defaultDataSub;
        doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId();
        doReturn(mDefaultDataSub).when(mMockedIsub).getDefaultDataSubId();
        if (defaultDataSub == 1) {
            doReturn(true).when(mPhone).isUserDataEnabled();
            doReturn(false).when(mPhone2).isUserDataEnabled();
        } else {
            doReturn(false).when(mPhone).isUserDataEnabled();
            doReturn(true).when(mPhone2).isUserDataEnabled();
        }
        sendDefaultDataSubChanged();
    }