Loading src/java/com/android/internal/telephony/PhoneSwitcher.java +57 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; } /** Loading @@ -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"); } Loading src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java +55 −97 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -96,8 +95,6 @@ public class TelephonyNetworkFactory extends NetworkFactory { mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler, EVENT_SUBSCRIPTION_CHANGED, null); mIsActiveForDefault = false; register(); } Loading Loading @@ -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); } } Loading @@ -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 Loading @@ -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); } } Loading @@ -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); } } Loading @@ -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(); } } tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +18 −22 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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); Loading @@ -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()); Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java +8 −6 Original line number Diff line number Diff line Loading @@ -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). Loading Loading @@ -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()); Loading @@ -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()); Loading Loading @@ -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); Loading tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java +2 −15 Original line number Diff line number Diff line Loading @@ -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++) { Loading @@ -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); Loading @@ -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); Loading Loading
src/java/com/android/internal/telephony/PhoneSwitcher.java +57 −38 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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); Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; } /** Loading @@ -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"); } Loading
src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java +55 −97 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -96,8 +95,6 @@ public class TelephonyNetworkFactory extends NetworkFactory { mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler, EVENT_SUBSCRIPTION_CHANGED, null); mIsActiveForDefault = false; register(); } Loading Loading @@ -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); } } Loading @@ -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 Loading @@ -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); } } Loading @@ -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); } } Loading @@ -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(); } }
tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +18 −22 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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); Loading @@ -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()); Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java +8 −6 Original line number Diff line number Diff line Loading @@ -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). Loading Loading @@ -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()); Loading @@ -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()); Loading Loading @@ -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); Loading
tests/telephonytests/src/com/android/internal/telephony/mocks/PhoneSwitcherMock.java +2 −15 Original line number Diff line number Diff line Loading @@ -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++) { Loading @@ -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); Loading @@ -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); Loading