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

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

Don't apply Internet network request specified on non-default sub.

Cellular network requests may specify a subscription ID. However
if the requests is asking for Internet capability, network factory
should ignore it if it's not targeted on preferred data phone.

In implementation, TelephonyNetworkFactory is refactored so that
it queries a PhoneSwitcher API on every network request to decide
whether it should be applied or not. This way PhoneSwitcher has
better control of distrubuting network requests more flexibly.

Bug: 121094781
Test: unittest
Change-Id: I49f8702b19c0bd0f559cf9a97b3d0fa41f6f7222
parent c7a05f68
Loading
Loading
Loading
Loading
+57 −38
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony;

import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;

@@ -137,18 +138,18 @@ public class PhoneSwitcher extends Handler {
    }

    @VisibleForTesting
    public PhoneSwitcher(Looper looper) {
    public PhoneSwitcher(int numPhones, Looper looper) {
        super(looper);
        mMaxActivePhones = 0;
        mSubscriptionController = null;
        mPhoneSubscriptions = null;
        mCommandsInterfaces = null;
        mContext = null;
        mPhoneStates = null;
        mPhones = null;
        mLocalLog = null;
        mActivePhoneRegistrants = null;
        mNumPhones = 0;
        mNumPhones = numPhones;
        mPhoneSubscriptions = new int[numPhones];
        mRadioConfig = RadioConfig.getInstance(mContext);
        mPhoneStateListener = new PhoneStateListener(looper) {
            public void onPhoneCapabilityChanged(PhoneCapability capability) {
@@ -385,6 +386,11 @@ public class PhoneSwitcher extends Handler {
        if (diffDetected) {
            log("evaluating due to " + sb.toString());
            if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
                // With HAL_COMMAND_PREFERRED_DATA, all phones are assumed to allow PS attach.
                // So marking all phone as active.
                for (int phoneId = 0; phoneId < mNumPhones; phoneId++) {
                    activate(phoneId);
                }
                if (SubscriptionManager.isUsableSubIdValue(mPreferredDataPhoneId)) {
                    mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
                }
@@ -485,7 +491,7 @@ public class PhoneSwitcher extends Handler {
        if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
            // Skip ALLOW_DATA for single SIM device
            if (mNumPhones > 1) {
                mCommandsInterfaces[phoneId].setDataAllowed(mPhoneStates[phoneId].active, null);
                mCommandsInterfaces[phoneId].setDataAllowed(isPhoneActive(phoneId), null);
            }
        } else {
            mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
@@ -503,9 +509,38 @@ public class PhoneSwitcher extends Handler {
    }

    private int phoneIdForRequest(NetworkRequest netRequest) {
        NetworkSpecifier specifier = netRequest.networkCapabilities.getNetworkSpecifier();
        int subId = getSubIdFromNetworkRequest(netRequest);

        if (subId == DEFAULT_SUBSCRIPTION_ID) return mPreferredDataPhoneId;
        if (subId == INVALID_SUBSCRIPTION_ID) return INVALID_PHONE_INDEX;

        int preferredDataSubId = SubscriptionManager.isValidPhoneId(mPreferredDataPhoneId)
                ? mPhoneSubscriptions[mPreferredDataPhoneId] : INVALID_SUBSCRIPTION_ID;
        // Currently we assume multi-SIM devices will only support one Internet PDN connection. So
        // if Internet PDN is established on the non-preferred phone, it will interrupt
        // Internet connection on the preferred phone. So we only accept Internet request with
        // preferred data subscription or no specified subscription.
        if (netRequest.networkCapabilities.hasCapability(
                NetworkCapabilities.NET_CAPABILITY_INTERNET) && subId != preferredDataSubId) {
            // Returning INVALID_PHONE_INDEX will result in netRequest not being handled.
            return INVALID_PHONE_INDEX;
        }

        // Try to find matching phone ID. If it doesn't exist, we'll end up returning INVALID.
        int phoneId = INVALID_PHONE_INDEX;
        for (int i = 0; i < mNumPhones; i++) {
            if (mPhoneSubscriptions[i] == subId) {
                phoneId = i;
                break;
            }
        }
        return phoneId;
    }

    private int getSubIdFromNetworkRequest(NetworkRequest networkRequest) {
        NetworkSpecifier specifier = networkRequest.networkCapabilities.getNetworkSpecifier();
        if (specifier == null) {
            return mPreferredDataPhoneId;
            return DEFAULT_SUBSCRIPTION_ID;
        }

        int subId;
@@ -516,22 +551,13 @@ public class PhoneSwitcher extends Handler {
            } catch (NumberFormatException e) {
                Rlog.e(LOG_TAG, "NumberFormatException on "
                        + ((StringNetworkSpecifier) specifier).specifier);
                subId = INVALID_SUBSCRIPTION_ID;
                return INVALID_SUBSCRIPTION_ID;
            }
        } else {
            subId = INVALID_SUBSCRIPTION_ID;
            return INVALID_SUBSCRIPTION_ID;
        }

        int phoneId = INVALID_PHONE_INDEX;
        if (subId == INVALID_SUBSCRIPTION_ID) return phoneId;

        for (int i = 0 ; i < mNumPhones; i++) {
            if (mPhoneSubscriptions[i] == subId) {
                phoneId = i;
                break;
            }
        }
        return phoneId;
        return subId;
    }

    private int getSubIdForDefaultNetworkRequests() {
@@ -560,28 +586,20 @@ public class PhoneSwitcher extends Handler {
        mPreferredDataPhoneId = phoneId;
    }

    /**
     * Returns whether phone should handle network requests
     * that don't specify a subId.
     */
    public boolean shouldApplyUnspecifiedRequests(int phoneId) {
    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
        validatePhoneId(phoneId);
        if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
            return phoneId == mPreferredDataPhoneId;
        } else {
            return mPhoneStates[phoneId].active && phoneId == mPreferredDataPhoneId;
        }

        // In any case, if phone state is inactive, don't apply the network request.
        if (!isPhoneActive(phoneId)) return false;

        int phoneIdToHandle = phoneIdForRequest(networkRequest);

        return phoneId == phoneIdToHandle;
    }

    /**
     * Returns whether phone should handle network requests
     * that specify a subId.
     */
    public boolean shouldApplySpecifiedRequests(int phoneId) {
        validatePhoneId(phoneId);
        // If we use SET_PREFERRED_DATA, always apply specified network requests. Otherwise,
        // only apply network requests if the phone is active (dataAllowed).
        return mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA || mPhoneStates[phoneId].active;
    @VisibleForTesting
    protected boolean isPhoneActive(int phoneId) {
        return mPhoneStates[phoneId].active;
    }

    /**
@@ -598,7 +616,8 @@ public class PhoneSwitcher extends Handler {
        mActivePhoneRegistrants.remove(h);
    }

    private void validatePhoneId(int phoneId) {
    @VisibleForTesting
    protected void validatePhoneId(int phoneId) {
        if (phoneId < 0 || phoneId >= mNumPhones) {
            throw new IllegalArgumentException("Invalid PhoneId");
        }
+55 −97
Original line number Diff line number Diff line
@@ -43,22 +43,22 @@ public class TelephonyNetworkFactory extends NetworkFactory {
    public final String LOG_TAG;
    protected static final boolean DBG = true;

    private static final int REQUEST_LOG_SIZE = 40;

    private static final int ACTION_NO_OP   = 0;
    private static final int ACTION_REQUEST = 1;
    private static final int ACTION_RELEASE = 2;

    private final PhoneSwitcher mPhoneSwitcher;
    private final SubscriptionController mSubscriptionController;
    private final SubscriptionMonitor mSubscriptionMonitor;
    private final DcTracker mDcTracker;
    private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);

    private final HashMap<NetworkRequest, LocalLog> mDefaultRequests =
            new HashMap<NetworkRequest, LocalLog>();
    private final HashMap<NetworkRequest, LocalLog> mSpecificRequests =
            new HashMap<NetworkRequest, LocalLog>();
    // Key: network request. Value: whether it's applied to DcTracker.
    private final HashMap<NetworkRequest, Boolean> mNetworkRequests = new HashMap();

    private final Phone mPhone;
    // Only when this network factory is active, it will apply any network requests.
    private boolean mIsActive;
    // Whether this network factory is active and should handle default network requests.
    // Default network requests are those that don't specify subscription ID.
    private boolean mIsActiveForDefault;
    private int mSubscriptionId;

    private final static int TELEPHONY_NETWORK_SCORE = 50;
@@ -88,7 +88,6 @@ public class TelephonyNetworkFactory extends NetworkFactory {
        // the future. For now we route everything to WWAN.
        mDcTracker = mPhone.getDcTracker(TransportType.WWAN);

        mIsActive = false;
        mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH,
                null);

@@ -96,8 +95,6 @@ public class TelephonyNetworkFactory extends NetworkFactory {
        mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler,
                EVENT_SUBSCRIPTION_CHANGED, null);

        mIsActiveForDefault = false;

        register();
    }

@@ -154,24 +151,17 @@ public class TelephonyNetworkFactory extends NetworkFactory {
        }
    }

    private static final int REQUEST_LOG_SIZE = 40;

    private static final int ACTION_NO_OP   = 0;
    private static final int ACTION_REQUEST = 1;
    private static final int ACTION_RELEASE = 2;

    private void applyRequestsOnActivePhoneSwitch(HashMap<NetworkRequest, LocalLog> requestMap,
            boolean cleanUpOnRelease, int action, String logStr) {
    private void applyRequestsOnActivePhoneSwitch(NetworkRequest networkRequest,
            boolean cleanUpOnRelease, int action) {
        if (action == ACTION_NO_OP) return;

        for (NetworkRequest networkRequest : requestMap.keySet()) {
            LocalLog localLog = requestMap.get(networkRequest);
            localLog.log(logStr);
        String logStr = "onActivePhoneSwitch: " + ((action == ACTION_REQUEST)
                ? "Requesting" : "Releasing") + " network request " + networkRequest;
        mLocalLog.log(logStr);
        if (action == ACTION_REQUEST) {
                mDcTracker.requestNetwork(networkRequest, localLog);
            mDcTracker.requestNetwork(networkRequest, mLocalLog);
        } else if (action == ACTION_RELEASE) {
                mDcTracker.releaseNetwork(networkRequest, localLog, cleanUpOnRelease);
            }
            mDcTracker.releaseNetwork(networkRequest, mLocalLog, cleanUpOnRelease);
        }
    }

@@ -187,22 +177,17 @@ public class TelephonyNetworkFactory extends NetworkFactory {

    // apply or revoke requests if our active-ness changes
    private void onActivePhoneSwitch() {
        final boolean newIsActive = mPhoneSwitcher.shouldApplySpecifiedRequests(
                mPhone.getPhoneId());
        final boolean newIsActiveForDefault =
                mPhoneSwitcher.shouldApplyUnspecifiedRequests(mPhone.getPhoneId());
        for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) {
            NetworkRequest networkRequest = entry.getKey();
            boolean applied = entry.getValue();

        String logString = "onActivePhoneSwitch(newIsActive " + newIsActive + ", "
                + "newIsActiveForDefault " + newIsActiveForDefault + ")";
        if (DBG) log(logString);
            boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
                    networkRequest, mPhone.getPhoneId());

        applyRequestsOnActivePhoneSwitch(mSpecificRequests, false,
                getAction(mIsActive, newIsActive), logString);
        applyRequestsOnActivePhoneSwitch(mDefaultRequests, true,
                getAction(mIsActiveForDefault, newIsActiveForDefault), logString);

        mIsActive = newIsActive;
        mIsActiveForDefault = newIsActiveForDefault;
            applyRequestsOnActivePhoneSwitch(networkRequest, true,
                    getAction(applied, shouldApply));
            mNetworkRequests.put(networkRequest, shouldApply);
        }
    }

    // watch for phone->subId changes, reapply new filter and let
@@ -226,34 +211,17 @@ public class TelephonyNetworkFactory extends NetworkFactory {

    private void onNeedNetworkFor(Message msg) {
        NetworkRequest networkRequest = (NetworkRequest)msg.obj;
        boolean isApplicable = false;
        LocalLog localLog = null;
        if (networkRequest.networkCapabilities.getNetworkSpecifier() == null) {
            // request only for the default network
            localLog = mDefaultRequests.get(networkRequest);
            if (localLog == null) {
                localLog = new LocalLog(REQUEST_LOG_SIZE);
                localLog.log("created for " + networkRequest);
                mDefaultRequests.put(networkRequest, localLog);
                isApplicable = mIsActiveForDefault;
            }
        } else {
            localLog = mSpecificRequests.get(networkRequest);
            if (localLog == null) {
                localLog = new LocalLog(REQUEST_LOG_SIZE);
                mSpecificRequests.put(networkRequest, localLog);
                isApplicable = mIsActive;
            }
        }
        if (isApplicable) {
            String s = "onNeedNetworkFor";
            localLog.log(s);
            log(s + " " + networkRequest);
            mDcTracker.requestNetwork(networkRequest, localLog);
        } else {
            String s = "not acting - isApplicable=" + isApplicable + ", mIsActive=" + mIsActive;
            localLog.log(s);
            log(s + " " + networkRequest);
        boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
                networkRequest, mPhone.getPhoneId());

        mNetworkRequests.put(networkRequest, shouldApply);

        String s = "onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply;
        log(s);
        mLocalLog.log(s);

        if (shouldApply) {
            mDcTracker.requestNetwork(networkRequest, mLocalLog);
        }
    }

@@ -266,25 +234,17 @@ public class TelephonyNetworkFactory extends NetworkFactory {

    private void onReleaseNetworkFor(Message msg) {
        NetworkRequest networkRequest = (NetworkRequest)msg.obj;
        LocalLog localLog = null;
        boolean isApplicable = false;
        if (networkRequest.networkCapabilities.getNetworkSpecifier() == null) {
            // request only for the default network
            isApplicable = mDefaultRequests.containsKey(networkRequest) && mIsActiveForDefault;
            localLog = mDefaultRequests.remove(networkRequest);
        } else {
            isApplicable = mSpecificRequests.containsKey(networkRequest) && mIsActive;
            localLog = mSpecificRequests.remove(networkRequest);
        }
        if (isApplicable) {
            String s = "onReleaseNetworkFor";
            localLog.log(s);
            log(s + " " + networkRequest);
            mDcTracker.releaseNetwork(networkRequest, localLog, false);
        } else {
            String s = "not releasing - isApplicable=" + isApplicable + ", mIsActive=" + mIsActive;
            localLog.log(s);
            log(s + " " + networkRequest);
        boolean applied = mNetworkRequests.get(networkRequest);

        mNetworkRequests.remove(networkRequest);

        String s = "onReleaseNetworkFor " + networkRequest + " applied " + applied;
        log(s);
        mLocalLog.log(s);


        if (applied) {
            mDcTracker.releaseNetwork(networkRequest, mLocalLog, false);
        }
    }

@@ -294,16 +254,14 @@ public class TelephonyNetworkFactory extends NetworkFactory {

    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
        pw.println(LOG_TAG + " mSubId=" + mSubscriptionId + " mIsActive=" +
                mIsActive + " mIsActiveForDefault=" + mIsActiveForDefault);
        pw.println("Default Requests:");
        pw.println("Network Requests:");
        pw.increaseIndent();
        for (NetworkRequest nr : mDefaultRequests.keySet()) {
            pw.println(nr);
            pw.increaseIndent();
            mDefaultRequests.get(nr).dump(fd, pw, args);
            pw.decreaseIndent();
        for (HashMap.Entry<NetworkRequest, Boolean> entry : mNetworkRequests.entrySet()) {
            NetworkRequest nr = entry.getKey();
            boolean applied = entry.getValue();
            pw.println((applied ? "Applied: " : "Not applied: ") + nr);
        }
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
    }
}
+18 −22
Original line number Diff line number Diff line
@@ -103,14 +103,14 @@ public class PhoneSwitcherTest extends TelephonyTest {

        // verify nothing has been done while there are no inputs
        assertFalse("data allowed initially", mDataAllowed[0]);
        assertFalse("data allowed initially", mDataAllowed[0]);
        assertFalse("phone active initially", mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertFalse("data allowed initially", mDataAllowed[1]);

        NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50);
        waitABit();

        assertFalse("data allowed after request", mDataAllowed[0]);
        assertFalse("phone active after request", mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertFalse("phone active after request", mPhoneSwitcher
                .shouldApplyNetworkRequest(internetNetworkRequest, 0));

        // not registered yet - shouldn't inc
        verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
@@ -413,38 +413,34 @@ public class PhoneSwitcherTest extends TelephonyTest {
        setSlotIndexToSubId(1, 2);
        setDefaultDataSubId(1);
        waitABit();
        // Phone 0 (sub 1) should preferredDataModem it has default data sub.
        // Phone 0 (sub 1) should be preferred data phone as it has default data sub.
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));

        clearInvocations(mMockRadioConfig);
        clearInvocations(mActivePhoneSwitchHandler);

        // Notify phoneSwitcher about default data sub and default network request.
        // It shouldn't change anything.
        addInternetNetworkRequest(null, 50);
        addMmsNetworkRequest(2);
        NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
        NetworkRequest mmsRequest = addMmsNetworkRequest(2);
        waitABit();
        verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
        verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));

        // Set sub 2 as preferred sub should make phone 1 preferredDataModem
        mPhoneSwitcher.setPreferredData(2);
        waitABit();
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));

        clearInvocations(mMockRadioConfig);
        clearInvocations(mActivePhoneSwitchHandler);
@@ -454,10 +450,10 @@ public class PhoneSwitcherTest extends TelephonyTest {
        waitABit();
        verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
        verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(0));
        assertTrue(mPhoneSwitcher.shouldApplySpecifiedRequests(1));
        assertTrue(mPhoneSwitcher.shouldApplyUnspecifiedRequests(0));
        assertFalse(mPhoneSwitcher.shouldApplyUnspecifiedRequests(1));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));

        // SetDataAllowed should never be triggered.
        verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any());
+8 −6
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
        Rlog.d(LOG_TAG + " " + mTestName, str);
    }

    private NetworkRequest makeSubSpecificDefaultRequest(int subId) {
    private NetworkRequest makeSubSpecificInternetRequest(int subId) {
        NetworkCapabilities netCap = (new NetworkCapabilities()).
                addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).
                addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED).
@@ -183,8 +183,8 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
        waitForMs(250);
        assertEquals(1, mNetworkRequestList.size());

        log("makeSubSpecificDefaultRequest: subId = " + subId);
        NetworkRequest subSpecificDefault = makeSubSpecificDefaultRequest(subId);
        log("makeSubSpecificInternetRequest: subId = " + subId);
        NetworkRequest subSpecificDefault = makeSubSpecificInternetRequest(subId);
        waitForMs(250);
        assertEquals(2, mNetworkRequestList.size());

@@ -193,7 +193,7 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
        waitForMs(250);
        assertEquals(0, mNetworkRequestList.size());

        log("makeSubSpecificDefaultRequest: subId = " + subId);
        log("makeSubSpecificInternetRequest: subId = " + subId);
        NetworkRequest subSpecificMms = makeSubSpecificMmsRequest(subId);
        waitForMs(250);
        assertEquals(0, mNetworkRequestList.size());
@@ -276,14 +276,16 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest {
        waitForMs(250);
        assertEquals(0, mNetworkRequestList.size());

        makeSubSpecificDefaultRequest(subId);
        makeSubSpecificInternetRequest(subId);
        waitForMs(250);
        assertEquals(0, mNetworkRequestList.size());

        mSubscriptionControllerMock.setSlotSubId(phoneId, subId);
        mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
        waitForMs(250);
        assertEquals(2, mNetworkRequestList.size());
        // Although specified a subId, Internet request is only handled by
        // preferred data phone.
        assertEquals(1, mNetworkRequestList.size());

        mSubscriptionControllerMock.setDefaultDataSubId(subId);
        mPhoneSwitcherMock.setPreferredDataPhoneId(phoneId);
+2 −15
Original line number Diff line number Diff line
@@ -27,14 +27,12 @@ import com.android.internal.telephony.PhoneSwitcher;
import java.util.concurrent.atomic.AtomicBoolean;

public class PhoneSwitcherMock extends PhoneSwitcher {
    private final int mNumPhones;
    private final RegistrantList mActivePhoneRegistrants;
    private final AtomicBoolean mIsActive[];

    public PhoneSwitcherMock(int numPhones, Looper looper) {
        super(looper);
        super(numPhones, looper);

        mNumPhones = numPhones;
        mActivePhoneRegistrants = new RegistrantList();
        mIsActive = new AtomicBoolean[numPhones];
        for(int i = 0; i < numPhones; i++) {
@@ -48,15 +46,10 @@ public class PhoneSwitcherMock extends PhoneSwitcher {
    }

    @Override
    public boolean shouldApplySpecifiedRequests(int phoneId) {
    protected boolean isPhoneActive(int phoneId) {
        return mIsActive[phoneId].get();
    }

    @Override
    public boolean shouldApplyUnspecifiedRequests(int phoneId) {
        return mIsActive[phoneId].get() && phoneId == mPreferredDataPhoneId;
    }

    @Override
    public void registerForActivePhoneSwitch(Handler h, int what, Object o) {
        Registrant r = new Registrant(h, what, o);
@@ -69,12 +62,6 @@ public class PhoneSwitcherMock extends PhoneSwitcher {
        mActivePhoneRegistrants.remove(h);
    }

    private void validatePhoneId(int phoneId) {
        if (phoneId < 0 || phoneId >= mNumPhones) {
            throw new IllegalArgumentException("Invalid PhoneId");
        }
    }

    @VisibleForTesting
    public void setPhoneActive(int phoneId, boolean active) {
        validatePhoneId(phoneId);