Loading src/java/com/android/internal/telephony/dataconnection/ApnSetting.java +24 −19 Original line number Diff line number Diff line Loading @@ -404,8 +404,7 @@ public class ApnSetting { return false; } public boolean isMetered(Context context, int subId) { public static boolean isMeteredApnType(String type, Context context, int subId) { synchronized (sMeteredApnTypes) { HashSet<String> meteredApnSet = sMeteredApnTypes.get(subId); Loading Loading @@ -435,21 +434,17 @@ public class ApnSetting { 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; Loading @@ -462,8 +457,18 @@ public class ApnSetting { } } } if (DBG) Rlog.d(LOG_TAG, type + " is not metered."); return false; } public boolean isMetered(Context context, int subId) { for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (isMeteredApnType(type, context, subId)) { if (DBG) Rlog.d(LOG_TAG, "Metered. APN = " + toString()); return true; } } if (DBG) Rlog.d(LOG_TAG, "Not metered. APN = " + toString()); return false; } Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +9 −3 Original line number Diff line number Diff line Loading @@ -1463,8 +1463,10 @@ public class DcTracker extends Handler { boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY); final ServiceStateTracker sst = mPhone.getServiceStateTracker(); // set to false if apn type is non-metered. boolean checkUserDataEnabled = !(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)); !(ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone.getContext(), mPhone.getSubId())); StringBuilder failureReason = new StringBuilder(); if (apnContext.isConnectable() && (isEmergencyApn || Loading Loading @@ -1590,8 +1592,12 @@ public class DcTracker extends Handler { for (ApnContext apnContext : mApnContexts.values()) { if (apnContext.isDisconnected() == false) didDisconnect = true; if (specificdisable) { if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) { if (DBG) log("ApnConextType: " + apnContext.getApnType()); // Use ApnSetting to decide metered or non-metered. // Tear down all metered data connections. ApnSetting apnSetting = apnContext.getApnSetting(); if (apnSetting != null && apnSetting.isMetered(mPhone.getContext(), mPhone.getSubId())) { if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType()); apnContext.setReason(reason); cleanUpConnection(tearDown, apnContext); } Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java +101 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import android.net.Uri; import android.os.HandlerThread; import android.os.IBinder; import android.os.Message; import android.os.PersistableBundle; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; Loading Loading @@ -58,6 +60,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; Loading Loading @@ -96,6 +99,8 @@ public class DcTrackerTest extends TelephonyTest { private AlarmManager mAlarmManager; private PersistableBundle mBundle; private final ApnSettingContentProvider mApnSettingContentProvider = new ApnSettingContentProvider(); Loading Loading @@ -227,7 +232,7 @@ public class DcTrackerTest extends TelephonyTest { "", // user "", // password 3, // authtype "default,supl", // types "ims", // types "IP", // protocol "IP", // roaming_protocol 1, // carrier_enabled Loading Loading @@ -291,6 +296,7 @@ public class DcTrackerTest extends TelephonyTest { new String[]{"36,2"}); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mBundle = mContextFixture.getCarrierConfigBundle(); new DcTrackerTestHandler(getClass().getSimpleName()).start(); waitUntilReady(); Loading Loading @@ -502,4 +508,97 @@ public class DcTrackerTest extends TelephonyTest { // Verify connected with APN2 setting. verifyDataConnected(FAKE_APN2); } @Test @MediumTest public void testUserDisableData() throws Exception { //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS //set Default and MMS to be metered in the CarrierConfigManager boolean dataEnabled = mDct.getDataEnabled(); mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); mDct.setEnabled(5, true); mDct.setEnabled(0, true); logd("Sending EVENT_RECORDS_LOADED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null)); waitForMs(200); logd("Sending EVENT_DATA_CONNECTION_ATTACHED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null)); waitForMs(200); logd("Sending DATA_ENABLED_CMD"); mDct.setDataEnabled(true); waitForMs(200); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1), eq(""), eq(""), eq(0), eq("IP"), any(Message.class)); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3), eq(""), eq(""), eq(3), eq("IP"), any(Message.class)); logd("Sending DATA_DISABLED_CMD"); mDct.setDataEnabled(false); waitForMs(200); // expected tear down all metered DataConnections verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(), any(Message.class)); assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState()); assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT)); assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS)); // reset the setting at the end of this test mDct.setDataEnabled(dataEnabled); waitForMs(200); } @Test @MediumTest public void testUserDisableRoaming() throws Exception { //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS //set Default and MMS to be metered in the CarrierConfigManager boolean roamingEnabled = mDct.getDataOnRoamingEnabled(); mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); mDct.setEnabled(5, true); mDct.setEnabled(0, true); logd("Sending EVENT_RECORDS_LOADED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null)); waitForMs(200); logd("Sending EVENT_DATA_CONNECTION_ATTACHED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null)); waitForMs(200); logd("Sending DATA_ENABLED_CMD"); mDct.setDataEnabled(true); waitForMs(200); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1), eq(""), eq(""), eq(0), eq("IP"), any(Message.class)); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3), eq(""), eq(""), eq(3), eq("IP"), any(Message.class)); logd("Sending DISABLE_ROAMING_CMD"); mDct.setDataOnRoamingEnabled(false); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_ROAMING_ON)); waitForMs(200); // expected tear down all metered DataConnections verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(), any(Message.class)); assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState()); assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT)); assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS)); // reset roaming settings at end of this test mDct.setDataOnRoamingEnabled(roamingEnabled); waitForMs(200); } } Loading
src/java/com/android/internal/telephony/dataconnection/ApnSetting.java +24 −19 Original line number Diff line number Diff line Loading @@ -404,8 +404,7 @@ public class ApnSetting { return false; } public boolean isMetered(Context context, int subId) { public static boolean isMeteredApnType(String type, Context context, int subId) { synchronized (sMeteredApnTypes) { HashSet<String> meteredApnSet = sMeteredApnTypes.get(subId); Loading Loading @@ -435,21 +434,17 @@ public class ApnSetting { 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; Loading @@ -462,8 +457,18 @@ public class ApnSetting { } } } if (DBG) Rlog.d(LOG_TAG, type + " is not metered."); return false; } public boolean isMetered(Context context, int subId) { for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (isMeteredApnType(type, context, subId)) { if (DBG) Rlog.d(LOG_TAG, "Metered. APN = " + toString()); return true; } } if (DBG) Rlog.d(LOG_TAG, "Not metered. APN = " + toString()); return false; } Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +9 −3 Original line number Diff line number Diff line Loading @@ -1463,8 +1463,10 @@ public class DcTracker extends Handler { boolean isEmergencyApn = apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY); final ServiceStateTracker sst = mPhone.getServiceStateTracker(); // set to false if apn type is non-metered. boolean checkUserDataEnabled = !(apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)); !(ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone.getContext(), mPhone.getSubId())); StringBuilder failureReason = new StringBuilder(); if (apnContext.isConnectable() && (isEmergencyApn || Loading Loading @@ -1590,8 +1592,12 @@ public class DcTracker extends Handler { for (ApnContext apnContext : mApnContexts.values()) { if (apnContext.isDisconnected() == false) didDisconnect = true; if (specificdisable) { if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IMS)) { if (DBG) log("ApnConextType: " + apnContext.getApnType()); // Use ApnSetting to decide metered or non-metered. // Tear down all metered data connections. ApnSetting apnSetting = apnContext.getApnSetting(); if (apnSetting != null && apnSetting.isMetered(mPhone.getContext(), mPhone.getSubId())) { if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType()); apnContext.setReason(reason); cleanUpConnection(tearDown, apnContext); } Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java +101 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import android.net.Uri; import android.os.HandlerThread; import android.os.IBinder; import android.os.Message; import android.os.PersistableBundle; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; Loading Loading @@ -58,6 +60,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; Loading Loading @@ -96,6 +99,8 @@ public class DcTrackerTest extends TelephonyTest { private AlarmManager mAlarmManager; private PersistableBundle mBundle; private final ApnSettingContentProvider mApnSettingContentProvider = new ApnSettingContentProvider(); Loading Loading @@ -227,7 +232,7 @@ public class DcTrackerTest extends TelephonyTest { "", // user "", // password 3, // authtype "default,supl", // types "ims", // types "IP", // protocol "IP", // roaming_protocol 1, // carrier_enabled Loading Loading @@ -291,6 +296,7 @@ public class DcTrackerTest extends TelephonyTest { new String[]{"36,2"}); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mBundle = mContextFixture.getCarrierConfigBundle(); new DcTrackerTestHandler(getClass().getSimpleName()).start(); waitUntilReady(); Loading Loading @@ -502,4 +508,97 @@ public class DcTrackerTest extends TelephonyTest { // Verify connected with APN2 setting. verifyDataConnected(FAKE_APN2); } @Test @MediumTest public void testUserDisableData() throws Exception { //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS //set Default and MMS to be metered in the CarrierConfigManager boolean dataEnabled = mDct.getDataEnabled(); mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); mDct.setEnabled(5, true); mDct.setEnabled(0, true); logd("Sending EVENT_RECORDS_LOADED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null)); waitForMs(200); logd("Sending EVENT_DATA_CONNECTION_ATTACHED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null)); waitForMs(200); logd("Sending DATA_ENABLED_CMD"); mDct.setDataEnabled(true); waitForMs(200); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1), eq(""), eq(""), eq(0), eq("IP"), any(Message.class)); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3), eq(""), eq(""), eq(3), eq("IP"), any(Message.class)); logd("Sending DATA_DISABLED_CMD"); mDct.setDataEnabled(false); waitForMs(200); // expected tear down all metered DataConnections verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(), any(Message.class)); assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState()); assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT)); assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS)); // reset the setting at the end of this test mDct.setDataEnabled(dataEnabled); waitForMs(200); } @Test @MediumTest public void testUserDisableRoaming() throws Exception { //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS //set Default and MMS to be metered in the CarrierConfigManager boolean roamingEnabled = mDct.getDataOnRoamingEnabled(); mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS, new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}); mDct.setEnabled(5, true); mDct.setEnabled(0, true); logd("Sending EVENT_RECORDS_LOADED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null)); waitForMs(200); logd("Sending EVENT_DATA_CONNECTION_ATTACHED"); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null)); waitForMs(200); logd("Sending DATA_ENABLED_CMD"); mDct.setDataEnabled(true); waitForMs(200); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1), eq(""), eq(""), eq(0), eq("IP"), any(Message.class)); verify(mSimulatedCommandsVerifier, times(1)).setupDataCall( eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3), eq(""), eq(""), eq(3), eq("IP"), any(Message.class)); logd("Sending DISABLE_ROAMING_CMD"); mDct.setDataOnRoamingEnabled(false); mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_ROAMING_ON)); waitForMs(200); // expected tear down all metered DataConnections verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(), any(Message.class)); assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState()); assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT)); assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS)); // reset roaming settings at end of this test mDct.setDataOnRoamingEnabled(roamingEnabled); waitForMs(200); } }