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

Commit 8e3200a6 authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by Android (Google) Code Review
Browse files

Merge "Switch data to non default SIM if mobile data enabled and in call."

parents 0421d2a5 16c43000
Loading
Loading
Loading
Loading
+66 −13
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony;
package com.android.internal.telephony;


import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_PRECISE_CALL_STATE;
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -39,6 +40,7 @@ import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.RemoteException;
import android.telephony.PhoneCapability;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.PhoneStateListener;
import android.telephony.PreciseCallState;
import android.telephony.Rlog;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
@@ -76,7 +78,8 @@ public class PhoneSwitcher extends Handler {
    private final int mNumPhones;
    private final int mNumPhones;
    private final Phone[] mPhones;
    private final Phone[] mPhones;
    private final LocalLog mLocalLog;
    private final LocalLog mLocalLog;
    private final PhoneStateListener mPhoneStateListener;
    @VisibleForTesting
    public final PhoneStateListener mPhoneStateListener;


    private int mMaxActivePhones;
    private int mMaxActivePhones;
    private static PhoneSwitcher sPhoneSwitcher = null;
    private static PhoneSwitcher sPhoneSwitcher = null;
@@ -95,6 +98,8 @@ public class PhoneSwitcher extends Handler {
    // Corresponding phoneId after considerting mPreferredDataSubId and mDefaultDataSubId above.
    // Corresponding phoneId after considerting mPreferredDataSubId and mDefaultDataSubId above.
    protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
    protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;


    private int mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX;

    private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED   = 101;
    private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED   = 101;
    private static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
    private static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
    private static final int EVENT_REQUEST_NETWORK                = 103;
    private static final int EVENT_REQUEST_NETWORK                = 103;
@@ -103,6 +108,7 @@ public class PhoneSwitcher extends Handler {
    private static final int EVENT_RADIO_CAPABILITY_CHANGED       = 106;
    private static final int EVENT_RADIO_CAPABILITY_CHANGED       = 106;
    private static final int EVENT_PREFERRED_SUBSCRIPTION_CHANGED = 107;
    private static final int EVENT_PREFERRED_SUBSCRIPTION_CHANGED = 107;
    private static final int EVENT_RADIO_AVAILABLE                = 108;
    private static final int EVENT_RADIO_AVAILABLE                = 108;
    private static final int EVENT_PHONE_IN_CALL_CHANGED          = 109;


    // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's
    // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's
    // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse
    // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse
@@ -174,14 +180,38 @@ public class PhoneSwitcher extends Handler {
        mRadioConfig = RadioConfig.getInstance(mContext);
        mRadioConfig = RadioConfig.getInstance(mContext);


        mPhoneStateListener = new PhoneStateListener(looper) {
        mPhoneStateListener = new PhoneStateListener(looper) {
            @Override
            public void onPhoneCapabilityChanged(PhoneCapability capability) {
            public void onPhoneCapabilityChanged(PhoneCapability capability) {
                onPhoneCapabilityChangedInternal(capability);
                onPhoneCapabilityChangedInternal(capability);
            }
            }

            @Override
            public void onPreciseCallStateChanged(PreciseCallState callState) {
                int oldPhoneIdInCall = mPhoneIdInCall;
                // 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.
                mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX;
                for (Phone phone : mPhones) {
                    if (isCallActive(phone) || isCallActive(phone.getImsPhone())) {
                        mPhoneIdInCall = phone.getPhoneId();
                        break;
                    }
                }

                if (mPhoneIdInCall != oldPhoneIdInCall) {
                    log("mPhoneIdInCall changed from" + oldPhoneIdInCall
                            + " to " + mPhoneIdInCall);
                    Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED);
                    msg.sendToTarget();
                }
            }
        };
        };


        TelephonyManager telephonyManager =
        TelephonyManager telephonyManager =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(mPhoneStateListener, LISTEN_PHONE_CAPABILITY_CHANGE);
        telephonyManager.listen(mPhoneStateListener, LISTEN_PHONE_CAPABILITY_CHANGE
                | LISTEN_PRECISE_CALL_STATE);


        mActivePhoneRegistrants = new RegistrantList();
        mActivePhoneRegistrants = new RegistrantList();
        mPhoneStates = new PhoneState[numPhones];
        mPhoneStates = new PhoneState[numPhones];
@@ -282,6 +312,10 @@ public class PhoneSwitcher extends Handler {
                onEvaluate(REQUESTS_UNCHANGED, "EVENT_RADIO_AVAILABLE");
                onEvaluate(REQUESTS_UNCHANGED, "EVENT_RADIO_AVAILABLE");
                break;
                break;
            }
            }
            case EVENT_PHONE_IN_CALL_CHANGED: {
                onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED");
                break;
            }
        }
        }
    }
    }


