Loading src/java/com/android/internal/telephony/data/DataEvaluation.java +8 −1 Original line number Diff line number Diff line Loading @@ -214,6 +214,11 @@ public class DataEvaluation { PREFERRED_TRANSPORT_CHANGED, /** Slice config changed. */ SLICE_CONFIG_CHANGED, /** * Single data network arbitration. On certain RATs, only one data network is allowed at the * same time. */ SINGLE_DATA_NETWORK_ARBITRATION, } /** Disallowed reasons. There could be multiple reasons if it is not allowed. */ Loading Loading @@ -266,7 +271,9 @@ public class DataEvaluation { /** Data network is not in the right state. */ ILLEGAL_STATE(true), /** VoPS is not supported by the network. */ VOPS_NOT_SUPPORTED(true); VOPS_NOT_SUPPORTED(true), /** Only one data network is allowed at one time. */ ONLY_ALLOWED_SINGLE_NETWORK(true); private final boolean mIsHardReason; Loading src/java/com/android/internal/telephony/data/DataNetwork.java +17 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ public class DataNetwork extends StateMachine { TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED, TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY, TEAR_DOWN_REASON_ILLEGAL_STATE, TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK, }) public @interface TearDownReason {} Loading Loading @@ -336,6 +337,9 @@ public class DataNetwork extends StateMachine { /** Data network tear down due to illegal state. */ public static final int TEAR_DOWN_REASON_ILLEGAL_STATE = 28; /** Data network tear down due to only allowed single network. */ public static final int TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK = 29; @IntDef(prefix = {"BANDWIDTH_SOURCE_"}, value = { BANDWIDTH_SOURCE_UNKNOWN, Loading Loading @@ -2382,6 +2386,17 @@ public class DataNetwork extends StateMachine { return highestPriorityCapability; } /** * @return The priority of the network. The priority is derived from the highest priority * capability of the network. */ public int getPriority() { return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed() .map(mDataConfigManager::getNetworkCapabilityPriority) .max(Integer::compare) .orElse(-1); } /** * @return The attached network request list. */ Loading Loading @@ -2729,6 +2744,8 @@ public class DataNetwork extends StateMachine { return "TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY"; case TEAR_DOWN_REASON_ILLEGAL_STATE: return "TEAR_DOWN_REASON_ILLEGAL_STATE"; case TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK: return "TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK"; default: return "UNKNOWN(" + reason + ")"; } Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +43 −8 Original line number Diff line number Diff line Loading @@ -136,9 +136,6 @@ public class DataNetworkController extends Handler { /** Event for removing a network request. */ private static final int EVENT_REMOVE_NETWORK_REQUEST = 3; /** Event for satisfying a single network request. */ private static final int EVENT_SATISFY_NETWORK_REQUEST = 4; /** Re-evaluate all unsatisfied network requests. */ private static final int EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS = 5; Loading Loading @@ -899,9 +896,6 @@ public class DataNetworkController extends Handler { case EVENT_ADD_NETWORK_REQUEST: onAddNetworkRequest((TelephonyNetworkRequest) msg.obj); break; case EVENT_SATISFY_NETWORK_REQUEST: onSatisfyNetworkRequest((TelephonyNetworkRequest) msg.obj); break; case EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS: DataEvaluationReason reason = (DataEvaluationReason) msg.obj; onReevaluateUnsatisfiedNetworkRequests(reason); Loading Loading @@ -1044,7 +1038,7 @@ public class DataNetworkController extends Handler { return; } logv("onAddNetworkRequest: added " + networkRequest); sendMessage(obtainMessage(EVENT_SATISFY_NETWORK_REQUEST, networkRequest)); onSatisfyNetworkRequest(networkRequest); } /** Loading Loading @@ -1078,6 +1072,12 @@ public class DataNetworkController extends Handler { setupDataNetwork(dataProfile, null, evaluation.getDataAllowedReason()); } } else if (evaluation.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) { // Re-evaluate the existing data networks. If this request's priority is higher than // the existing data network, the data network will be torn down so this request will // get a chance to be satisfied. sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, DataEvaluationReason.SINGLE_DATA_NETWORK_ARBITRATION)); } } Loading Loading @@ -1144,7 +1144,6 @@ public class DataNetworkController extends Handler { */ private boolean shouldCheckRegistrationState() { // Always don't check registration state on non-DDS sub. log("shouldCheckRegistrationState: phoneSwitcher=" + PhoneSwitcher.getInstance()); if (mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()) { return false; } Loading @@ -1156,6 +1155,16 @@ public class DataNetworkController extends Handler { return true; } /** * @return {@code true} if the network only allows single data network at one time. */ private boolean isOnlySingleDataNetworkAllowed(@TransportType int transport) { if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) return false; return mDataConfigManager.getNetworkTypesOnlySupportSingleDataNetwork() .contains(getDataNetworkType(transport)); } /** * Evaluate a network request. The goal is to find a suitable {@link DataProfile} that can be * used to setup the data network. Loading Loading @@ -1263,6 +1272,12 @@ public class DataNetworkController extends Handler { evaluation.addDataDisallowedReason(DataDisallowedReason.EMERGENCY_CALL); } // Check if only one data network is allowed. if (isOnlySingleDataNetworkAllowed(transport) && !mDataNetworkList.isEmpty()) { evaluation.addDataDisallowedReason( DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); } if (!mDataSettingsManager.isDataEnabled(DataUtils.networkCapabilityToApnType( networkRequest.getApnTypeNetworkCapability()))) { evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED); Loading Loading @@ -1440,6 +1455,24 @@ public class DataNetworkController extends Handler { evaluation.addDataDisallowedReason(DataDisallowedReason.EMERGENCY_CALL); } // Check if there are other network that has higher priority, and only single data network // is allowed. if (isOnlySingleDataNetworkAllowed(dataNetwork.getTransport())) { // If there is network request that has higher priority than this data network, then // tear down the network, regardless that network request is satisfied or not. if (mAllNetworkRequestList.stream() .filter(request -> dataNetwork.getTransport() == mAccessNetworksManager.getPreferredTransportByNetworkCapability( request.getApnTypeNetworkCapability())) .anyMatch(request -> request.getPriority() > dataNetwork.getPriority())) { evaluation.addDataDisallowedReason( DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); } else { log("evaluateDataNetwork: " + dataNetwork + " has the highest priority. " + "No need to tear down"); } } // Check if data is disabled boolean dataDisabled = false; if (!mDataSettingsManager.isDataEnabled()) { Loading Loading @@ -1663,6 +1696,8 @@ public class DataNetworkController extends Handler { return DataNetwork.TEAR_DOWN_REASON_ILLEGAL_STATE; case VOPS_NOT_SUPPORTED: return DataNetwork.TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED; case ONLY_ALLOWED_SINGLE_NETWORK: return DataNetwork.TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK; } } return 0; Loading tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +107 −5 Original line number Diff line number Diff line Loading @@ -139,8 +139,11 @@ public class DataNetworkControllerTest extends TelephonyTest { .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE) .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT)) .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) .setProfileId(1234) Loading @@ -163,8 +166,10 @@ public class DataNetworkControllerTest extends TelephonyTest { .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE) .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)) .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) .setProfileId(1235) Loading @@ -178,6 +183,7 @@ public class DataNetworkControllerTest extends TelephonyTest { private final DataProfile mEmergencyDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setEntryName("DEFAULT EIMS") .setId(2165) .setProtocol(ApnSetting.PROTOCOL_IPV4V6) .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) .setApnName("sos") Loading @@ -187,6 +193,51 @@ public class DataNetworkControllerTest extends TelephonyTest { .build()) .build(); private final DataProfile mFotaDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setId(2166) .setOperatorNumeric("12345") .setEntryName("fota_apn") .setApnName("fota_apn") .setUser("user") .setPassword("passwd") .setApnTypeBitmask(ApnSetting.TYPE_FOTA) .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) .setProfileId(1236) .setMaxConns(321) .setWaitTime(456) .setMaxConnsTime(789) .build()) .setPreferred(false) .build(); private final DataProfile mTetheringDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setId(2167) .setOperatorNumeric("12345") .setEntryName("dun_apn") .setApnName("dun_apn") .setUser("user") .setPassword("passwd") .setApnTypeBitmask(ApnSetting.TYPE_DUN) .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) .setProfileId(1236) .setMaxConns(321) .setWaitTime(456) .setMaxConnsTime(789) .build()) .setPreferred(false) .build(); /** Data call response map. The first key is the transport type, the second key is the cid. */ private final Map<Integer, Map<Integer, DataCallResponse>> mDataCallResponses = new HashMap<>(); Loading Loading @@ -364,6 +415,11 @@ public class DataNetworkControllerTest extends TelephonyTest { mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, true); mCarrierConfig.putIntArray(CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY, new int[] {TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B}); mContextFixture.putResource(com.android.internal.R.string.config_bandwidthEstimateSource, "bandwidth_estimator"); } Loading Loading @@ -449,14 +505,19 @@ public class DataNetworkControllerTest extends TelephonyTest { doAnswer(invocation -> { TelephonyNetworkRequest networkRequest = (TelephonyNetworkRequest) invocation.getArguments()[0]; int networkType = (int) invocation.getArguments()[1]; List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile, mImsDataProfile, mEmergencyDataProfile); mEmergencyDataProfile, mFotaDataProfile, mTetheringDataProfile); for (DataProfile dataProfile : profiles) { if (dataProfile.canSatisfy(networkRequest.getCapabilities())) { if (dataProfile.canSatisfy(networkRequest.getCapabilities()) && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0 || (dataProfile.getApnSetting().getNetworkTypeBitmask() & ServiceState.getBitmaskForTech(networkType)) != 0)) { return dataProfile; } } logd("Cannot find data profile to satisfy " + networkRequest); logd("Cannot find data profile to satisfy " + networkRequest + ", network type=" + TelephonyManager.getNetworkTypeName(networkType)); return null; }).when(mDataProfileManager).getDataProfileForNetworkRequest( any(TelephonyNetworkRequest.class), anyInt()); Loading Loading @@ -1678,4 +1739,45 @@ public class DataNetworkControllerTest extends TelephonyTest { // network should still be not-restricted. NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); } @Test public void testSinglePdnArbitration() throws Exception { // On old 1x network, only one data network is allowed. serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT, NetworkRegistrationInfo.REGISTRATION_STATE_HOME); mDataNetworkControllerUT.addNetworkRequest( createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_DUN)); processAllMessages(); verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); mDataNetworkControllerUT.addNetworkRequest( createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET)); processAllFutureMessages(); // Lower priority network should not trump the higher priority network. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); // Now send a higher priority network request TelephonyNetworkRequest fotaRequest = createNetworkRequest( NetworkCapabilities.NET_CAPABILITY_FOTA); mDataNetworkControllerUT.addNetworkRequest(fotaRequest); processAllFutureMessages(); // The existing internet data network should be torn down. verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_DUN); // The higher priority emergency data network should be established. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_FOTA); // Now remove the fota request and tear down fota network. mDataNetworkControllerUT.removeNetworkRequest(fotaRequest); processAllMessages(); List<DataNetwork> dataNetworks = getDataNetworks(); dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED); processAllMessages(); // The tethering data network should come back since now it has the highest priority after // fota is gone. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); } } tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,18 @@ public class DataProfileManagerTest extends TelephonyTest { assertThat(dp.getApnSetting().getApnName()).isEqualTo(TETHERING_APN); } @Test public void testGetDataProfileForNetworkRequestNoCompatibleRat() { NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone); DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, TelephonyManager.NETWORK_TYPE_GSM); // Should not find data profile due to RAT incompatible. assertThat(dp).isNull(); } @Test public void testGetDataProfileForNetworkRequestRotation() { TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( Loading Loading
src/java/com/android/internal/telephony/data/DataEvaluation.java +8 −1 Original line number Diff line number Diff line Loading @@ -214,6 +214,11 @@ public class DataEvaluation { PREFERRED_TRANSPORT_CHANGED, /** Slice config changed. */ SLICE_CONFIG_CHANGED, /** * Single data network arbitration. On certain RATs, only one data network is allowed at the * same time. */ SINGLE_DATA_NETWORK_ARBITRATION, } /** Disallowed reasons. There could be multiple reasons if it is not allowed. */ Loading Loading @@ -266,7 +271,9 @@ public class DataEvaluation { /** Data network is not in the right state. */ ILLEGAL_STATE(true), /** VoPS is not supported by the network. */ VOPS_NOT_SUPPORTED(true); VOPS_NOT_SUPPORTED(true), /** Only one data network is allowed at one time. */ ONLY_ALLOWED_SINGLE_NETWORK(true); private final boolean mIsHardReason; Loading
src/java/com/android/internal/telephony/data/DataNetwork.java +17 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ public class DataNetwork extends StateMachine { TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED, TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY, TEAR_DOWN_REASON_ILLEGAL_STATE, TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK, }) public @interface TearDownReason {} Loading Loading @@ -336,6 +337,9 @@ public class DataNetwork extends StateMachine { /** Data network tear down due to illegal state. */ public static final int TEAR_DOWN_REASON_ILLEGAL_STATE = 28; /** Data network tear down due to only allowed single network. */ public static final int TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK = 29; @IntDef(prefix = {"BANDWIDTH_SOURCE_"}, value = { BANDWIDTH_SOURCE_UNKNOWN, Loading Loading @@ -2382,6 +2386,17 @@ public class DataNetwork extends StateMachine { return highestPriorityCapability; } /** * @return The priority of the network. The priority is derived from the highest priority * capability of the network. */ public int getPriority() { return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed() .map(mDataConfigManager::getNetworkCapabilityPriority) .max(Integer::compare) .orElse(-1); } /** * @return The attached network request list. */ Loading Loading @@ -2729,6 +2744,8 @@ public class DataNetwork extends StateMachine { return "TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY"; case TEAR_DOWN_REASON_ILLEGAL_STATE: return "TEAR_DOWN_REASON_ILLEGAL_STATE"; case TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK: return "TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK"; default: return "UNKNOWN(" + reason + ")"; } Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +43 −8 Original line number Diff line number Diff line Loading @@ -136,9 +136,6 @@ public class DataNetworkController extends Handler { /** Event for removing a network request. */ private static final int EVENT_REMOVE_NETWORK_REQUEST = 3; /** Event for satisfying a single network request. */ private static final int EVENT_SATISFY_NETWORK_REQUEST = 4; /** Re-evaluate all unsatisfied network requests. */ private static final int EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS = 5; Loading Loading @@ -899,9 +896,6 @@ public class DataNetworkController extends Handler { case EVENT_ADD_NETWORK_REQUEST: onAddNetworkRequest((TelephonyNetworkRequest) msg.obj); break; case EVENT_SATISFY_NETWORK_REQUEST: onSatisfyNetworkRequest((TelephonyNetworkRequest) msg.obj); break; case EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS: DataEvaluationReason reason = (DataEvaluationReason) msg.obj; onReevaluateUnsatisfiedNetworkRequests(reason); Loading Loading @@ -1044,7 +1038,7 @@ public class DataNetworkController extends Handler { return; } logv("onAddNetworkRequest: added " + networkRequest); sendMessage(obtainMessage(EVENT_SATISFY_NETWORK_REQUEST, networkRequest)); onSatisfyNetworkRequest(networkRequest); } /** Loading Loading @@ -1078,6 +1072,12 @@ public class DataNetworkController extends Handler { setupDataNetwork(dataProfile, null, evaluation.getDataAllowedReason()); } } else if (evaluation.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) { // Re-evaluate the existing data networks. If this request's priority is higher than // the existing data network, the data network will be torn down so this request will // get a chance to be satisfied. sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS, DataEvaluationReason.SINGLE_DATA_NETWORK_ARBITRATION)); } } Loading Loading @@ -1144,7 +1144,6 @@ public class DataNetworkController extends Handler { */ private boolean shouldCheckRegistrationState() { // Always don't check registration state on non-DDS sub. log("shouldCheckRegistrationState: phoneSwitcher=" + PhoneSwitcher.getInstance()); if (mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()) { return false; } Loading @@ -1156,6 +1155,16 @@ public class DataNetworkController extends Handler { return true; } /** * @return {@code true} if the network only allows single data network at one time. */ private boolean isOnlySingleDataNetworkAllowed(@TransportType int transport) { if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) return false; return mDataConfigManager.getNetworkTypesOnlySupportSingleDataNetwork() .contains(getDataNetworkType(transport)); } /** * Evaluate a network request. The goal is to find a suitable {@link DataProfile} that can be * used to setup the data network. Loading Loading @@ -1263,6 +1272,12 @@ public class DataNetworkController extends Handler { evaluation.addDataDisallowedReason(DataDisallowedReason.EMERGENCY_CALL); } // Check if only one data network is allowed. if (isOnlySingleDataNetworkAllowed(transport) && !mDataNetworkList.isEmpty()) { evaluation.addDataDisallowedReason( DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); } if (!mDataSettingsManager.isDataEnabled(DataUtils.networkCapabilityToApnType( networkRequest.getApnTypeNetworkCapability()))) { evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED); Loading Loading @@ -1440,6 +1455,24 @@ public class DataNetworkController extends Handler { evaluation.addDataDisallowedReason(DataDisallowedReason.EMERGENCY_CALL); } // Check if there are other network that has higher priority, and only single data network // is allowed. if (isOnlySingleDataNetworkAllowed(dataNetwork.getTransport())) { // If there is network request that has higher priority than this data network, then // tear down the network, regardless that network request is satisfied or not. if (mAllNetworkRequestList.stream() .filter(request -> dataNetwork.getTransport() == mAccessNetworksManager.getPreferredTransportByNetworkCapability( request.getApnTypeNetworkCapability())) .anyMatch(request -> request.getPriority() > dataNetwork.getPriority())) { evaluation.addDataDisallowedReason( DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK); } else { log("evaluateDataNetwork: " + dataNetwork + " has the highest priority. " + "No need to tear down"); } } // Check if data is disabled boolean dataDisabled = false; if (!mDataSettingsManager.isDataEnabled()) { Loading Loading @@ -1663,6 +1696,8 @@ public class DataNetworkController extends Handler { return DataNetwork.TEAR_DOWN_REASON_ILLEGAL_STATE; case VOPS_NOT_SUPPORTED: return DataNetwork.TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED; case ONLY_ALLOWED_SINGLE_NETWORK: return DataNetwork.TEAR_DOWN_ONLY_ALLOWED_SINGLE_NETWORK; } } return 0; Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +107 −5 Original line number Diff line number Diff line Loading @@ -139,8 +139,11 @@ public class DataNetworkControllerTest extends TelephonyTest { .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE) .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT)) .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) .setProfileId(1234) Loading @@ -163,8 +166,10 @@ public class DataNetworkControllerTest extends TelephonyTest { .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE) .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN)) .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) .setProfileId(1235) Loading @@ -178,6 +183,7 @@ public class DataNetworkControllerTest extends TelephonyTest { private final DataProfile mEmergencyDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setEntryName("DEFAULT EIMS") .setId(2165) .setProtocol(ApnSetting.PROTOCOL_IPV4V6) .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) .setApnName("sos") Loading @@ -187,6 +193,51 @@ public class DataNetworkControllerTest extends TelephonyTest { .build()) .build(); private final DataProfile mFotaDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setId(2166) .setOperatorNumeric("12345") .setEntryName("fota_apn") .setApnName("fota_apn") .setUser("user") .setPassword("passwd") .setApnTypeBitmask(ApnSetting.TYPE_FOTA) .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) .setProfileId(1236) .setMaxConns(321) .setWaitTime(456) .setMaxConnsTime(789) .build()) .setPreferred(false) .build(); private final DataProfile mTetheringDataProfile = new DataProfile.Builder() .setApnSetting(new ApnSetting.Builder() .setId(2167) .setOperatorNumeric("12345") .setEntryName("dun_apn") .setApnName("dun_apn") .setUser("user") .setPassword("passwd") .setApnTypeBitmask(ApnSetting.TYPE_DUN) .setProtocol(ApnSetting.PROTOCOL_IPV6) .setRoamingProtocol(ApnSetting.PROTOCOL_IP) .setCarrierEnabled(true) .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) .setProfileId(1236) .setMaxConns(321) .setWaitTime(456) .setMaxConnsTime(789) .build()) .setPreferred(false) .build(); /** Data call response map. The first key is the transport type, the second key is the cid. */ private final Map<Integer, Map<Integer, DataCallResponse>> mDataCallResponses = new HashMap<>(); Loading Loading @@ -364,6 +415,11 @@ public class DataNetworkControllerTest extends TelephonyTest { mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, true); mCarrierConfig.putIntArray(CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY, new int[] {TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B}); mContextFixture.putResource(com.android.internal.R.string.config_bandwidthEstimateSource, "bandwidth_estimator"); } Loading Loading @@ -449,14 +505,19 @@ public class DataNetworkControllerTest extends TelephonyTest { doAnswer(invocation -> { TelephonyNetworkRequest networkRequest = (TelephonyNetworkRequest) invocation.getArguments()[0]; int networkType = (int) invocation.getArguments()[1]; List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile, mImsDataProfile, mEmergencyDataProfile); mEmergencyDataProfile, mFotaDataProfile, mTetheringDataProfile); for (DataProfile dataProfile : profiles) { if (dataProfile.canSatisfy(networkRequest.getCapabilities())) { if (dataProfile.canSatisfy(networkRequest.getCapabilities()) && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0 || (dataProfile.getApnSetting().getNetworkTypeBitmask() & ServiceState.getBitmaskForTech(networkType)) != 0)) { return dataProfile; } } logd("Cannot find data profile to satisfy " + networkRequest); logd("Cannot find data profile to satisfy " + networkRequest + ", network type=" + TelephonyManager.getNetworkTypeName(networkType)); return null; }).when(mDataProfileManager).getDataProfileForNetworkRequest( any(TelephonyNetworkRequest.class), anyInt()); Loading Loading @@ -1678,4 +1739,45 @@ public class DataNetworkControllerTest extends TelephonyTest { // network should still be not-restricted. NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); } @Test public void testSinglePdnArbitration() throws Exception { // On old 1x network, only one data network is allowed. serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT, NetworkRegistrationInfo.REGISTRATION_STATE_HOME); mDataNetworkControllerUT.addNetworkRequest( createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_DUN)); processAllMessages(); verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); mDataNetworkControllerUT.addNetworkRequest( createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET)); processAllFutureMessages(); // Lower priority network should not trump the higher priority network. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); // Now send a higher priority network request TelephonyNetworkRequest fotaRequest = createNetworkRequest( NetworkCapabilities.NET_CAPABILITY_FOTA); mDataNetworkControllerUT.addNetworkRequest(fotaRequest); processAllFutureMessages(); // The existing internet data network should be torn down. verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_DUN); // The higher priority emergency data network should be established. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_FOTA); // Now remove the fota request and tear down fota network. mDataNetworkControllerUT.removeNetworkRequest(fotaRequest); processAllMessages(); List<DataNetwork> dataNetworks = getDataNetworks(); dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED); processAllMessages(); // The tethering data network should come back since now it has the highest priority after // fota is gone. verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN); verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); } }
tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,18 @@ public class DataProfileManagerTest extends TelephonyTest { assertThat(dp.getApnSetting().getApnName()).isEqualTo(TETHERING_APN); } @Test public void testGetDataProfileForNetworkRequestNoCompatibleRat() { NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone); DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, TelephonyManager.NETWORK_TYPE_GSM); // Should not find data profile due to RAT incompatible. assertThat(dp).isNull(); } @Test public void testGetDataProfileForNetworkRequestRotation() { TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( Loading