| /* |
| * Copyright 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony.data; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| |
| import static org.mockito.ArgumentMatchers.any; |
| import static org.mockito.ArgumentMatchers.anyInt; |
| import static org.mockito.ArgumentMatchers.eq; |
| import static org.mockito.Mockito.doAnswer; |
| import static org.mockito.Mockito.doReturn; |
| import static org.mockito.Mockito.verify; |
| |
| import android.annotation.NonNull; |
| import android.content.ContentValues; |
| import android.database.Cursor; |
| import android.database.MatrixCursor; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkCapabilities; |
| import android.net.NetworkRequest; |
| import android.net.Uri; |
| import android.os.Looper; |
| import android.os.SystemClock; |
| import android.provider.Telephony; |
| import android.telephony.AccessNetworkConstants; |
| import android.telephony.NetworkRegistrationInfo; |
| import android.telephony.ServiceState; |
| import android.telephony.TelephonyManager; |
| import android.telephony.data.ApnSetting; |
| import android.telephony.data.DataProfile; |
| import android.telephony.data.TrafficDescriptor; |
| import android.telephony.data.TrafficDescriptor.OsAppId; |
| import android.test.mock.MockContentProvider; |
| import android.test.mock.MockContentResolver; |
| import android.testing.AndroidTestingRunner; |
| import android.testing.TestableLooper; |
| |
| import com.android.internal.telephony.TelephonyTest; |
| import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback; |
| import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; |
| import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.ArgumentCaptor; |
| import org.mockito.Mockito; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| @RunWith(AndroidTestingRunner.class) |
| @TestableLooper.RunWithLooper |
| public class DataProfileManagerTest extends TelephonyTest { |
| private static final String GENERAL_PURPOSE_APN = "GP_APN"; |
| private static final String GENERAL_PURPOSE_APN1 = "GP_APN1"; |
| private static final String IMS_APN = "IMS_APN"; |
| private static final String TETHERING_APN = "DUN_APN"; |
| private static final String APN_SET_ID_1_APN = "APN_SET_ID_1_APN"; |
| private static final String APN_SET_ID_1_TETHERING_APN = "APN_SET_ID_1_TETHERING_APN"; |
| private static final String MATCH_ALL_APN_SET_ID_IMS_APN = "MATCH_ALL_APN_SET_ID_IMS_APN"; |
| private static final String PLMN = "330123"; |
| private static final int DEFAULT_APN_SET_ID = Telephony.Carriers.NO_APN_SET_ID; |
| private static final int APN_SET_ID_1 = 1; |
| private static final int MATCH_ALL_APN_SET_ID = Telephony.Carriers.MATCH_ALL_APN_SET_ID; |
| |
| // Mocked classes |
| private DataProfileManagerCallback mDataProfileManagerCallback; |
| |
| private DataProfileManager mDataProfileManagerUT; |
| |
| private final ApnSettingContentProvider mApnSettingContentProvider = |
| new ApnSettingContentProvider(); |
| |
| private int mPreferredApnId = 0; |
| |
| private DataNetworkControllerCallback mDataNetworkControllerCallback; |
| |
| private DataConfigManagerCallback mDataConfigManagerCallback; |
| |
| private boolean mSimInserted = true; |
| |
| private class ApnSettingContentProvider extends MockContentProvider { |
| public final String[] APN_COLUMNS = new String[]{ |
| Telephony.Carriers._ID, Telephony.Carriers.NUMERIC, |
| Telephony.Carriers.NAME, Telephony.Carriers.APN, |
| Telephony.Carriers.PROXY, Telephony.Carriers.PORT, |
| Telephony.Carriers.MMSC, Telephony.Carriers.MMSPROXY, |
| Telephony.Carriers.MMSPORT, Telephony.Carriers.USER, |
| Telephony.Carriers.PASSWORD, Telephony.Carriers.AUTH_TYPE, |
| Telephony.Carriers.TYPE, |
| Telephony.Carriers.PROTOCOL, |
| Telephony.Carriers.ROAMING_PROTOCOL, |
| Telephony.Carriers.CARRIER_ENABLED, |
| Telephony.Carriers.PROFILE_ID, |
| Telephony.Carriers.MODEM_PERSIST, |
| Telephony.Carriers.MAX_CONNECTIONS, |
| Telephony.Carriers.WAIT_TIME_RETRY, |
| Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS, |
| Telephony.Carriers.MTU, |
| Telephony.Carriers.MTU_V4, |
| Telephony.Carriers.MTU_V6, |
| Telephony.Carriers.MVNO_TYPE, |
| Telephony.Carriers.MVNO_MATCH_DATA, |
| Telephony.Carriers.NETWORK_TYPE_BITMASK, |
| Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK, |
| Telephony.Carriers.APN_SET_ID, |
| Telephony.Carriers.CARRIER_ID, |
| Telephony.Carriers.SKIP_464XLAT, |
| Telephony.Carriers.ALWAYS_ON, |
| }; |
| |
| private int mPreferredApnSet = 0; |
| |
| public List<Object> mAllApnSettings = List.of( |
| new Object[]{ |
| 1, // id |
| PLMN, // numeric |
| GENERAL_PURPOSE_APN, // name |
| GENERAL_PURPOSE_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "default,supl,mms,ia", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 1280, // mtu_v4 |
| 1280, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| DEFAULT_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| new Object[]{ |
| 2, // id |
| PLMN, // numeric |
| IMS_APN, // name |
| IMS_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "ims", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 0, // mtu_v4 |
| 0, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| DEFAULT_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| new Object[]{ |
| 3, // id |
| PLMN, // numeric |
| TETHERING_APN, // name |
| TETHERING_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "dun", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 2, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 0, // mtu_v4 |
| 0, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| DEFAULT_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // alwys_on |
| }, |
| new Object[]{ |
| 4, // id |
| PLMN, // numeric |
| GENERAL_PURPOSE_APN1, // name |
| GENERAL_PURPOSE_APN1, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "default,supl", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 0, // mtu_v4 |
| 0, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| DEFAULT_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| // This APN entry is created to test de-duping. |
| new Object[]{ |
| 5, // id |
| PLMN, // numeric |
| GENERAL_PURPOSE_APN, // name |
| GENERAL_PURPOSE_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "fota", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 0, // mtu_v4 |
| 0, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| DEFAULT_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| new Object[]{ |
| 6, // id |
| PLMN, // numeric |
| APN_SET_ID_1_APN, // name |
| APN_SET_ID_1_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "default,supl,mms,ia", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 1280, // mtu_v4 |
| 1280, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| APN_SET_ID_1, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| new Object[]{ |
| 7, // id |
| PLMN, // numeric |
| APN_SET_ID_1_TETHERING_APN, // name |
| APN_SET_ID_1_TETHERING_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "dun", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 1280, // mtu_v4 |
| 1280, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| APN_SET_ID_1, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| }, |
| new Object[]{ |
| 8, // id |
| PLMN, // numeric |
| MATCH_ALL_APN_SET_ID_IMS_APN, // name |
| MATCH_ALL_APN_SET_ID_IMS_APN, // apn |
| "", // proxy |
| "", // port |
| "", // mmsc |
| "", // mmsproxy |
| "", // mmsport |
| "", // user |
| "", // password |
| -1, // authtype |
| "ims", // types |
| "IPV4V6", // protocol |
| "IPV4V6", // roaming_protocol |
| 1, // carrier_enabled |
| 0, // profile_id |
| 1, // modem_cognitive |
| 0, // max_conns |
| 0, // wait_time |
| 0, // max_conns_time |
| 0, // mtu |
| 1280, // mtu_v4 |
| 1280, // mtu_v6 |
| "", // mvno_type |
| "", // mnvo_match_data |
| TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask |
| 0, // lingering_network_type_bitmask |
| MATCH_ALL_APN_SET_ID, // apn_set_id |
| -1, // carrier_id |
| -1, // skip_464xlat |
| 0 // always_on |
| } |
| ); |
| |
| private Set<Object> mDeletedApns = new HashSet<>(); |
| |
| @Override |
| public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, |
| String sortOrder) { |
| logd("ApnSettingContentProvider: query"); |
| logd(" uri = " + uri); |
| logd(" projection = " + Arrays.toString(projection)); |
| logd(" selection = " + selection); |
| logd(" selectionArgs = " + Arrays.toString(selectionArgs)); |
| logd(" sortOrder = " + sortOrder); |
| |
| if (uri.compareTo(Telephony.Carriers.CONTENT_URI) == 0 |
| || uri.toString().startsWith(Uri.withAppendedPath( |
| Telephony.Carriers.CONTENT_URI, "filtered").toString()) |
| || uri.toString().startsWith(Uri.withAppendedPath( |
| Telephony.Carriers.SIM_APN_URI, "filtered").toString())) { |
| if (projection == null) { |
| |
| logd("Query '" + PLMN + "' APN settings"); |
| MatrixCursor mc = new MatrixCursor(APN_COLUMNS); |
| if (mSimInserted) { |
| for (Object apnSetting : mAllApnSettings) { |
| if (!mDeletedApns.contains(apnSetting)) { |
| mc.addRow((Object[]) apnSetting); |
| } |
| } |
| } |
| return mc; |
| } |
| } else if (isPathPrefixMatch(uri, |
| Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapnset"))) { |
| MatrixCursor mc = new MatrixCursor( |
| new String[]{Telephony.Carriers.APN_SET_ID}); |
| // apn_set_id is the only field used with this URL |
| mc.addRow(new Object[]{ mPreferredApnSet }); |
| mc.addRow(new Object[]{ 0 }); |
| return mc; |
| } else if (uri.isPathPrefixMatch(Telephony.Carriers.PREFERRED_APN_URI)) { |
| for (Object apnSetting : mAllApnSettings) { |
| if (!mDeletedApns.contains(apnSetting)) { |
| int id = (int) ((Object[]) apnSetting)[0]; |
| if (id == mPreferredApnId) { |
| MatrixCursor mc = new MatrixCursor(APN_COLUMNS); |
| mc.addRow((Object[]) apnSetting); |
| return mc; |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public int update(Uri url, ContentValues values, String where, String[] whereArgs) { |
| mPreferredApnSet = values.getAsInteger(Telephony.Carriers.APN_SET_ID); |
| return 1; |
| } |
| |
| @Override |
| public int delete(Uri uri, String selection, String[] selectionArgs) { |
| return 0; |
| } |
| |
| @Override |
| public Uri insert(Uri uri, ContentValues values) { |
| logd("ApnSettingContentProvider: uri=" + uri + ", values=" + values); |
| if (uri.isPathPrefixMatch(Telephony.Carriers.PREFERRED_APN_URI)) { |
| mPreferredApnId = values.getAsInteger(Telephony.Carriers.APN_ID); |
| if (mPreferredApnId != -1) { |
| for (Object apnSetting : mAllApnSettings) { |
| int id = (int) ((Object[]) apnSetting)[0]; |
| if (id == mPreferredApnId) { |
| mPreferredApnSet = (int) ((Object[]) apnSetting)[28]; //update setId too |
| } |
| } |
| } else { |
| mPreferredApnSet = 0; // db is emptied |
| } |
| logd("mPreferredApnId=" + mPreferredApnId); |
| } |
| return null; |
| } |
| |
| public boolean removeApnByApnId(int apnId) { |
| for (Object apnSetting : mAllApnSettings) { |
| int id = (int) ((Object[]) apnSetting)[0]; |
| if (apnId == id) { |
| mDeletedApns.add(apnSetting); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| public void restoreApnSettings() { |
| mDeletedApns.clear(); |
| } |
| |
| public void setPreferredApn(String apnName) { |
| for (Object apnSetting : mAllApnSettings) { |
| if (apnName == ((Object[]) apnSetting)[3]) { |
| mPreferredApnId = (int) ((Object[]) apnSetting)[0]; |
| mPreferredApnSet = (int) ((Object[]) apnSetting)[28]; |
| logd("mPreferredApnId=" + mPreferredApnId + " ,mPreferredApnSet=" |
| + mPreferredApnSet); |
| break; |
| } |
| } |
| } |
| |
| public int getCountApnSpecifyType(String type) { |
| int count = 0; |
| for (Object apnSetting : mAllApnSettings) { |
| String apnTypes = (String) ((Object[]) apnSetting)[12]; |
| if (apnTypes.contains(type)) { |
| count++; |
| } |
| } |
| return count; |
| } |
| } |
| |
| /** |
| * Test if this is a path prefix match against the given Uri. Verifies that |
| * scheme, authority, and atomic path segments match. |
| * |
| * Copied from frameworks/base/core/java/android/net/Uri.java |
| */ |
| private boolean isPathPrefixMatch(Uri uriA, Uri uriB) { |
| if (!Objects.equals(uriA.getScheme(), uriB.getScheme())) return false; |
| if (!Objects.equals(uriA.getAuthority(), uriB.getAuthority())) return false; |
| |
| List<String> segA = uriA.getPathSegments(); |
| List<String> segB = uriB.getPathSegments(); |
| |
| final int size = segB.size(); |
| if (segA.size() < size) return false; |
| |
| for (int i = 0; i < size; i++) { |
| if (!Objects.equals(segA.get(i), segB.get(i))) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| private void dedupeDataProfiles(@NonNull List<DataProfile> dataProfiles) throws Exception { |
| Class[] cArgs = new Class[1]; |
| cArgs[0] = List.class; |
| Method method = DataProfileManager.class.getDeclaredMethod("dedupeDataProfiles", cArgs); |
| method.setAccessible(true); |
| method.invoke(mDataProfileManagerUT, dataProfiles); |
| } |
| |
| private @NonNull List<DataProfile> getAllDataProfiles() throws Exception { |
| Field field = DataProfileManager.class.getDeclaredField("mAllDataProfiles"); |
| field.setAccessible(true); |
| return (List<DataProfile>) field.get(mDataProfileManagerUT); |
| } |
| |
| @Before |
| public void setUp() throws Exception { |
| logd("DataProfileManagerTest +Setup!"); |
| super.setUp(getClass().getSimpleName()); |
| mDataProfileManagerCallback = Mockito.mock(DataProfileManagerCallback.class); |
| ((MockContentResolver) mContext.getContentResolver()).addProvider( |
| Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider); |
| |
| doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific(); |
| doReturn(List.of(ApnSetting.TYPE_IA, ApnSetting.TYPE_DEFAULT)) |
| .when(mDataConfigManager).getAllowedInitialAttachApnTypes(); |
| doAnswer(invocation -> { |
| ((Runnable) invocation.getArguments()[0]).run(); |
| return null; |
| }).when(mDataProfileManagerCallback).invokeFromExecutor(any(Runnable.class)); |
| mDataProfileManagerUT = new DataProfileManager(mPhone, mDataNetworkController, |
| mMockedWwanDataServiceManager, Looper.myLooper(), mDataProfileManagerCallback); |
| ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor = |
| ArgumentCaptor.forClass(DataNetworkControllerCallback.class); |
| verify(mDataNetworkController).registerDataNetworkControllerCallback( |
| dataNetworkControllerCallbackCaptor.capture()); |
| mDataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue(); |
| ArgumentCaptor<DataConfigManagerCallback> dataConfigManagerCallbackCaptor = |
| ArgumentCaptor.forClass(DataConfigManagerCallback.class); |
| verify(mDataConfigManager).registerCallback(dataConfigManagerCallbackCaptor.capture()); |
| mDataConfigManagerCallback = dataConfigManagerCallbackCaptor.getValue(); |
| mDataConfigManagerCallback.onCarrierConfigChanged(); |
| processAllMessages(); |
| |
| logd("DataProfileManagerTest -Setup!"); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| mDataProfileManagerUT = null; |
| mDataNetworkControllerCallback = null; |
| mDataConfigManagerCallback = null; |
| super.tearDown(); |
| } |
| |
| @Test |
| public void testGetDataProfileForNetworkRequest() { |
| 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_LTE, false); |
| |
| assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue(); |
| assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| |
| request = new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS) |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL) |
| .build(); |
| tnr = new TelephonyNetworkRequest(request, mPhone); |
| dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false); |
| |
| assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue(); |
| assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| |
| request = new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS) |
| .build(); |
| tnr = new TelephonyNetworkRequest(request, mPhone); |
| dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue(); |
| assertThat(dp.getApnSetting().getApnName()).isEqualTo(IMS_APN); |
| |
| request = new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN) |
| .build(); |
| tnr = new TelephonyNetworkRequest(request, mPhone); |
| dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dp).isNull(); |
| |
| doReturn(new NetworkRegistrationInfo.Builder() |
| .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR) |
| .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) |
| .build()).when(mServiceState).getNetworkRegistrationInfo(anyInt(), anyInt()); |
| |
| request = new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN) |
| .build(); |
| tnr = new TelephonyNetworkRequest(request, mPhone); |
| dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_NR, false); |
| assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue(); |
| 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, false); |
| // Should not find data profile due to RAT incompatible. |
| assertThat(dp).isNull(); |
| } |
| |
| @Test |
| public void testGetDataProfileForNetworkRequestRotation() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| logd("Set setLastSetupTimestamp on " + dataProfile); |
| dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime()); |
| |
| // See if another one can be returned. |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1); |
| } |
| |
| @Test |
| public void testGetDataProfileForEnterpriseNetworkRequest() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting()).isNull(); |
| OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId()); |
| |
| assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID); |
| assertThat(osAppId.getAppId()).isEqualTo("ENTERPRISE"); |
| assertThat(osAppId.getDifferentiator()).isEqualTo(1); |
| |
| tnr = new TelephonyNetworkRequest(new NetworkRequest(new NetworkCapabilities() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE) |
| .addEnterpriseId(2), ConnectivityManager.TYPE_NONE, |
| 0, NetworkRequest.Type.REQUEST), mPhone); |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting()).isNull(); |
| osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId()); |
| |
| assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID); |
| assertThat(osAppId.getAppId()).isEqualTo("ENTERPRISE"); |
| assertThat(osAppId.getDifferentiator()).isEqualTo(2); |
| } |
| |
| @Test |
| public void testGetDataProfileForUrllcNetworkRequest() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting()).isNull(); |
| OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId()); |
| |
| assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID); |
| assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_LATENCY"); |
| assertThat(osAppId.getDifferentiator()).isEqualTo(1); |
| } |
| |
| @Test |
| public void testGetDataProfileForEmbbNetworkRequest() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting()).isNull(); |
| OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId()); |
| |
| assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID); |
| assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_BANDWIDTH"); |
| assertThat(osAppId.getDifferentiator()).isEqualTo(1); |
| } |
| |
| |
| @Test |
| public void testSetPreferredDataProfile() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime()); |
| dataProfile.setPreferred(true); |
| mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile)); |
| processAllMessages(); |
| |
| // See if the same one can be returned. |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| } |
| |
| @Test |
| public void testSetInitialAttachDataProfile() { |
| ArgumentCaptor<DataProfile> dataProfileCaptor = |
| ArgumentCaptor.forClass(DataProfile.class); |
| |
| verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(), |
| eq(false), eq(null)); |
| assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName()) |
| .isEqualTo(GENERAL_PURPOSE_APN); |
| } |
| |
| @Test |
| public void testSetInitialAttachDataProfileMultipleRequests() throws Exception { |
| // Test: Modem Cleared IA, should always send IA to modem |
| // TODO(b/237444788): this case should be removed from U |
| mDataProfileManagerUT.obtainMessage(3 /* EVENT_SIM_REFRESH */).sendToTarget(); |
| processAllMessages(); |
| |
| Field IADPField = DataProfileManager.class.getDeclaredField("mInitialAttachDataProfile"); |
| IADPField.setAccessible(true); |
| DataProfile dp = (DataProfile) IADPField.get(mDataProfileManagerUT); |
| |
| Mockito.clearInvocations(mMockedWwanDataServiceManager); |
| mDataProfileManagerUT.obtainMessage(3 /* EVENT_SIM_REFRESH */).sendToTarget(); |
| processAllMessages(); |
| DataProfile dp2 = (DataProfile) IADPField.get(mDataProfileManagerUT); |
| |
| assertThat(Objects.equals(dp, dp2)).isTrue(); |
| verify(mMockedWwanDataServiceManager) |
| .setInitialAttachApn(any(DataProfile.class), eq(false), eq(null)); |
| |
| // Test: Modem did NOT clear IA, should not send IA to modem even if IA stays the same |
| mDataProfileManagerUT.obtainMessage(2 /* EVENT_APN_DATABASE_CHANGED */).sendToTarget(); |
| processAllMessages(); |
| |
| IADPField = DataProfileManager.class.getDeclaredField("mInitialAttachDataProfile"); |
| IADPField.setAccessible(true); |
| dp = (DataProfile) IADPField.get(mDataProfileManagerUT); |
| Mockito.clearInvocations(mMockedWwanDataServiceManager); |
| |
| mDataProfileManagerUT.obtainMessage(2 /* EVENT_APN_DATABASE_CHANGED */).sendToTarget(); |
| processAllMessages(); |
| dp2 = (DataProfile) IADPField.get(mDataProfileManagerUT); |
| |
| assertThat(Objects.equals(dp, dp2)).isTrue(); |
| verify(mMockedWwanDataServiceManager, Mockito.never()) |
| .setInitialAttachApn(any(DataProfile.class), eq(false), eq(null)); |
| } |
| |
| @Test |
| public void testSimRemoval() { |
| Mockito.clearInvocations(mDataProfileManagerCallback); |
| changeSimStateTo(TelephonyManager.SIM_STATE_ABSENT); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| verify(mDataProfileManagerCallback).onDataProfilesChanged(); |
| |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile).isNull(); |
| |
| // expect default EIMS when SIM absent |
| tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS) |
| .build(), mPhone); |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos"); |
| |
| // expect no default IMS when SIM absent |
| tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS) |
| .build(), mPhone); |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile).isEqualTo(null); |
| } |
| |
| @Test |
| public void testSimInsertedAgain() throws Exception { |
| testSimRemoval(); |
| Mockito.clearInvocations(mDataProfileManagerCallback); |
| Mockito.clearInvocations(mMockedWwanDataServiceManager); |
| |
| doReturn(List.of(ApnSetting.TYPE_IMS)) |
| .when(mDataConfigManager).getAllowedInitialAttachApnTypes(); |
| |
| changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| ArgumentCaptor<DataProfile> dataProfileCaptor = |
| ArgumentCaptor.forClass(DataProfile.class); |
| |
| verify(mDataProfileManagerCallback).onDataProfilesChanged(); |
| verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(), |
| eq(false), eq(null)); |
| |
| // Should only use IMS APN for initial attach |
| assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName()).isEqualTo(IMS_APN); |
| |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| new TelephonyNetworkRequest(new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS) |
| .build(), mPhone), |
| TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(IMS_APN); |
| } |
| |
| @Test |
| public void testDedupeDataProfiles() { |
| NetworkRequest request = new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA) |
| .build(); |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone); |
| // This should get the merged data profile after deduping. |
| DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue(); |
| } |
| |
| @Test |
| public void testDedupeDataProfiles2() throws Exception { |
| DataProfile dataProfile1 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName("general") |
| .setApnName("apn") |
| .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS |
| | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_HIPRI) |
| .setUser("user") |
| .setPassword("password") |
| .setAuthType(ApnSetting.AUTH_TYPE_CHAP) |
| .setMmsc(Uri.parse("http://mms-s")) |
| .setMmsProxyAddress("mmsc.proxy") |
| .setMmsProxyPort(8080) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setMvnoMatchData("1") |
| .setMvnoType(1) |
| .build()) |
| .build(); |
| |
| DataProfile dataProfile2 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName("XCAP") |
| .setApnName("apn") |
| .setApnTypeBitmask(ApnSetting.TYPE_XCAP) |
| .setUser("user") |
| .setPassword("password") |
| .setAuthType(ApnSetting.AUTH_TYPE_CHAP) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setMvnoMatchData("2") |
| .setMvnoType(2) |
| .build()) |
| .build(); |
| |
| logd("apn1=" + dataProfile1.getApnSetting()); |
| logd("apn2=" + dataProfile2.getApnSetting()); |
| logd("apn1 can handle default=" + dataProfile1.getApnSetting() |
| .canHandleType(ApnSetting.TYPE_DEFAULT)); |
| logd("apn2 can handle default=" + dataProfile2.getApnSetting() |
| .canHandleType(ApnSetting.TYPE_DEFAULT)); |
| assertThat(dataProfile1.getApnSetting().similar(dataProfile2.getApnSetting())).isTrue(); |
| |
| List<DataProfile> dataProfiles = new ArrayList<>(Arrays.asList(dataProfile2, dataProfile1)); |
| |
| dedupeDataProfiles(dataProfiles); |
| // After deduping, there should be only one. |
| assertThat(dataProfiles).hasSize(1); |
| |
| DataProfile dataProfile = dataProfiles.get(0); |
| assertThat(dataProfile.getApnSetting()).isNotNull(); |
| |
| logd("Merged profile=" + dataProfile); |
| assertThat(dataProfile.getApnSetting().getEntryName()).isEqualTo("general"); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("apn"); |
| assertThat(dataProfile.getApnSetting().getApnTypeBitmask()).isEqualTo( |
| ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL |
| | ApnSetting.TYPE_HIPRI | ApnSetting.TYPE_XCAP); |
| assertThat(dataProfile.getApnSetting().getUser()).isEqualTo("user"); |
| assertThat(dataProfile.getApnSetting().getPassword()).isEqualTo("password"); |
| assertThat(dataProfile.getApnSetting().getAuthType()).isEqualTo(ApnSetting.AUTH_TYPE_CHAP); |
| assertThat(dataProfile.getApnSetting().getMmsc()).isEqualTo(Uri.parse("http://mms-s")); |
| assertThat(dataProfile.getApnSetting().getMmsProxyAddressAsString()) |
| .isEqualTo("mmsc.proxy"); |
| assertThat(dataProfile.getApnSetting().getMmsProxyPort()).isEqualTo(8080); |
| assertThat(dataProfile.getApnSetting().getProtocol()).isEqualTo(ApnSetting.PROTOCOL_IPV4V6); |
| assertThat(dataProfile.getApnSetting().getRoamingProtocol()) |
| .isEqualTo(ApnSetting.PROTOCOL_IPV4V6); |
| } |
| |
| @Test |
| public void testDedupeDataProfiles3() throws Exception { |
| DataProfile dataProfile1 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName("BTT Lastgenphone") |
| .setId(1) |
| .setOperatorNumeric("123456") |
| .setApnName("lastgenphone") |
| .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS |
| | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA) |
| .setMmsc(Uri.parse("http://mmsc.mobile.btt.net")) |
| .setMmsProxyAddress("proxy.mobile.btt.net") |
| .setMmsProxyPort(80) |
| .setMtuV4(1410) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .build()) |
| .build(); |
| |
| DataProfile dataProfile2 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName("BTT XCAP") |
| .setId(5) |
| .setOperatorNumeric("123456") |
| .setApnName("lastgenphone") |
| .setApnTypeBitmask(ApnSetting.TYPE_XCAP) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .build()) |
| .build(); |
| |
| List<DataProfile> dataProfiles = new ArrayList<>(Arrays.asList(dataProfile2, dataProfile1)); |
| |
| logd("dp1.apnSetting, dp2.apnSetting similar=" |
| + dataProfile1.getApnSetting().similar(dataProfile2.getApnSetting())); |
| |
| dedupeDataProfiles(dataProfiles); |
| // After deduping, there should be only one. |
| assertThat(dataProfiles).hasSize(1); |
| |
| DataProfile dataProfile = dataProfiles.get(0); |
| assertThat(dataProfile.getApnSetting()).isNotNull(); |
| |
| |
| logd("After merged: " + dataProfile); |
| assertThat(dataProfile.getApnSetting().getApnTypeBitmask()).isEqualTo( |
| ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL |
| | ApnSetting.TYPE_FOTA | ApnSetting.TYPE_XCAP); |
| } |
| |
| @Test |
| public void testDefaultEmergencyDataProfileValid() { |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| |
| assertThat(dataProfile.getApn()).isEqualTo("sos"); |
| assertThat(dataProfile.getTrafficDescriptor().getDataNetworkName()).isEqualTo("sos"); |
| } |
| |
| @Test |
| public void testResetApn() { |
| changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| .build(), mPhone); |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN); |
| dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime()); |
| mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile)); |
| processAllMessages(); |
| |
| // After internet connected, preferred APN should be set |
| assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue(); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue(); |
| |
| // APN reset |
| mPreferredApnId = -1; |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| // preferred APN should set to be the last data profile that succeeded for internet setup |
| assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue(); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue(); |
| |
| // Test user selected a bad data profile, expects to adopt the last data profile that |
| // succeeded for internet setup after APN reset |
| // some bad profile that cannot be used for internet |
| mApnSettingContentProvider.setPreferredApn(MATCH_ALL_APN_SET_ID_IMS_APN); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue(); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse(); |
| |
| // APN reset, preferred APN should set to be the last data profile that succeeded for |
| // internet setup |
| mPreferredApnId = -1; |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue(); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue(); |
| |
| // Test removed data profile(user created after reset) shouldn't show up |
| mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile)); |
| processAllMessages(); |
| //APN reset and removed GENERAL_PURPOSE_APN from APN DB |
| mPreferredApnId = -1; |
| mApnSettingContentProvider.removeApnByApnId(1); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| // There should be no preferred APN after APN reset because last working profile is removed |
| assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isFalse(); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse(); |
| |
| // restore mApnSettingContentProvider |
| mApnSettingContentProvider.restoreApnSettings(); |
| } |
| |
| @Test |
| public void testResetApnWithPreferredConfig() { |
| // carrier configured preferred data profile should be picked |
| doReturn(GENERAL_PURPOSE_APN1).when(mDataConfigManager).getDefaultPreferredApn(); |
| TelephonyNetworkRequest tnr = new TelephonyNetworkRequest( |
| new NetworkRequest.Builder() |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) |
| .build(), mPhone); |
| changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| // The carrier configured data profile should be the preferred APN after APN reset |
| DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue(); |
| |
| // APN reset |
| mPreferredApnId = -1; |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| Mockito.clearInvocations(mDataConfigManager); |
| processAllMessages(); |
| |
| // The carrier configured data profile should be the preferred APN after APN reset |
| dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest( |
| tnr, TelephonyManager.NETWORK_TYPE_LTE, false); |
| assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1); |
| assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue(); |
| } |
| |
| @Test |
| public void testTetheringApnExisting() { |
| assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting( |
| TelephonyManager.NETWORK_TYPE_NR)).isTrue(); |
| assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting( |
| TelephonyManager.NETWORK_TYPE_LTE)).isFalse(); |
| } |
| |
| @Test |
| public void testTetheringApnDisabledForRoaming() { |
| doReturn(true).when(mDataConfigManager).isTetheringProfileDisabledForRoaming(); |
| |
| assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting( |
| TelephonyManager.NETWORK_TYPE_NR)).isTrue(); |
| |
| ServiceState ss = new ServiceState(); |
| |
| ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder() |
| .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) |
| .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR) |
| .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) |
| .setDomain(NetworkRegistrationInfo.DOMAIN_PS) |
| .build()); |
| |
| ss.setDataRoamingFromRegistration(true); |
| doReturn(ss).when(mSST).getServiceState(); |
| doReturn(ss).when(mPhone).getServiceState(); |
| |
| assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting( |
| TelephonyManager.NETWORK_TYPE_NR)).isFalse(); |
| } |
| |
| @Test |
| public void testNoDefaultIms() throws Exception { |
| List<DataProfile> dataProfiles = getAllDataProfiles(); |
| int countIms = mApnSettingContentProvider.getCountApnSpecifyType("ims"); |
| |
| // Since the database already had IMS, there should not be default IMS created in the |
| // database. |
| assertThat(dataProfiles.stream() |
| .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) |
| .collect(Collectors.toList())).hasSize(countIms); |
| } |
| |
| @Test |
| public void testDataProfileCompatibility() throws Exception { |
| DataProfile enterpriseDataProfile = new DataProfile.Builder() |
| .setTrafficDescriptor(new TrafficDescriptor(null, |
| new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID, |
| "ENTERPRISE", 1).getBytes())) |
| .build(); |
| |
| // Make sure the TD only profile is always compatible. |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(enterpriseDataProfile)).isTrue(); |
| |
| // Make sure the profile which is slightly modified is also compatible. |
| DataProfile dataProfile1 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(GENERAL_PURPOSE_APN) |
| .setId(1) |
| .setApnName(GENERAL_PURPOSE_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS |
| | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA | ApnSetting.TYPE_FOTA) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_NONE) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setPersistent(true) |
| .setMtuV4(1280) |
| .setMtuV6(1280) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(DEFAULT_APN_SET_ID) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue(); |
| } |
| |
| @Test |
| public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAsDefault() { |
| mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN); |
| changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| // Test DataProfile's apn_set_id is default so it match with current preferred apn_set_id. |
| DataProfile dataProfile1 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(TETHERING_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(TETHERING_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_DUN) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setProfileId(2) |
| .setPersistent(true) |
| .setMtuV4(0) |
| .setMtuV6(0) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(DEFAULT_APN_SET_ID) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue(); |
| |
| // Test DataProfile's apn_set_id is specified(1) so it not match with current |
| // preferred apn_set_id. |
| DataProfile dataProfile2 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(APN_SET_ID_1_TETHERING_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(APN_SET_ID_1_TETHERING_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_DUN) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setPersistent(true) |
| .setMtuV4(1280) |
| .setMtuV6(1280) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(APN_SET_ID_1) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse(); |
| |
| // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred |
| // apn_set_id. |
| DataProfile dataProfile3 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_IMS) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setPersistent(true) |
| .setMtuV4(1280) |
| .setMtuV6(1280) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(MATCH_ALL_APN_SET_ID) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue(); |
| } |
| |
| @Test |
| public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAs1() { |
| mApnSettingContentProvider.setPreferredApn(APN_SET_ID_1_APN); |
| changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); |
| mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); |
| processAllMessages(); |
| |
| // Test DataProfile's apn_set_id is same as preferred apn_set_id. |
| DataProfile dataProfile1 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(APN_SET_ID_1_TETHERING_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(APN_SET_ID_1_TETHERING_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_DUN) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setPersistent(true) |
| .setMtuV4(1280) |
| .setMtuV6(1280) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(APN_SET_ID_1) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue(); |
| |
| // Test DataProfile's apn_set_id is default. so it not match with current preferred |
| // apn_set_id(1). |
| DataProfile dataProfile2 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(TETHERING_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(TETHERING_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_DUN) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setProfileId(2) |
| .setPersistent(true) |
| .setMtuV4(0) |
| .setMtuV6(0) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(DEFAULT_APN_SET_ID) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse(); |
| |
| // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred |
| // apn_set_id. |
| DataProfile dataProfile3 = new DataProfile.Builder() |
| .setApnSetting(new ApnSetting.Builder() |
| .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN) |
| .setOperatorNumeric(PLMN) |
| .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN) |
| .setProxyAddress("") |
| .setMmsProxyAddress("") |
| .setApnTypeBitmask(ApnSetting.TYPE_IMS) |
| .setUser("") |
| .setPassword("") |
| .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN) |
| .setProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6) |
| .setCarrierEnabled(true) |
| .setPersistent(true) |
| .setMtuV4(1280) |
| .setMtuV6(1280) |
| .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE |
| | TelephonyManager.NETWORK_TYPE_BITMASK_NR)) |
| .setMvnoMatchData("") |
| .setApnSetId(MATCH_ALL_APN_SET_ID) |
| .build()) |
| .build(); |
| |
| assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue(); |
| } |
| |
| @Test |
| public void testPermanentFailureWithNoPreferredDataProfile() { |
| // No preferred APN is set |
| |
| 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_LTE, false); |
| |
| // Mark the APN as permanent failed. |
| dp.getApnSetting().setPermanentFailed(true); |
| |
| // Data profile manager should return a different data profile for setup as the previous |
| // data profile has been marked as permanent failed. |
| assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false)).isNotEqualTo(dp); |
| } |
| |
| @Test |
| public void testPermanentFailureWithPreferredDataProfile() { |
| // Set the preferred APN |
| mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN); |
| mDataProfileManagerUT.obtainMessage(2 /* EVENT_APN_DATABASE_CHANGED */).sendToTarget(); |
| processAllMessages(); |
| |
| 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_LTE, false); |
| |
| // Mark the APN as permanent failed. |
| dp.getApnSetting().setPermanentFailed(true); |
| |
| // Since preferred APN is already set, and that data profile was marked as permanent failed, |
| // so this should result in getting nothing. |
| assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, |
| TelephonyManager.NETWORK_TYPE_LTE, false)).isNull(); |
| } |
| |
| private void changeSimStateTo(@TelephonyManager.SimState int simState) { |
| mSimInserted = simState == TelephonyManager.SIM_STATE_LOADED; |
| mDataNetworkControllerCallback.onSimStateChanged(simState); |
| } |
| } |