DcTrackerTest.java revision 3374f09335e5b7681af05a35dd7454b565f8bb72
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.dataconnection;
18
19import android.app.AlarmManager;
20import android.app.PendingIntent;
21import android.content.ContentResolver;
22import android.content.Context;
23import android.content.Intent;
24import android.database.Cursor;
25import android.database.MatrixCursor;
26import android.net.LinkProperties;
27import android.net.NetworkCapabilities;
28import android.net.NetworkRequest;
29import android.net.Uri;
30import android.os.HandlerThread;
31import android.os.IBinder;
32import android.os.Message;
33import android.os.PersistableBundle;
34import android.platform.test.annotations.Postsubmit;
35import android.provider.Settings;
36import android.provider.Telephony;
37import android.telephony.CarrierConfigManager;
38import android.telephony.ServiceState;
39import android.telephony.SubscriptionInfo;
40import android.telephony.SubscriptionManager;
41import android.test.mock.MockContentProvider;
42import android.test.mock.MockContentResolver;
43import android.test.suitebuilder.annotation.MediumTest;
44import android.util.LocalLog;
45
46import com.android.internal.telephony.DctConstants;
47import com.android.internal.telephony.ISub;
48import com.android.internal.telephony.Phone;
49import com.android.internal.telephony.PhoneConstants;
50import com.android.internal.telephony.TelephonyTest;
51import com.android.internal.telephony.TestApplication;
52import com.android.internal.telephony.dataconnection.DcTracker.DataAllowFailReason;
53
54import org.junit.After;
55import org.junit.Before;
56import org.junit.Test;
57import org.mockito.ArgumentCaptor;
58import org.mockito.Mock;
59import org.mockito.invocation.InvocationOnMock;
60import org.mockito.stubbing.Answer;
61
62import java.lang.reflect.Method;
63import java.util.Arrays;
64import java.util.List;
65import java.util.regex.Matcher;
66import java.util.regex.Pattern;
67
68import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
69import static org.junit.Assert.assertArrayEquals;
70import static org.junit.Assert.assertEquals;
71import static org.junit.Assert.assertFalse;
72import static org.junit.Assert.assertTrue;
73import static org.junit.Assert.fail;
74import static org.mockito.Matchers.any;
75import static org.mockito.Matchers.anyInt;
76import static org.mockito.Matchers.anyLong;
77import static org.mockito.Matchers.anyString;
78import static org.mockito.Matchers.eq;
79import static org.mockito.Mockito.doReturn;
80import static org.mockito.Mockito.doAnswer;
81import static org.mockito.Mockito.never;
82import static org.mockito.Mockito.times;
83import static org.mockito.Mockito.verify;
84
85public class DcTrackerTest extends TelephonyTest {
86
87    private final static String[] sNetworkAttributes = new String[]{
88            "mobile,0,0,0,-1,true", "mobile_mms,2,0,2,60000,true",
89            "mobile_supl,3,0,2,60000,true", "mobile_dun,4,0,2,60000,true",
90            "mobile_hipri,5,0,3,60000,true", "mobile_fota,10,0,2,60000,true",
91            "mobile_ims,11,0,2,60000,true", "mobile_cbs,12,0,2,60000,true",
92            "mobile_ia,14,0,2,-1,true", "mobile_emergency,15,0,2,-1,true"};
93
94    private final static List<String> sApnTypes = Arrays.asList(
95            "default", "mms", "cbs", "fota", "supl", "ia", "emergency", "dun", "hipri", "ims");
96
97    private static final String FAKE_APN1 = "FAKE APN 1";
98    private static final String FAKE_APN2 = "FAKE APN 2";
99    private static final String FAKE_APN3 = "FAKE APN 3";
100    private static final String FAKE_IFNAME = "FAKE IFNAME";
101    private static final String FAKE_PCSCF_ADDRESS = "22.33.44.55";
102    private static final String FAKE_GATEWAY = "11.22.33.44";
103    private static final String FAKE_DNS = "55.66.77.88";
104    private static final String FAKE_ADDRESS = "99.88.77.66";
105
106    @Mock
107    ISub mIsub;
108    @Mock
109    IBinder mBinder;
110    @Mock
111    NetworkRequest mNetworkRequest;
112    @Mock
113    SubscriptionInfo mSubscriptionInfo;
114
115    private DcTracker mDct;
116    private DcTrackerTestHandler mDcTrackerTestHandler;
117
118    private AlarmManager mAlarmManager;
119
120    private PersistableBundle mBundle;
121
122    private SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
123
124    private final ApnSettingContentProvider mApnSettingContentProvider =
125            new ApnSettingContentProvider();
126
127    private class DcTrackerTestHandler extends HandlerThread {
128
129        private DcTrackerTestHandler(String name) {
130            super(name);
131        }
132
133        @Override
134        public void onLooperPrepared() {
135            mDct = new DcTracker(mPhone);
136            setReady(true);
137        }
138    }
139
140    private class ApnSettingContentProvider extends MockContentProvider {
141
142        @Override
143        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
144                            String sortOrder) {
145            logd("ApnSettingContentProvider: query");
146            logd("   uri = " + uri);
147            logd("   projection = " + Arrays.toString(projection));
148            logd("   selection = " + selection);
149            logd("   selectionArgs = " + Arrays.toString(selectionArgs));
150            logd("   sortOrder = " + sortOrder);
151
152            if (uri.compareTo(Telephony.Carriers.CONTENT_URI) == 0) {
153                if (projection == null && selectionArgs == null && selection != null) {
154
155                    Pattern pattern = Pattern.compile("^numeric = '([0-9]*)'");
156                    Matcher matcher = pattern.matcher(selection);
157                    if (!matcher.find()) {
158                        logd("Cannot find MCC/MNC from " + selection);
159                        return null;
160                    }
161
162                    String plmn = matcher.group(1);
163
164                    logd("Query '" + plmn + "' APN settings");
165                    MatrixCursor mc = new MatrixCursor(
166                            new String[]{Telephony.Carriers._ID, Telephony.Carriers.NUMERIC,
167                                    Telephony.Carriers.NAME, Telephony.Carriers.APN,
168                                    Telephony.Carriers.PROXY, Telephony.Carriers.PORT,
169                                    Telephony.Carriers.MMSC, Telephony.Carriers.MMSPROXY,
170                                    Telephony.Carriers.MMSPORT, Telephony.Carriers.USER,
171                                    Telephony.Carriers.PASSWORD, Telephony.Carriers.AUTH_TYPE,
172                                    Telephony.Carriers.TYPE,
173                                    Telephony.Carriers.PROTOCOL,
174                                    Telephony.Carriers.ROAMING_PROTOCOL,
175                                    Telephony.Carriers.CARRIER_ENABLED, Telephony.Carriers.BEARER,
176                                    Telephony.Carriers.BEARER_BITMASK,
177                                    Telephony.Carriers.PROFILE_ID,
178                                    Telephony.Carriers.MODEM_COGNITIVE,
179                                    Telephony.Carriers.MAX_CONNS, Telephony.Carriers.WAIT_TIME,
180                                    Telephony.Carriers.MAX_CONNS_TIME, Telephony.Carriers.MTU,
181                                    Telephony.Carriers.MVNO_TYPE,
182                                    Telephony.Carriers.MVNO_MATCH_DATA});
183
184                    mc.addRow(new Object[]{
185                            2163,                   // id
186                            plmn,                   // numeric
187                            "sp-mode",              // name
188                            FAKE_APN1,              // apn
189                            "",                     // proxy
190                            "",                     // port
191                            "",                     // mmsc
192                            "",                     // mmsproxy
193                            "",                     // mmsport
194                            "",                     // user
195                            "",                     // password
196                            -1,                     // authtype
197                            "default,supl",         // types
198                            "IP",                   // protocol
199                            "IP",                   // roaming_protocol
200                            1,                      // carrier_enabled
201                            0,                      // bearer
202                            0,                      // bearer_bitmask
203                            0,                      // profile_id
204                            0,                      // modem_cognitive
205                            0,                      // max_conns
206                            0,                      // wait_time
207                            0,                      // max_conns_time
208                            0,                      // mtu
209                            "",                     // mvno_type
210                            ""                      // mnvo_match_data
211                    });
212
213                    mc.addRow(new Object[]{
214                            2164,                   // id
215                            plmn,                   // numeric
216                            "mopera U",             // name
217                            FAKE_APN2,              // apn
218                            "",                     // proxy
219                            "",                     // port
220                            "",                     // mmsc
221                            "",                     // mmsproxy
222                            "",                     // mmsport
223                            "",                     // user
224                            "",                     // password
225                            -1,                     // authtype
226                            "default,supl",         // types
227                            "IP",                   // protocol
228                            "IP",                   // roaming_protocol
229                            1,                      // carrier_enabled
230                            0,                      // bearer
231                            0,                      // bearer_bitmask
232                            0,                      // profile_id
233                            0,                      // modem_cognitive
234                            0,                      // max_conns
235                            0,                      // wait_time
236                            0,                      // max_conns_time
237                            0,                      // mtu
238                            "",                     // mvno_type
239                            ""                      // mnvo_match_data
240                    });
241
242                    mc.addRow(new Object[]{
243                            2165,                   // id
244                            plmn,                   // numeric
245                            "b-mobile for Nexus",   // name
246                            FAKE_APN3,              // apn
247                            "",                     // proxy
248                            "",                     // port
249                            "",                     // mmsc
250                            "",                     // mmsproxy
251                            "",                     // mmsport
252                            "",                     // user
253                            "",                     // password
254                            3,                      // authtype
255                            "ims",                  // types
256                            "IP",                   // protocol
257                            "IP",                   // roaming_protocol
258                            1,                      // carrier_enabled
259                            0,                      // bearer
260                            0,                      // bearer_bitmask
261                            0,                      // profile_id
262                            0,                      // modem_cognitive
263                            0,                      // max_conns
264                            0,                      // wait_time
265                            0,                      // max_conns_time
266                            0,                      // mtu
267                            "",                     // mvno_type
268                            ""                      // mnvo_match_data
269                    });
270
271                    return mc;
272                }
273            }
274
275            return null;
276        }
277    }
278
279    @Before
280    public void setUp() throws Exception {
281        // set the lazy cp to the real content provider in order to use the real settings
282        ContentResolver realContentResolver = TestApplication.getAppContext().getContentResolver();
283        Settings.Global.getInt(realContentResolver, Settings.Global.MOBILE_DATA, 1);
284
285        logd("DcTrackerTest +Setup!");
286        super.setUp(getClass().getSimpleName());
287
288        doReturn("fake.action_detached").when(mPhone).getActionDetached();
289        doReturn("fake.action_attached").when(mPhone).getActionAttached();
290        doReturn("44010").when(mSimRecords).getOperatorNumeric();
291
292        mContextFixture.putStringArrayResource(com.android.internal.R.array.networkAttributes,
293                sNetworkAttributes);
294        mContextFixture.putStringArrayResource(com.android.internal.R.array.
295                config_mobile_tcp_buffers, new String[]{
296                "umts:131072,262144,1452032,4096,16384,399360",
297                "hspa:131072,262144,2441216,4096,16384,399360",
298                "hsupa:131072,262144,2441216,4096,16384,399360",
299                "hsdpa:131072,262144,2441216,4096,16384,399360",
300                "hspap:131072,262144,2441216,4096,16384,399360",
301                "edge:16384,32768,131072,4096,16384,65536",
302                "gprs:4096,8192,24576,4096,8192,24576",
303                "1xrtt:16384,32768,131070,4096,16384,102400",
304                "evdo:131072,262144,1048576,4096,16384,524288",
305                "lte:524288,1048576,8388608,262144,524288,4194304"});
306
307        ((MockContentResolver) mContext.getContentResolver()).addProvider(
308                Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
309
310        doReturn(true).when(mSimRecords).getRecordsLoaded();
311        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
312        doReturn(true).when(mSST).getDesiredPowerState();
313        doReturn(true).when(mSST).getPowerStateFromCarrier();
314        doAnswer(
315                new Answer<Void>() {
316                    @Override
317                    public Void answer(InvocationOnMock invocation) throws Throwable {
318                        mOnSubscriptionsChangedListener =
319                                (SubscriptionManager.OnSubscriptionsChangedListener)
320                                        invocation.getArguments()[0];
321                        return null;
322                    }
323                }
324        ).when(mSubscriptionManager).addOnSubscriptionsChangedListener(any());
325        doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
326
327        doReturn(1).when(mIsub).getDefaultDataSubId();
328        doReturn(mIsub).when(mBinder).queryLocalInterface(anyString());
329        mServiceManagerMockedServices.put("isub", mBinder);
330
331        mContextFixture.putStringArrayResource(
332                com.android.internal.R.array.config_cell_retries_per_error_code,
333                new String[]{"36,2"});
334
335        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
336        mBundle = mContextFixture.getCarrierConfigBundle();
337
338        mDcTrackerTestHandler = new DcTrackerTestHandler(getClass().getSimpleName());
339        mDcTrackerTestHandler.start();
340        waitUntilReady();
341        waitForMs(600);
342        logd("DcTrackerTest -Setup!");
343    }
344
345    @After
346    public void tearDown() throws Exception {
347        logd("DcTrackerTest -tearDown");
348        mDct.removeCallbacksAndMessages(null);
349        mDct = null;
350        mDcTrackerTestHandler.quitSafely();
351        super.tearDown();
352    }
353
354    // Create a successful data response
355    public static DataCallResponse createDataCallResponse() {
356
357        DataCallResponse dcResponse = new DataCallResponse();
358
359        dcResponse.version = 11;
360        dcResponse.status = 0;
361        dcResponse.suggestedRetryTime = -1; // No retry suggested by the modem
362        dcResponse.cid = 1;
363        dcResponse.active = 2;
364        dcResponse.type = "IP";
365        dcResponse.ifname = FAKE_IFNAME;
366        dcResponse.mtu = 1440;
367        dcResponse.addresses = new String[]{FAKE_ADDRESS};
368        dcResponse.dnses = new String[]{FAKE_DNS};
369        dcResponse.gateways = new String[]{FAKE_GATEWAY};
370        dcResponse.pcscf = new String[]{FAKE_PCSCF_ADDRESS};
371        return dcResponse;
372    }
373
374    private void verifyDataConnected(final String apnSetting) {
375        verify(mPhone, times(1)).notifyDataConnection(eq(Phone.REASON_CONNECTED),
376                eq(PhoneConstants.APN_TYPE_DEFAULT));
377
378        verify(mAlarmManager, times(1)).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(),
379                any(PendingIntent.class));
380
381        assertEquals(apnSetting, mDct.getActiveApnString(PhoneConstants.APN_TYPE_DEFAULT));
382        assertArrayEquals(new String[]{PhoneConstants.APN_TYPE_DEFAULT}, mDct.getActiveApnTypes());
383        assertTrue(mDct.getAnyDataEnabled());
384
385        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
386        assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
387
388        LinkProperties linkProperties = mDct.getLinkProperties(PhoneConstants.APN_TYPE_DEFAULT);
389        assertEquals(FAKE_IFNAME, linkProperties.getInterfaceName());
390        assertEquals(1, linkProperties.getAddresses().size());
391        assertEquals(FAKE_ADDRESS, linkProperties.getAddresses().get(0).getHostAddress());
392        assertEquals(1, linkProperties.getDnsServers().size());
393        assertEquals(FAKE_DNS, linkProperties.getDnsServers().get(0).getHostAddress());
394        assertEquals(FAKE_GATEWAY, linkProperties.getRoutes().get(0).getGateway().getHostAddress());
395    }
396
397    private boolean isDataAllowed(DataAllowFailReason dataAllowFailReasons) {
398        try {
399            Method method = DcTracker.class.getDeclaredMethod("isDataAllowed",
400                    DataAllowFailReason.class);
401            method.setAccessible(true);
402            return (boolean) method.invoke(mDct, dataAllowFailReasons);
403        } catch (Exception e) {
404            fail(e.toString());
405            return false;
406        }
407    }
408
409    // Test the normal data call setup scenario.
410    @Test
411    @MediumTest
412    public void testDataSetup() {
413
414        mDct.setDataEnabled(true);
415
416        mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
417
418        DataAllowFailReason failureReason = new DataAllowFailReason();
419        boolean allowed = isDataAllowed(failureReason);
420        assertFalse(failureReason.getDataAllowFailReason(), allowed);
421
422        logd("Sending EVENT_RECORDS_LOADED");
423        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
424        waitForMs(200);
425
426        ArgumentCaptor<String> apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
427        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
428                eq(Phone.REASON_SIM_LOADED), apnTypeArgumentCaptor.capture(),
429                eq(PhoneConstants.DataState.DISCONNECTED));
430
431        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
432
433        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
434        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
435        waitForMs(200);
436
437        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
438        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
439                eq(Phone.REASON_DATA_ATTACHED), apnTypeArgumentCaptor.capture(),
440                eq(PhoneConstants.DataState.DISCONNECTED));
441
442        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
443
444        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
445        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
446                eq(Phone.REASON_DATA_ENABLED), apnTypeArgumentCaptor.capture(),
447                eq(PhoneConstants.DataState.DISCONNECTED));
448
449        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
450
451        logd("Sending EVENT_ENABLE_NEW_APN");
452        // APN id 0 is APN_TYPE_DEFAULT
453        mDct.setEnabled(0, true);
454        waitForMs(200);
455
456        failureReason.clearAllReasons();
457        allowed = isDataAllowed(failureReason);
458        assertTrue(failureReason.getDataAllowFailReason(), allowed);
459
460        // Verify if RIL command was sent properly.
461        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
462                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
463                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
464
465        verifyDataConnected(FAKE_APN1);
466    }
467
468    // Test the scenario where the first data call setup is failed, and then retry the setup later.
469    @Test
470    @MediumTest
471    public void testDataRetry() {
472
473        mDct.setDataEnabled(true);
474
475        DataCallResponse dcResponse = createDataCallResponse();
476        // LOST_CONNECTION(0x10004) is a non-permanent failure, so we'll retry data setup later.
477        dcResponse.status = 0x10004;
478        // Simulate RIL fails the data call setup
479        mSimulatedCommands.setDataCallResponse(false, dcResponse);
480
481        DataAllowFailReason failureReason = new DataAllowFailReason();
482        boolean allowed = isDataAllowed(failureReason);
483        assertFalse(failureReason.getDataAllowFailReason(), allowed);
484
485        logd("Sending EVENT_RECORDS_LOADED");
486        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
487        waitForMs(200);
488
489        ArgumentCaptor<String> apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
490        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
491                eq(Phone.REASON_SIM_LOADED), apnTypeArgumentCaptor.capture(),
492                eq(PhoneConstants.DataState.DISCONNECTED));
493
494        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
495
496        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
497        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
498        waitForMs(200);
499
500        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
501        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
502                eq(Phone.REASON_DATA_ATTACHED), apnTypeArgumentCaptor.capture(),
503                eq(PhoneConstants.DataState.DISCONNECTED));
504
505        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
506
507        apnTypeArgumentCaptor = ArgumentCaptor.forClass(String.class);
508        verify(mPhone, times(sNetworkAttributes.length)).notifyDataConnection(
509                eq(Phone.REASON_DATA_ENABLED), apnTypeArgumentCaptor.capture(),
510                eq(PhoneConstants.DataState.DISCONNECTED));
511
512        assertEquals(sApnTypes, apnTypeArgumentCaptor.getAllValues());
513
514        logd("Sending EVENT_ENABLE_NEW_APN");
515        // APN id 0 is APN_TYPE_DEFAULT
516        mDct.setEnabled(0, true);
517        waitForMs(200);
518
519
520        failureReason.clearAllReasons();
521        allowed = isDataAllowed(failureReason);
522        assertTrue(failureReason.getDataAllowFailReason(), allowed);
523
524        // Verify if RIL command was sent properly.
525        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
526                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
527                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
528
529        // Make sure we never notify connected because the data call setup is supposed to fail.
530        verify(mPhone, never()).notifyDataConnection(eq(Phone.REASON_CONNECTED),
531                eq(PhoneConstants.APN_TYPE_DEFAULT));
532
533        // Verify the retry manger schedule another data call setup.
534        verify(mAlarmManager, times(1)).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
535                anyLong(), any(PendingIntent.class));
536
537        // This time we'll let RIL command succeed.
538        mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
539
540        // Simulate the timer expires.
541        Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
542        intent.putExtra("reconnect_alarm_extra_type", PhoneConstants.APN_TYPE_DEFAULT);
543        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, 0);
544        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
545        mContext.sendBroadcast(intent);
546        waitForMs(200);
547
548        // Verify if RIL command was sent properly.
549        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
550                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN2),
551                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
552
553        // Verify connected with APN2 setting.
554        verifyDataConnected(FAKE_APN2);
555    }
556
557    @Test
558    @MediumTest
559    public void testUserDisableData() throws Exception {
560        //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS
561        //set Default and MMS to be metered in the CarrierConfigManager
562        boolean dataEnabled = mDct.getDataEnabled();
563        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
564                new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
565        mDct.setEnabled(5, true);
566        mDct.setEnabled(0, true);
567
568        logd("Sending EVENT_RECORDS_LOADED");
569        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
570        waitForMs(200);
571
572        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
573        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
574        waitForMs(200);
575
576        logd("Sending DATA_ENABLED_CMD");
577        mDct.setDataEnabled(true);
578
579        waitForMs(200);
580        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
581                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
582                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
583        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
584                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3),
585                eq(""), eq(""), eq(3), eq("IP"), any(Message.class));
586
587        logd("Sending DATA_DISABLED_CMD");
588        mDct.setDataEnabled(false);
589        waitForMs(200);
590
591        // expected tear down all metered DataConnections
592        verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(),
593                any(Message.class));
594        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
595        assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
596        assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS));
597
598        // reset the setting at the end of this test
599        mDct.setDataEnabled(dataEnabled);
600        waitForMs(200);
601    }
602
603    @Test
604    @MediumTest
605    public void testUserDisableRoaming() throws Exception {
606        //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS
607        //step 2: set roaming disabled, data is enabled
608        //step 3: under roaming service
609        //step 4: only tear down metered data connections.
610
611        //set Default and MMS to be metered in the CarrierConfigManager
612        boolean roamingEnabled = mDct.getDataOnRoamingEnabled();
613        boolean dataEnabled = mDct.getDataEnabled();
614
615        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
616                new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
617        mDct.setEnabled(5, true);
618        mDct.setEnabled(0, true);
619
620        logd("Sending EVENT_RECORDS_LOADED");
621        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
622        waitForMs(200);
623
624        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
625        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
626        waitForMs(200);
627
628        logd("Sending DATA_ENABLED_CMD");
629        mDct.setDataEnabled(true);
630
631        waitForMs(200);
632        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
633                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
634                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
635        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
636                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3),
637                eq(""), eq(""), eq(3), eq("IP"), any(Message.class));
638
639        //user is in roaming
640        doReturn(true).when(mServiceState).getDataRoaming();
641        logd("Sending DISABLE_ROAMING_CMD");
642        mDct.setDataOnRoamingEnabled(false);
643        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_ROAMING_ON));
644        waitForMs(200);
645
646        // expected tear down all metered DataConnections
647        verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(),
648                any(Message.class));
649        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
650        assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
651        assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS));
652
653        // reset roaming settings / data enabled settings at end of this test
654        mDct.setDataOnRoamingEnabled(roamingEnabled);
655        mDct.setDataEnabled(dataEnabled);
656        waitForMs(200);
657    }
658
659    @Postsubmit
660    @Test
661    @MediumTest
662    public void testDataCallOnUserDisableRoaming() throws Exception {
663        //step 1: mock under roaming service and user disabled roaming from settings.
664        //step 2: user toggled data settings on
665        //step 3: only non-metered data call is established
666
667        boolean roamingEnabled = mDct.getDataOnRoamingEnabled();
668        boolean dataEnabled = mDct.getDataEnabled();
669
670        //set Default and MMS to be metered in the CarrierConfigManager
671        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
672                new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
673        mDct.setEnabled(5, true);
674        mDct.setEnabled(0, true);
675        doReturn(true).when(mServiceState).getDataRoaming();
676
677        logd("Sending DISABLE_ROAMING_CMD");
678        mDct.setDataOnRoamingEnabled(false);
679
680        logd("Sending EVENT_RECORDS_LOADED");
681        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
682        waitForMs(200);
683
684        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
685        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
686        waitForMs(200);
687
688        logd("Sending DATA_ENABLED_CMD");
689        mDct.setDataEnabled(true);
690
691        waitForMs(200);
692        verify(mSimulatedCommandsVerifier, times(0)).setupDataCall(
693                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
694                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
695        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
696                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3),
697                eq(""), eq(""), eq(3), eq("IP"), any(Message.class));
698
699        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
700        assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
701        assertEquals(DctConstants.State.CONNECTED, mDct.getState(PhoneConstants.APN_TYPE_IMS));
702
703        // reset roaming settings / data enabled settings at end of this test
704        mDct.setDataOnRoamingEnabled(roamingEnabled);
705        mDct.setDataEnabled(dataEnabled);
706        waitForMs(200);
707    }
708
709    // Test the default data switch scenario.
710    @Test
711    @MediumTest
712    public void testDDSResetAutoAttach() throws Exception {
713
714        mDct.setDataEnabled(true);
715
716        mContextFixture.putBooleanResource(
717                com.android.internal.R.bool.config_auto_attach_data_on_creation, true);
718
719        mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
720
721        DataAllowFailReason failureReason = new DataAllowFailReason();
722        boolean allowed = isDataAllowed(failureReason);
723        assertFalse(failureReason.getDataAllowFailReason(), allowed);
724
725        ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
726        verify(mUiccController, times(1)).registerForIccChanged(eq(mDct),
727                intArgumentCaptor.capture(), eq(null));
728        // Ideally this should send EVENT_ICC_CHANGED.
729        mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
730        waitForMs(100);
731
732        verify(mSimRecords, times(1)).registerForRecordsLoaded(eq(mDct),
733                intArgumentCaptor.capture(), eq(null));
734        // Ideally this should send EVENT_RECORDS_LOADED.
735        mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
736        waitForMs(100);
737
738        verify(mSST, times(1)).registerForDataConnectionAttached(eq(mDct),
739                intArgumentCaptor.capture(), eq(null));
740        // Ideally this should send EVENT_DATA_CONNECTION_ATTACHED");
741        mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
742        waitForMs(200);
743
744        NetworkRequest nr = new NetworkRequest.Builder()
745                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
746        LocalLog l = new LocalLog(100);
747        mDct.requestNetwork(nr, l);
748        waitForMs(200);
749
750        verifyDataConnected(FAKE_APN1);
751
752        assertTrue(mDct.getAutoAttachOnCreation());
753        mDct.update();
754        // The auto attach flag should be reset after update
755        assertFalse(mDct.getAutoAttachOnCreation());
756
757        verify(mSST, times(1)).registerForDataConnectionDetached(eq(mDct),
758                intArgumentCaptor.capture(), eq(null));
759        // Ideally this should send EVENT_DATA_CONNECTION_DETACHED
760        mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
761        waitForMs(200);
762
763        // Data should not be allowed since auto attach flag has been reset.
764        failureReason.clearAllReasons();
765        allowed = isDataAllowed(failureReason);
766        assertFalse(failureReason.getDataAllowFailReason(), allowed);
767    }
768
769    // Test for API carrierActionSetMeteredApnsEnabled.
770    @Postsubmit
771    @Test
772    @MediumTest
773    public void testCarrierActionSetMeteredApnsEnabled() throws Exception {
774        //step 1: setup two DataCalls one for Internet and IMS
775        //step 2: set data is enabled
776        //step 3: cold sim is detected
777        //step 4: all data connection is torn down
778        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
779                new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
780
781        boolean dataEnabled = mDct.getDataEnabled();
782        mDct.setDataEnabled(true);
783
784        mDct.setEnabled(5, true);
785        mDct.setEnabled(0, true);
786
787        logd("Sending EVENT_RECORDS_LOADED");
788        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
789        waitForMs(200);
790
791        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
792        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
793        waitForMs(200);
794
795        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
796                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(2), eq(FAKE_APN3),
797                eq(""), eq(""), eq(3), eq("IP"), any(Message.class));
798        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
799                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), eq(0), eq(FAKE_APN1),
800                eq(""), eq(""), eq(0), eq("IP"), any(Message.class));
801        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
802
803        mDct.setApnsEnabledByCarrier(false);
804        waitForMs(100);
805
806        // Validate all metered data connections have been torn down
807        verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(anyInt(), anyInt(),
808                any(Message.class));
809        assertEquals(DctConstants.State.CONNECTED, mDct.getOverallState());
810        assertEquals(DctConstants.State.IDLE, mDct.getState(PhoneConstants.APN_TYPE_DEFAULT));
811
812        // Reset settings at the end of test
813        mDct.setDataEnabled(dataEnabled);
814        waitForMs(200);
815    }
816}
817