Loading src/java/com/android/internal/telephony/dataconnection/ApnSetting.java +79 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.internal.telephony.dataconnection; import android.content.Context; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.ServiceState; import android.text.TextUtils; Loading @@ -26,6 +29,8 @@ import com.android.internal.telephony.uicc.IccRecords; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; Loading @@ -34,6 +39,10 @@ import java.util.Locale; */ public class ApnSetting { static final String LOG_TAG = "ApnSetting"; private static final boolean DBG = false; static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*"; Loading Loading @@ -103,6 +112,12 @@ public class ApnSetting { * */ public boolean permanentFailed = false; /** * Metered APN types which would be accounted for in data usage. This is a map of subId -> * set of metered apn strings for the carrier. */ private static HashMap<Integer, HashSet<String>> sMeteredApnTypes = new HashMap<>(); public ApnSetting(int id, String numeric, String carrier, String apn, String proxy, String port, String mmsc, String mmsProxy, String mmsPort, Loading Loading @@ -389,6 +404,70 @@ public class ApnSetting { return false; } public boolean isMetered(Context context, int subId) { synchronized (sMeteredApnTypes) { HashSet<String> meteredApnSet = sMeteredApnTypes.get(subId); // In case of cache miss, we need to look up the settings from carrier config. if (meteredApnSet == null) { // Retrieve the metered APN types from carrier config CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) { Rlog.e(LOG_TAG, "Carrier config service is not available"); return true; } PersistableBundle b = configManager.getConfig(subId); if (b == null) { Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); return true; } String[] meteredApnTypes = b.getStringArray( CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS); if (meteredApnTypes == null) { Rlog.e(LOG_TAG, "KEY_CARRIER_METERED_APN_TYPES_STRINGS is not available. " + "subId = " + subId); return true; } meteredApnSet = new HashSet<String>(Arrays.asList(meteredApnTypes)); sMeteredApnTypes.put(subId, meteredApnSet); } if (DBG) { Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " + Arrays.toString(meteredApnSet.toArray())); } // If all types of APN are metered, then this APN setting must be metered. if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) { if (DBG) Rlog.d(LOG_TAG, "All APN types are metered."); return true; } for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (meteredApnSet.contains(type)) { if (DBG) Rlog.d(LOG_TAG, type + " is metered."); return true; } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) { // Assuming no configuration error, if at least one APN type is // metered, then this APN setting is metered. if (meteredApnSet.size() > 0) { if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); return true; } } } } if (DBG) Rlog.d(LOG_TAG, "Not metered. APN = " + toString()); return false; } // TODO - if we have this function we should also have hashCode. // Also should handle changes in type order and perhaps case-insensitivity @Override Loading src/java/com/android/internal/telephony/dataconnection/DataConnection.java +7 −0 Original line number Diff line number Diff line Loading @@ -884,6 +884,13 @@ public class DataConnection extends StateMachine { default: } } // If none of the APN types associated with this APN setting is metered, // then we apply NOT_METERED capability to the network. if (!mApnSetting.isMetered(mPhone.getContext(), mPhone.getSubId())) { result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } result.maybeMarkCapabilitiesRestricted(); } int up = 14; Loading tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +1 −0 Original line number Diff line number Diff line Loading @@ -467,6 +467,7 @@ public class ContextFixture implements TestFixture<Context> { }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt()); doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt()); mConfiguration.locale = Locale.US; doReturn(mConfiguration).when(mResources).getConfiguration(); Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java +199 −18 Original line number Diff line number Diff line Loading @@ -16,25 +16,77 @@ package com.android.internal.telephony.dataconnection; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.dataconnection.ApnSetting; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import junit.framework.TestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; public class ApnSettingTest extends TestCase { import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; public static void assertApnSettingsEqual(List<ApnSetting> a1, List<ApnSetting> a2) { public class ApnSettingTest extends TelephonyTest { private PersistableBundle mBundle; @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); mBundle = mContextFixture.getCarrierConfigBundle(); } @After public void tearDown() throws Exception { super.tearDown(); } private ApnSetting createApnSetting(String[] apnTypes) { return new ApnSetting( 2163, // id "44010", // numeric "sp-mode", // name "spmode.ne.jp", // apn "", // proxy "", // port "", // mmsc "", // mmsproxy "", // mmsport "", // user "", // password -1, // authtype apnTypes, // types "IP", // protocol "IP", // roaming_protocol true, // carrier_enabled 0, // bearer 0, // bearer_bitmask 0, // profile_id false, // modem_cognitive 0, // max_conns 0, // wait_time 0, // max_conns_time 0, // mtu "", // mvno_type ""); // mnvo_match_data } private static void assertApnSettingsEqual(List<ApnSetting> a1, List<ApnSetting> a2) { assertEquals(a1.size(), a2.size()); for (int i = 0; i < a1.size(); ++i) { assertApnSettingEqual(a1.get(i), a2.get(i)); } } public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { private static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { assertEquals(a1.carrier, a2.carrier); assertEquals(a1.apn, a2.apn); assertEquals(a1.proxy, a2.proxy); Loading Loading @@ -66,6 +118,7 @@ public class ApnSettingTest extends TestCase { assertEquals(a1.mvnoMatchData, a2.mvnoMatchData); } @Test @SmallTest public void testFromString() throws Exception { String[] dunTypes = {"DUN"}; Loading Loading @@ -113,6 +166,7 @@ public class ApnSettingTest extends TestCase { assertEquals(null, ApnSetting.fromString(testString)); } @Test @SmallTest public void testArrayFromString() throws Exception { // Test a multiple v3 string. Loading @@ -135,6 +189,7 @@ public class ApnSettingTest extends TestCase { assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString)); } @Test @SmallTest public void testToString() throws Exception { String[] types = {"default", "*"}; Loading @@ -147,4 +202,130 @@ public class ApnSettingTest extends TestCase { "IPV6, IP, true, 14, 8192, 0, false, 0, 0, 0, 0, , , false"; assertEquals(expected, apn.toString()); } @Test @SmallTest public void testIsMetered() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_MMS, PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_DUN}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 1)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 1)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 1)); } @Test @SmallTest public void testIsMeteredAnother() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_IA}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 2)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 2)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 2)); } @Test @SmallTest public void testIsMeteredNothingCharged() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{}); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_FOTA}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 3)); } @Test @SmallTest public void testIsMeteredNothingFree() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_ALL}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_DUN}). isMetered(mContext, 4)); } } No newline at end of file Loading
src/java/com/android/internal/telephony/dataconnection/ApnSetting.java +79 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.internal.telephony.dataconnection; import android.content.Context; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.ServiceState; import android.text.TextUtils; Loading @@ -26,6 +29,8 @@ import com.android.internal.telephony.uicc.IccRecords; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; Loading @@ -34,6 +39,10 @@ import java.util.Locale; */ public class ApnSetting { static final String LOG_TAG = "ApnSetting"; private static final boolean DBG = false; static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*"; Loading Loading @@ -103,6 +112,12 @@ public class ApnSetting { * */ public boolean permanentFailed = false; /** * Metered APN types which would be accounted for in data usage. This is a map of subId -> * set of metered apn strings for the carrier. */ private static HashMap<Integer, HashSet<String>> sMeteredApnTypes = new HashMap<>(); public ApnSetting(int id, String numeric, String carrier, String apn, String proxy, String port, String mmsc, String mmsProxy, String mmsPort, Loading Loading @@ -389,6 +404,70 @@ public class ApnSetting { return false; } public boolean isMetered(Context context, int subId) { synchronized (sMeteredApnTypes) { HashSet<String> meteredApnSet = sMeteredApnTypes.get(subId); // In case of cache miss, we need to look up the settings from carrier config. if (meteredApnSet == null) { // Retrieve the metered APN types from carrier config CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) { Rlog.e(LOG_TAG, "Carrier config service is not available"); return true; } PersistableBundle b = configManager.getConfig(subId); if (b == null) { Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); return true; } String[] meteredApnTypes = b.getStringArray( CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS); if (meteredApnTypes == null) { Rlog.e(LOG_TAG, "KEY_CARRIER_METERED_APN_TYPES_STRINGS is not available. " + "subId = " + subId); return true; } meteredApnSet = new HashSet<String>(Arrays.asList(meteredApnTypes)); sMeteredApnTypes.put(subId, meteredApnSet); } if (DBG) { Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " + Arrays.toString(meteredApnSet.toArray())); } // If all types of APN are metered, then this APN setting must be metered. if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) { if (DBG) Rlog.d(LOG_TAG, "All APN types are metered."); return true; } for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (meteredApnSet.contains(type)) { if (DBG) Rlog.d(LOG_TAG, type + " is metered."); return true; } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) { // Assuming no configuration error, if at least one APN type is // metered, then this APN setting is metered. if (meteredApnSet.size() > 0) { if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); return true; } } } } if (DBG) Rlog.d(LOG_TAG, "Not metered. APN = " + toString()); return false; } // TODO - if we have this function we should also have hashCode. // Also should handle changes in type order and perhaps case-insensitivity @Override Loading
src/java/com/android/internal/telephony/dataconnection/DataConnection.java +7 −0 Original line number Diff line number Diff line Loading @@ -884,6 +884,13 @@ public class DataConnection extends StateMachine { default: } } // If none of the APN types associated with this APN setting is metered, // then we apply NOT_METERED capability to the network. if (!mApnSetting.isMetered(mPhone.getContext(), mPhone.getSubId())) { result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } result.maybeMarkCapabilitiesRestricted(); } int up = 14; Loading
tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +1 −0 Original line number Diff line number Diff line Loading @@ -467,6 +467,7 @@ public class ContextFixture implements TestFixture<Context> { }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt()); doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt()); mConfiguration.locale = Locale.US; doReturn(mConfiguration).when(mResources).getConfiguration(); Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java +199 −18 Original line number Diff line number Diff line Loading @@ -16,25 +16,77 @@ package com.android.internal.telephony.dataconnection; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.dataconnection.ApnSetting; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import junit.framework.TestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; public class ApnSettingTest extends TestCase { import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; public static void assertApnSettingsEqual(List<ApnSetting> a1, List<ApnSetting> a2) { public class ApnSettingTest extends TelephonyTest { private PersistableBundle mBundle; @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); mBundle = mContextFixture.getCarrierConfigBundle(); } @After public void tearDown() throws Exception { super.tearDown(); } private ApnSetting createApnSetting(String[] apnTypes) { return new ApnSetting( 2163, // id "44010", // numeric "sp-mode", // name "spmode.ne.jp", // apn "", // proxy "", // port "", // mmsc "", // mmsproxy "", // mmsport "", // user "", // password -1, // authtype apnTypes, // types "IP", // protocol "IP", // roaming_protocol true, // carrier_enabled 0, // bearer 0, // bearer_bitmask 0, // profile_id false, // modem_cognitive 0, // max_conns 0, // wait_time 0, // max_conns_time 0, // mtu "", // mvno_type ""); // mnvo_match_data } private static void assertApnSettingsEqual(List<ApnSetting> a1, List<ApnSetting> a2) { assertEquals(a1.size(), a2.size()); for (int i = 0; i < a1.size(); ++i) { assertApnSettingEqual(a1.get(i), a2.get(i)); } } public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { private static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { assertEquals(a1.carrier, a2.carrier); assertEquals(a1.apn, a2.apn); assertEquals(a1.proxy, a2.proxy); Loading Loading @@ -66,6 +118,7 @@ public class ApnSettingTest extends TestCase { assertEquals(a1.mvnoMatchData, a2.mvnoMatchData); } @Test @SmallTest public void testFromString() throws Exception { String[] dunTypes = {"DUN"}; Loading Loading @@ -113,6 +166,7 @@ public class ApnSettingTest extends TestCase { assertEquals(null, ApnSetting.fromString(testString)); } @Test @SmallTest public void testArrayFromString() throws Exception { // Test a multiple v3 string. Loading @@ -135,6 +189,7 @@ public class ApnSettingTest extends TestCase { assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString)); } @Test @SmallTest public void testToString() throws Exception { String[] types = {"default", "*"}; Loading @@ -147,4 +202,130 @@ public class ApnSettingTest extends TestCase { "IPV6, IP, true, 14, 8192, 0, false, 0, 0, 0, 0, , , false"; assertEquals(expected, apn.toString()); } @Test @SmallTest public void testIsMetered() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_MMS, PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_DUN}). isMetered(mContext, 1)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 1)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 1)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 1)); } @Test @SmallTest public void testIsMeteredAnother() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_IA}). isMetered(mContext, 2)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 2)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 2)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 2)); } @Test @SmallTest public void testIsMeteredNothingCharged() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{}); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IMS, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_FOTA}). isMetered(mContext, 3)); assertFalse(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 3)); } @Test @SmallTest public void testIsMeteredNothingFree() throws Exception { mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_ALL}); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_ALL}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}). isMetered(mContext, 4)); assertTrue(createApnSetting( new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_DUN}). isMetered(mContext, 4)); } } No newline at end of file