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

Commit 9203ba4d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Skip switch data if cross-sim call active"

parents 013a98bb 3536b944
Loading
Loading
Loading
Loading
+53 −68
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.telephony.ims.RegistrationManager;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Log;

import com.android.ims.ImsException;
import com.android.ims.ImsManager;
@@ -119,7 +120,7 @@ import java.util.concurrent.CompletableFuture;
 */
public class PhoneSwitcher extends Handler {
    private static final String LOG_TAG = "PhoneSwitcher";
    protected static final boolean VDBG = false;
    protected static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);

    /** Fragment "key" argument passed thru {@link #SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS} */
    private static final String SETTINGS_EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
@@ -469,36 +470,14 @@ public class PhoneSwitcher extends Handler {
        return sPhoneSwitcher;
    }

    /**
     * Whether this phone IMS registration is on its original network. This result impacts
     * whether we want to do DDS switch to the phone having voice call.
     * If it's registered on IWLAN or cross SIM in multi-SIM case, return false. Otherwise,
     * return true.
     */
    private boolean isImsOnOriginalNetwork(Phone phone) {
        if (phone == null) return false;
        int phoneId = phone.getPhoneId();
        if (!SubscriptionManager.isValidPhoneId(phoneId)) return false;

        int imsRegTech = mImsRegTechProvider.get(mContext, phoneId);
        // If IMS is registered on IWLAN or cross SIM, return false.
        boolean isOnOriginalNetwork = (imsRegTech != REGISTRATION_TECH_IWLAN)
                && (imsRegTech != REGISTRATION_TECH_CROSS_SIM);
        if (!isOnOriginalNetwork) {
            logl("IMS call on IWLAN or cross SIM. Call will be ignored for DDS switch");
        }
        return isOnOriginalNetwork;
    }

    private boolean isPhoneInVoiceCallChanged() {
    private boolean updatesIfPhoneInVoiceCallChanged() {
        int oldPhoneIdInVoiceCall = mPhoneIdInVoiceCall;
        // If there's no active call, the value will become INVALID_PHONE_INDEX
        // and internet data will be switched back to system selected or user selected
        // subscription.
        mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;
        for (Phone phone : PhoneFactory.getPhones()) {
            if (isPhoneInVoiceCall(phone) || (isPhoneInVoiceCall(phone.getImsPhone())
                    && isImsOnOriginalNetwork(phone))) {
            if (isPhoneInVoiceCall(phone) || isPhoneInVoiceCall(phone.getImsPhone())) {
                mPhoneIdInVoiceCall = phone.getPhoneId();
                break;
            }
@@ -780,25 +759,25 @@ public class PhoneSwitcher extends Handler {
                onEvaluate(REQUESTS_UNCHANGED, EVALUATION_REASON_RADIO_ON);
                break;
            }
            case EVENT_IMS_RADIO_TECH_CHANGED:
            case EVENT_IMS_RADIO_TECH_CHANGED: {
                // register for radio tech change to listen to radio tech handover in case previous
                // attempt was not successful
                registerForImsRadioTechChange();
                // If the phoneId in voice call didn't change, do nothing.
                if (!isPhoneInVoiceCallChanged()) {
                    break;
                }
                // if voice call state changes or in voice call didn't change
                // but RAT changes(e.g. Iwlan -> cross sim), reevaluate for data switch.
                if (updatesIfPhoneInVoiceCallChanged() || isAnyVoiceCallActiveOnDevice()) {
                    evaluateIfImmediateDataSwitchIsNeeded("Ims radio tech changed",
                            DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                }
                break;

            }
            case EVENT_PRECISE_CALL_STATE_CHANGED: {
                // register for radio tech change to listen to radio tech handover in case previous
                // attempt was not successful
                registerForImsRadioTechChange();

                // If the phoneId in voice call didn't change, do nothing.
                if (!isPhoneInVoiceCallChanged()) {
                if (!updatesIfPhoneInVoiceCallChanged()) {
                    break;
                }

@@ -1606,27 +1585,9 @@ public class PhoneSwitcher extends Handler {
        }
    }

    private int getSubIdForDefaultNetworkRequests() {
        if (isActiveSubId(mAutoSelectedDataSubId)) {
            return mAutoSelectedDataSubId;
        } else {
            return mPrimaryDataSubId;
        }
    }

    // This updates mPreferredDataPhoneId which decides which phone should handle default network
    // requests.
    protected void updatePreferredDataPhoneId() {
        Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall);
        // check user enabled data on the default phone
        Phone defaultDataPhone = getPhoneBySubId(mPrimaryDataSubId);
        boolean isDataEnabled = false;
        if (voicePhone != null && defaultDataPhone != null
                && defaultDataPhone.isUserDataEnabled()) {
            // check voice during call feature is enabled
            isDataEnabled = voicePhone.isDataAllowed();
        }

        if (mEmergencyOverride != null && findPhoneById(mEmergencyOverride.mPhoneId) != null) {
            // Override DDS for emergency even if user data is not enabled, since it is an
            // emergency.
@@ -1636,29 +1597,53 @@ public class PhoneSwitcher extends Handler {
                    + " phoneId = " + mEmergencyOverride.mPhoneId);
            mPreferredDataPhoneId = mEmergencyOverride.mPhoneId;
            mLastSwitchPreferredDataReason = DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
        } else if (isDataEnabled) {
            // If a phone is in call and user enabled its mobile data, we
            // should switch internet connection to it. Because the other modem
            // will lose data connection anyway.
            mPreferredDataPhoneId = mPhoneIdInVoiceCall;
            mLastSwitchPreferredDataReason = DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL;
        } else {
            int subId = getSubIdForDefaultNetworkRequests();
            int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;

            if (SubscriptionManager.isUsableSubIdValue(subId)) {
                for (int i = 0; i < mActiveModemCount; i++) {
                    if (mPhoneSubscriptions[i] == subId) {
                        phoneId = i;
                        break;
            int imsRegTech = mImsRegTechProvider.get(mContext, mPhoneIdInVoiceCall);
            if (isAnyVoiceCallActiveOnDevice() && imsRegTech != REGISTRATION_TECH_IWLAN) {
                if (imsRegTech != REGISTRATION_TECH_CROSS_SIM) {
                    if (shouldSwitchDataDueToInCall()) mPreferredDataPhoneId = mPhoneIdInVoiceCall;
                } else {
                    logl("IMS call on cross-SIM, skip switching data to phone "
                            + mPhoneIdInVoiceCall);
                }
            } else {
                mPreferredDataPhoneId = getFallbackDataPhoneIdForInternetRequests();
            }
        }

            mPreferredDataPhoneId = phoneId;
        mPreferredDataSubId.set(SubscriptionManager.getSubscriptionId(mPreferredDataPhoneId));
    }

        mPreferredDataSubId.set(SubscriptionManager.getSubscriptionId(mPreferredDataPhoneId));
    /**
     * @return the default data phone Id (or auto selected phone Id in auto data switch/CBRS case)
     */
    private int getFallbackDataPhoneIdForInternetRequests() {
        int fallbackSubId = isActiveSubId(mAutoSelectedDataSubId)
                ? mAutoSelectedDataSubId : mPrimaryDataSubId;

        if (SubscriptionManager.isUsableSubIdValue(fallbackSubId)) {
            for (int phoneId = 0; phoneId < mActiveModemCount; phoneId++) {
                if (mPhoneSubscriptions[phoneId] == fallbackSubId) {
                    return phoneId;
                }
            }
        }
        return SubscriptionManager.INVALID_PHONE_INDEX;
    }

    /**
     * If a phone is in call and user enabled its mobile data and auto data switch feature, we
     * should switch internet connectionto it because the other modem will lose data connection
     * anyway.
     * @return {@code true} if should switch data to the phone in voice call
     */
    private boolean shouldSwitchDataDueToInCall() {
        Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall);
        Phone defaultDataPhone = getPhoneBySubId(mPrimaryDataSubId);
        return defaultDataPhone != null // check user enabled data
                && defaultDataPhone.isUserDataEnabled()
                && voicePhone != null // check user enabled voice during call feature
                && voicePhone.isDataAllowed();
    }

    protected void transitionToEmergencyPhone() {
+18 −7
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@ import java.util.concurrent.LinkedBlockingQueue;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class PhoneSwitcherTest extends TelephonyTest {
    private static final int AUTO_DATA_SWITCH_NOTIFICATION = 1;
    private static final int ACTIVE_PHONE_SWITCH = 1;
    private static final int EVENT_RADIO_ON = 108;
    private static final int EVENT_MODEM_COMMAND_DONE = 112;
@@ -1176,7 +1175,7 @@ public class PhoneSwitcherTest extends TelephonyTest {
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));

        // Phone2 has active call. So data switch to it.
        // Phone2 has active call, and data is on. So data switch to it.
        doReturn(true).when(mPhone).isUserDataEnabled();
        notifyDataEnabled(true);
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
@@ -1186,8 +1185,19 @@ public class PhoneSwitcherTest extends TelephonyTest {
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        clearInvocations(mMockRadioConfig);

        // Phone2 call ended. So data switch back to default data sub.
        // Phone2(nDDS) call ended. But Phone1 having cross-SIM call. Don't switch.
        mockImsRegTech(1, REGISTRATION_TECH_CROSS_SIM);
        notifyPhoneAsInIncomingCall(mPhone);
        notifyPhoneAsInactive(mPhone2);
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
        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);
        notifyPhoneAsInactive(mPhone);
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
@@ -1195,13 +1205,14 @@ public class PhoneSwitcherTest extends TelephonyTest {
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
        clearInvocations(mMockRadioConfig);

        // Phone2 has holding call, but data is turned off. So no data switching should happen.
        // Phone2 has holding call on VoWifi, no need to switch data
        mockImsRegTech(1, REGISTRATION_TECH_IWLAN);
        notifyPhoneAsInHoldingCall(mPhone2);
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
        assertTrue(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
        assertFalse(mPhoneSwitcherUT.shouldApplyNetworkRequest(
                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
    }