@@ -404,7 +438,7 @@ public class PhoneSwitcher extends Handler {
                 */
                 */
                if (mMaxActivePhones == mPhones.length) {
                if (mMaxActivePhones == mPhones.length) {
                    for (int i = 0; i < mMaxActivePhones; i++) {
                    for (int i = 0; i < mMaxActivePhones; i++) {
                        newActivePhones.add(mPhones[i].mPhoneId);
                        newActivePhones.add(mPhones[i].getPhoneId());
                    }
                    }
                } else {
                } else {
                    for (DcRequest dcRequest : mPrioritizedDcRequests) {
                    for (DcRequest dcRequest : mPrioritizedDcRequests) {
@@ -571,6 +605,14 @@ public class PhoneSwitcher extends Handler {
    // This updates mPreferredDataPhoneId which decides which phone should
    // This updates mPreferredDataPhoneId which decides which phone should
    // handle default network requests.
    // handle default network requests.
    private void updatePhoneIdForDefaultNetworkRequests() {
    private void updatePhoneIdForDefaultNetworkRequests() {
        if (SubscriptionManager.isValidPhoneId(mPhoneIdInCall)) {
            // 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.
            // TODO: validate network first.

            mPreferredDataPhoneId = mPhoneIdInCall;
        } else {
            int subId = getSubIdForDefaultNetworkRequests();
            int subId = getSubIdForDefaultNetworkRequests();
            int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
            int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;


@@ -585,6 +627,7 @@ public class PhoneSwitcher extends Handler {


            mPreferredDataPhoneId = phoneId;
            mPreferredDataPhoneId = phoneId;
        }
        }
    }


    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
        validatePhoneId(phoneId);
        validatePhoneId(phoneId);
@@ -636,6 +679,16 @@ public class PhoneSwitcher extends Handler {
        }
        }
    }
    }


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

        return (phone.getForegroundCall().getState() == Call.State.ACTIVE
                || phone.getBackgroundCall().getState() == Call.State.ACTIVE
                || phone.getRingingCall().getState() == Call.State.ACTIVE);
    }

    private void updateHalCommandToUse() {
    private void updateHalCommandToUse() {
        mHalCommandToUse = mRadioConfig.isSetPreferredDataCommandSupported()
        mHalCommandToUse = mRadioConfig.isSetPreferredDataCommandSupported()
                ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
                ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
+58 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,10 @@ public class PhoneSwitcherTest extends TelephonyTest {
    private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
    private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
    @Mock
    @Mock
    private Handler mActivePhoneSwitchHandler;
    private Handler mActivePhoneSwitchHandler;
    @Mock
    private GsmCdmaCall mActiveCall;
    @Mock
    private GsmCdmaCall mInactiveCall;


    // The thread that mPhoneSwitcher will handle events in.
    // The thread that mPhoneSwitcher will handle events in.
    private HandlerThread mHandlerThread;
    private HandlerThread mHandlerThread;
@@ -463,6 +467,57 @@ public class PhoneSwitcherTest extends TelephonyTest {


    }
    }


    @Test
    @SmallTest
    public void testNonDefaultDataPhoneInCall() throws Exception {
        final int numPhones = 2;
        final int maxActivePhones = 1;
        doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
        initialize(numPhones, maxActivePhones);
        // 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);
        waitABit();
        NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
        waitABit();
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        clearInvocations(mMockRadioConfig);

        doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
        doReturn(Call.State.IDLE).when(mInactiveCall).getState();
        doReturn(mInactiveCall).when(mPhone).getForegroundCall();
        doReturn(mInactiveCall).when(mPhone).getBackgroundCall();
        doReturn(mInactiveCall).when(mPhone).getRingingCall();
        doReturn(mInactiveCall).when(mPhone2).getForegroundCall();
        doReturn(mInactiveCall).when(mPhone2).getBackgroundCall();
        doReturn(mInactiveCall).when(mPhone2).getRingingCall();

        // Initialization done.

        // Phone2 has active call. So data switch to it.
        doReturn(mActiveCall).when(mPhone2).getForegroundCall();
        mPhoneSwitcher.mPhoneStateListener.onPreciseCallStateChanged(null);
        waitABit();
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        clearInvocations(mMockRadioConfig);

        // Phone2 call ended. So data switch back to default data sub.
        doReturn(mInactiveCall).when(mPhone2).getForegroundCall();
        mPhoneSwitcher.mPhoneStateListener.onPreciseCallStateChanged(null);
        waitABit();
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));

        mHandlerThread.quit();
    }

    /* Private utility methods start here */
    /* Private utility methods start here */


    private void sendDefaultDataSubChanged() {
    private void sendDefaultDataSubChanged() {
@@ -503,11 +558,14 @@ public class PhoneSwitcherTest extends TelephonyTest {
    private void setNumPhones(int numPhones) {
    private void setNumPhones(int numPhones) {
        mDataAllowed = new boolean[numPhones];
        mDataAllowed = new boolean[numPhones];
        mSlotIndexToSubId = new int[numPhones][];
        mSlotIndexToSubId = new int[numPhones][];
        doReturn(0).when(mPhone).getPhoneId();
        doReturn(1).when(mPhone2).getPhoneId();
        for (int i = 0; i < numPhones; i++) {
        for (int i = 0; i < numPhones; i++) {
            mSlotIndexToSubId[i] = new int[1];
            mSlotIndexToSubId[i] = new int[1];
            mSlotIndexToSubId[i][0] = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
            mSlotIndexToSubId[i][0] = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        }
        }


        doReturn(numPhones).when(mTelephonyManager).getPhoneCount();
        if (numPhones == 1) {
        if (numPhones == 1) {
            mCommandsInterfaces = new CommandsInterface[] {mCommandsInterface0};
            mCommandsInterfaces = new CommandsInterface[] {mCommandsInterface0};
            mPhones = new Phone[] {mPhone};
            mPhones = new Phone[] {mPhone};