Loading src/java/com/android/internal/telephony/PhoneSwitcher.java +46 −4 Original line number Diff line number Diff line Loading @@ -85,6 +85,10 @@ public class PhoneSwitcher extends Handler { private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000; private static final int MODEM_COMMAND_RETRY_PERIOD_MS = 5000; // If there are no subscriptions in a device, then the phone to be used for emergency should // always be the "first" phone. private static final int DEFAULT_EMERGENCY_PHONE_ID = 0; private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>(); private final RegistrantList mActivePhoneRegistrants; private final SubscriptionController mSubscriptionController; Loading Loading @@ -582,9 +586,15 @@ public class PhoneSwitcher extends Handler { mPrimaryDataSubId = primaryDataSubId; } // Check to see if there is any active subscription on any phone boolean hasAnyActiveSubscription = false; // Check if phoneId to subId mapping is changed. for (int i = 0; i < mNumPhones; i++) { int sub = mSubscriptionController.getSubIdUsingPhoneId(i); if (SubscriptionManager.isValidSubscriptionId(sub)) hasAnyActiveSubscription = true; if (sub != mPhoneSubscriptions[i]) { sb.append(" phone[").append(i).append("] ").append(mPhoneSubscriptions[i]); sb.append("->").append(sub); Loading @@ -593,9 +603,22 @@ public class PhoneSwitcher extends Handler { } } if (!hasAnyActiveSubscription) { transitionToEmergencyPhone(); } else { if (VDBG) log("Found an active subscription"); } // Check if phoneId for preferred data is changed. int oldPreferredDataPhoneId = mPreferredDataPhoneId; updatePreferredDataPhoneId(); // When there are no subscriptions, the preferred data phone ID is invalid, but we want // to keep a valid phoneId for Emergency, so skip logic that updates for preferred data // phone ID. Ideally there should be a single set of checks that evaluate the correct // phoneId on a service-by-service basis (EIMS being one), but for now... just bypass // this logic in the no-SIM case. if (hasAnyActiveSubscription) updatePreferredDataPhoneId(); if (oldPreferredDataPhoneId != mPreferredDataPhoneId) { sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId) .append("->").append(mPreferredDataPhoneId); Loading Loading @@ -742,8 +765,7 @@ public class PhoneSwitcher extends Handler { // 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) if (netRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && subId != preferredDataSubId && subId != mValidator.getSubIdInValidation()) { // Returning INVALID_PHONE_INDEX will result in netRequest not being handled. return INVALID_PHONE_INDEX; Loading Loading @@ -820,6 +842,18 @@ public class PhoneSwitcher extends Handler { mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } private void transitionToEmergencyPhone() { if (mPreferredDataPhoneId != DEFAULT_EMERGENCY_PHONE_ID) { log("No active subscriptions: resetting preferred phone to 0 for emergency"); mPreferredDataPhoneId = DEFAULT_EMERGENCY_PHONE_ID; } if (mPreferredDataSubId != INVALID_SUBSCRIPTION_ID) { mPreferredDataSubId = INVALID_SUBSCRIPTION_ID; notifyPreferredDataSubIdChanged(); } } private Phone findPhoneById(final int phoneId) { if (phoneId < 0 || phoneId >= mNumPhones) { return null; Loading @@ -831,13 +865,21 @@ public class PhoneSwitcher extends Handler { validatePhoneId(phoneId); // In any case, if phone state is inactive, don't apply the network request. if (!isPhoneActive(phoneId)) return false; if (!isPhoneActive(phoneId) || ( mSubscriptionController.getSubIdUsingPhoneId(phoneId) == INVALID_SUBSCRIPTION_ID && !isEmergencyNetworkRequest(networkRequest))) { return false; } int phoneIdToHandle = phoneIdForRequest(networkRequest); return phoneId == phoneIdToHandle; } boolean isEmergencyNetworkRequest(NetworkRequest networkRequest) { return networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS); } @VisibleForTesting protected boolean isPhoneActive(int phoneId) { return mPhoneStates[phoneId].active; Loading src/java/com/android/internal/telephony/SubscriptionController.java +10 −2 Original line number Diff line number Diff line Loading @@ -3574,7 +3574,15 @@ public class SubscriptionController extends ISub.Stub { } private @ApnSetting.ApnType int getWhiteListedApnDataTypes(int subId, String callingPackage) { return Integer.valueOf(getSubscriptionProperty(subId, SubscriptionManager.WHITE_LISTED_APN_DATA, callingPackage)); String whiteListedApnData = getSubscriptionProperty(subId, SubscriptionManager.WHITE_LISTED_APN_DATA, callingPackage); try { return Integer.valueOf(whiteListedApnData); } catch (NumberFormatException e) { loge("[getWhiteListedApnDataTypes] couldn't parse apn data:" + whiteListedApnData); } return ApnSetting.TYPE_NONE; } } src/java/com/android/internal/telephony/dataconnection/DcTracker.java +13 −1 Original line number Diff line number Diff line Loading @@ -740,6 +740,7 @@ public class DcTracker extends Handler { } initEmergencyApnSetting(); addEmergencyApnSetting(); mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId(); Loading Loading @@ -3968,6 +3969,7 @@ public class DcTracker extends Handler { pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum); pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag); pw.println(" mDataStallNoRxEnabled=" + mDataStallNoRxEnabled); pw.println(" mEmergencyApn=" + mEmergencyApn); pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv); pw.println(" mNoRecvPollCount=" + mNoRecvPollCount); pw.println(" mResolver=" + mResolver); Loading Loading @@ -4091,7 +4093,7 @@ public class DcTracker extends Handler { /** * Read APN configuration from Telephony.db for Emergency APN * All opertors recognize the connection request for EPDN based on APN type * All operators recognize the connection request for EPDN based on APN type * PLMN name,APN name are not mandatory parameters */ private void initEmergencyApnSetting() { Loading @@ -4112,6 +4114,15 @@ public class DcTracker extends Handler { } cursor.close(); } if (mEmergencyApn != null) return; // If no emergency APN setting has been found, make one using reasonable defaults mEmergencyApn = new ApnSetting.Builder() .setEntryName("Emergency") .setProtocol(ApnSetting.PROTOCOL_IPV4V6) .setApnName("sos") .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY) .build(); } /** Loading @@ -4131,6 +4142,7 @@ public class DcTracker extends Handler { if (!mAllApnSettings.contains(mEmergencyApn)) { mAllApnSettings.add(mEmergencyApn); log("Adding emergency APN : " + mEmergencyApn); return; } } } Loading tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -116,7 +116,6 @@ public class PhoneSwitcherTest extends TelephonyTest { NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50); waitABit(); assertFalse("data allowed after request", mDataAllowed[0]); assertFalse("phone active after request", mPhoneSwitcher .shouldApplyNetworkRequest(internetNetworkRequest, 0)); Loading @@ -132,7 +131,6 @@ public class PhoneSwitcherTest extends TelephonyTest { setDefaultDataSubId(0); verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); assertFalse("data allowed", mDataAllowed[0]); setSlotIndexToSubId(0, 0); mSubChangedListener.onSubscriptionsChanged(); Loading Loading @@ -413,6 +411,7 @@ public class PhoneSwitcherTest extends TelephonyTest { mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, ACTIVE_PHONE_SWITCH, null); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); clearInvocations(mMockRadioConfig); clearInvocations(mActivePhoneSwitchHandler); // Phone 0 has sub 1, phone 1 has sub 2. Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java +2 −4 Original line number Diff line number Diff line Loading @@ -152,13 +152,11 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest { mContextFixture.setSystemService(Context.CONNECTIVITY_SERVICE, new ConnectivityManager(mContext, mIConnectivityManager)); mTelephonyRegistryMock = new TelephonyRegistryMock(); mPhoneSwitcherMock = new PhoneSwitcherMock(numberOfPhones, mLooper); mSubscriptionControllerMock = new SubscriptionControllerMock(mContext, mTelephonyRegistryMock, numberOfPhones); mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones); mPhoneSwitcherMock = new PhoneSwitcherMock(numberOfPhones, mLooper); mSubscriptionControllerMock = new SubscriptionControllerMock(mContext, mTelephonyRegistryMock, numberOfPhones); mPhoneSwitcherMock = new PhoneSwitcherMock( numberOfPhones, mLooper, mSubscriptionControllerMock); mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones); replaceInstance(SubscriptionController.class, "sInstance", null, Loading Loading
src/java/com/android/internal/telephony/PhoneSwitcher.java +46 −4 Original line number Diff line number Diff line Loading @@ -85,6 +85,10 @@ public class PhoneSwitcher extends Handler { private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000; private static final int MODEM_COMMAND_RETRY_PERIOD_MS = 5000; // If there are no subscriptions in a device, then the phone to be used for emergency should // always be the "first" phone. private static final int DEFAULT_EMERGENCY_PHONE_ID = 0; private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>(); private final RegistrantList mActivePhoneRegistrants; private final SubscriptionController mSubscriptionController; Loading Loading @@ -582,9 +586,15 @@ public class PhoneSwitcher extends Handler { mPrimaryDataSubId = primaryDataSubId; } // Check to see if there is any active subscription on any phone boolean hasAnyActiveSubscription = false; // Check if phoneId to subId mapping is changed. for (int i = 0; i < mNumPhones; i++) { int sub = mSubscriptionController.getSubIdUsingPhoneId(i); if (SubscriptionManager.isValidSubscriptionId(sub)) hasAnyActiveSubscription = true; if (sub != mPhoneSubscriptions[i]) { sb.append(" phone[").append(i).append("] ").append(mPhoneSubscriptions[i]); sb.append("->").append(sub); Loading @@ -593,9 +603,22 @@ public class PhoneSwitcher extends Handler { } } if (!hasAnyActiveSubscription) { transitionToEmergencyPhone(); } else { if (VDBG) log("Found an active subscription"); } // Check if phoneId for preferred data is changed. int oldPreferredDataPhoneId = mPreferredDataPhoneId; updatePreferredDataPhoneId(); // When there are no subscriptions, the preferred data phone ID is invalid, but we want // to keep a valid phoneId for Emergency, so skip logic that updates for preferred data // phone ID. Ideally there should be a single set of checks that evaluate the correct // phoneId on a service-by-service basis (EIMS being one), but for now... just bypass // this logic in the no-SIM case. if (hasAnyActiveSubscription) updatePreferredDataPhoneId(); if (oldPreferredDataPhoneId != mPreferredDataPhoneId) { sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId) .append("->").append(mPreferredDataPhoneId); Loading Loading @@ -742,8 +765,7 @@ public class PhoneSwitcher extends Handler { // 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) if (netRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && subId != preferredDataSubId && subId != mValidator.getSubIdInValidation()) { // Returning INVALID_PHONE_INDEX will result in netRequest not being handled. return INVALID_PHONE_INDEX; Loading Loading @@ -820,6 +842,18 @@ public class PhoneSwitcher extends Handler { mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } private void transitionToEmergencyPhone() { if (mPreferredDataPhoneId != DEFAULT_EMERGENCY_PHONE_ID) { log("No active subscriptions: resetting preferred phone to 0 for emergency"); mPreferredDataPhoneId = DEFAULT_EMERGENCY_PHONE_ID; } if (mPreferredDataSubId != INVALID_SUBSCRIPTION_ID) { mPreferredDataSubId = INVALID_SUBSCRIPTION_ID; notifyPreferredDataSubIdChanged(); } } private Phone findPhoneById(final int phoneId) { if (phoneId < 0 || phoneId >= mNumPhones) { return null; Loading @@ -831,13 +865,21 @@ public class PhoneSwitcher extends Handler { validatePhoneId(phoneId); // In any case, if phone state is inactive, don't apply the network request. if (!isPhoneActive(phoneId)) return false; if (!isPhoneActive(phoneId) || ( mSubscriptionController.getSubIdUsingPhoneId(phoneId) == INVALID_SUBSCRIPTION_ID && !isEmergencyNetworkRequest(networkRequest))) { return false; } int phoneIdToHandle = phoneIdForRequest(networkRequest); return phoneId == phoneIdToHandle; } boolean isEmergencyNetworkRequest(NetworkRequest networkRequest) { return networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS); } @VisibleForTesting protected boolean isPhoneActive(int phoneId) { return mPhoneStates[phoneId].active; Loading
src/java/com/android/internal/telephony/SubscriptionController.java +10 −2 Original line number Diff line number Diff line Loading @@ -3574,7 +3574,15 @@ public class SubscriptionController extends ISub.Stub { } private @ApnSetting.ApnType int getWhiteListedApnDataTypes(int subId, String callingPackage) { return Integer.valueOf(getSubscriptionProperty(subId, SubscriptionManager.WHITE_LISTED_APN_DATA, callingPackage)); String whiteListedApnData = getSubscriptionProperty(subId, SubscriptionManager.WHITE_LISTED_APN_DATA, callingPackage); try { return Integer.valueOf(whiteListedApnData); } catch (NumberFormatException e) { loge("[getWhiteListedApnDataTypes] couldn't parse apn data:" + whiteListedApnData); } return ApnSetting.TYPE_NONE; } }
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +13 −1 Original line number Diff line number Diff line Loading @@ -740,6 +740,7 @@ public class DcTracker extends Handler { } initEmergencyApnSetting(); addEmergencyApnSetting(); mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId(); Loading Loading @@ -3968,6 +3969,7 @@ public class DcTracker extends Handler { pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum); pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag); pw.println(" mDataStallNoRxEnabled=" + mDataStallNoRxEnabled); pw.println(" mEmergencyApn=" + mEmergencyApn); pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv); pw.println(" mNoRecvPollCount=" + mNoRecvPollCount); pw.println(" mResolver=" + mResolver); Loading Loading @@ -4091,7 +4093,7 @@ public class DcTracker extends Handler { /** * Read APN configuration from Telephony.db for Emergency APN * All opertors recognize the connection request for EPDN based on APN type * All operators recognize the connection request for EPDN based on APN type * PLMN name,APN name are not mandatory parameters */ private void initEmergencyApnSetting() { Loading @@ -4112,6 +4114,15 @@ public class DcTracker extends Handler { } cursor.close(); } if (mEmergencyApn != null) return; // If no emergency APN setting has been found, make one using reasonable defaults mEmergencyApn = new ApnSetting.Builder() .setEntryName("Emergency") .setProtocol(ApnSetting.PROTOCOL_IPV4V6) .setApnName("sos") .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY) .build(); } /** Loading @@ -4131,6 +4142,7 @@ public class DcTracker extends Handler { if (!mAllApnSettings.contains(mEmergencyApn)) { mAllApnSettings.add(mEmergencyApn); log("Adding emergency APN : " + mEmergencyApn); return; } } } Loading
tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -116,7 +116,6 @@ public class PhoneSwitcherTest extends TelephonyTest { NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50); waitABit(); assertFalse("data allowed after request", mDataAllowed[0]); assertFalse("phone active after request", mPhoneSwitcher .shouldApplyNetworkRequest(internetNetworkRequest, 0)); Loading @@ -132,7 +131,6 @@ public class PhoneSwitcherTest extends TelephonyTest { setDefaultDataSubId(0); verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong()); assertFalse("data allowed", mDataAllowed[0]); setSlotIndexToSubId(0, 0); mSubChangedListener.onSubscriptionsChanged(); Loading Loading @@ -413,6 +411,7 @@ public class PhoneSwitcherTest extends TelephonyTest { mPhoneSwitcher.registerForActivePhoneSwitch(mActivePhoneSwitchHandler, ACTIVE_PHONE_SWITCH, null); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); clearInvocations(mMockRadioConfig); clearInvocations(mActivePhoneSwitchHandler); // Phone 0 has sub 1, phone 1 has sub 2. Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java +2 −4 Original line number Diff line number Diff line Loading @@ -152,13 +152,11 @@ public class TelephonyNetworkFactoryTest extends TelephonyTest { mContextFixture.setSystemService(Context.CONNECTIVITY_SERVICE, new ConnectivityManager(mContext, mIConnectivityManager)); mTelephonyRegistryMock = new TelephonyRegistryMock(); mPhoneSwitcherMock = new PhoneSwitcherMock(numberOfPhones, mLooper); mSubscriptionControllerMock = new SubscriptionControllerMock(mContext, mTelephonyRegistryMock, numberOfPhones); mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones); mPhoneSwitcherMock = new PhoneSwitcherMock(numberOfPhones, mLooper); mSubscriptionControllerMock = new SubscriptionControllerMock(mContext, mTelephonyRegistryMock, numberOfPhones); mPhoneSwitcherMock = new PhoneSwitcherMock( numberOfPhones, mLooper, mSubscriptionControllerMock); mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones); replaceInstance(SubscriptionController.class, "sInstance", null, Loading