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

Commit 4d5d10c2 authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by Gerrit Code Review
Browse files

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

parents b231b210 c164fda2
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};