DataConnectionTest.java revision c0a3ed8c70021d47cd55bbc1406a9cf63bd6afe2
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 static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
20import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
21import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
22import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
23import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
24import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
25
26import static org.junit.Assert.assertEquals;
27import static org.junit.Assert.assertFalse;
28import static org.junit.Assert.assertTrue;
29import static org.mockito.Matchers.any;
30import static org.mockito.Matchers.eq;
31import static org.mockito.Mockito.doReturn;
32import static org.mockito.Mockito.times;
33import static org.mockito.Mockito.verify;
34
35import android.net.LinkProperties;
36import android.net.NetworkCapabilities;
37import android.net.NetworkInfo;
38import android.net.NetworkUtils;
39import android.os.AsyncResult;
40import android.os.Handler;
41import android.os.HandlerThread;
42import android.os.Message;
43import android.telephony.CarrierConfigManager;
44import android.telephony.ServiceState;
45import android.telephony.data.DataCallResponse;
46import android.telephony.data.DataProfile;
47import android.telephony.data.InterfaceAddress;
48import android.test.suitebuilder.annotation.SmallTest;
49
50import com.android.internal.telephony.PhoneConstants;
51import com.android.internal.telephony.RILConstants;
52import com.android.internal.telephony.RetryManager;
53import com.android.internal.telephony.TelephonyTest;
54import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
55import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
56import com.android.internal.telephony.dataconnection.DataConnection.SetupResult;
57import com.android.internal.util.IState;
58import com.android.internal.util.StateMachine;
59
60import org.junit.After;
61import org.junit.Before;
62import org.junit.Test;
63import org.mockito.ArgumentCaptor;
64import org.mockito.Mock;
65
66import java.lang.reflect.Field;
67import java.lang.reflect.Method;
68import java.util.Arrays;
69
70public class DataConnectionTest extends TelephonyTest {
71
72    @Mock
73    DcTesterFailBringUpAll mDcTesterFailBringUpAll;
74    @Mock
75    ConnectionParams mCp;
76    @Mock
77    DisconnectParams mDcp;
78    @Mock
79    ApnContext mApnContext;
80    @Mock
81    DcFailBringUp mDcFailBringUp;
82
83    private DataConnection mDc;
84    private DataConnectionTestHandler mDataConnectionTestHandler;
85    private DcController mDcc;
86
87    private ApnSetting mApn1 = new ApnSetting(
88            2163,                   // id
89            "44010",                // numeric
90            "sp-mode",              // name
91            "spmode.ne.jp",         // apn
92            "",                     // proxy
93            "",                     // port
94            "",                     // mmsc
95            "",                     // mmsproxy
96            "",                     // mmsport
97            "",                     // user
98            "",                     // password
99            -1,                     // authtype
100            new String[]{"default", "supl"},     // types
101            "IP",                   // protocol
102            "IP",                   // roaming_protocol
103            true,                   // carrier_enabled
104            0,                      // bearer
105            0,                      // bearer_bitmask
106            0,                      // profile_id
107            false,                  // modem_cognitive
108            0,                      // max_conns
109            0,                      // wait_time
110            0,                      // max_conns_time
111            0,                      // mtu
112            "",                     // mvno_type
113            "");                    // mnvo_match_data
114
115    private class DataConnectionTestHandler extends HandlerThread {
116
117        private DataConnectionTestHandler(String name) {
118            super(name);
119        }
120
121        @Override
122        public void onLooperPrepared() {
123            Handler h = new Handler();
124
125            mDcc = DcController.makeDcc(mPhone, mDcTracker, h);
126            mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDcTesterFailBringUpAll,
127                    mDcc);
128        }
129    }
130
131    @Before
132    public void setUp() throws Exception {
133        logd("+Setup!");
134        super.setUp(getClass().getSimpleName());
135
136        doReturn("fake.action_detached").when(mPhone).getActionDetached();
137        replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
138        replaceInstance(ConnectionParams.class, "mRilRat", mCp,
139                ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
140        doReturn(mApn1).when(mApnContext).getApnSetting();
141        doReturn(PhoneConstants.APN_TYPE_DEFAULT).when(mApnContext).getApnType();
142
143        mDcFailBringUp.saveParameters(0, 0, -2);
144        doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
145
146        mContextFixture.putStringArrayResource(com.android.internal.R.array.
147                config_mobile_tcp_buffers, new String[]{
148                "umts:131072,262144,1452032,4096,16384,399360",
149                "hspa:131072,262144,2441216,4096,16384,399360",
150                "hsupa:131072,262144,2441216,4096,16384,399360",
151                "hsdpa:131072,262144,2441216,4096,16384,399360",
152                "hspap:131072,262144,2441216,4096,16384,399360",
153                "edge:16384,32768,131072,4096,16384,65536",
154                "gprs:4096,8192,24576,4096,8192,24576",
155                "1xrtt:16384,32768,131070,4096,16384,102400",
156                "evdo:131072,262144,1048576,4096,16384,524288",
157                "lte:524288,1048576,8388608,262144,524288,4194304"});
158
159
160        mDcp.mApnContext = mApnContext;
161
162        mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName());
163        mDataConnectionTestHandler.start();
164
165        waitForMs(200);
166        logd("-Setup!");
167    }
168
169    @After
170    public void tearDown() throws Exception {
171        logd("tearDown");
172        mDc = null;
173        mDcc = null;
174        mDataConnectionTestHandler.quit();
175        super.tearDown();
176    }
177
178    private IState getCurrentState() throws Exception {
179        Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
180        method.setAccessible(true);
181        return (IState) method.invoke(mDc);
182    }
183
184    private long getSuggestedRetryDelay(AsyncResult ar) throws Exception {
185        Class[] cArgs = new Class[1];
186        cArgs[0] = AsyncResult.class;
187        Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs);
188        method.setAccessible(true);
189        return (long) method.invoke(mDc, ar);
190    }
191
192    private SetupResult setLinkProperties(DataCallResponse response,
193                                                         LinkProperties linkProperties)
194            throws Exception {
195        Class[] cArgs = new Class[2];
196        cArgs[0] = DataCallResponse.class;
197        cArgs[1] = LinkProperties.class;
198        Method method = DataConnection.class.getDeclaredMethod("setLinkProperties", cArgs);
199        method.setAccessible(true);
200        return (SetupResult) method.invoke(mDc, response, linkProperties);
201    }
202
203    @Test
204    @SmallTest
205    public void testSanity() throws Exception {
206        assertEquals("DcInactiveState", getCurrentState().getName());
207    }
208
209    @Test
210    @SmallTest
211    public void testConnectEvent() throws Exception {
212        testSanity();
213
214        mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
215        waitForMs(200);
216
217        verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
218                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
219        verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
220                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
221
222        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
223        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
224                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), dpCaptor.capture(),
225                eq(false), eq(false), any(Message.class));
226
227        assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
228
229        assertEquals("DcActiveState", getCurrentState().getName());
230    }
231
232    @Test
233    @SmallTest
234    public void testDisconnectEvent() throws Exception {
235        testConnectEvent();
236
237        mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
238        waitForMs(100);
239
240        verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(eq(1),
241                eq(RILConstants.DEACTIVATE_REASON_NONE), any(Message.class));
242
243        assertEquals("DcInactiveState", getCurrentState().getName());
244    }
245
246    @Test
247    @SmallTest
248    public void testModemSuggestRetry() throws Exception {
249        DataCallResponse response = new DataCallResponse(0, 0, 1, 2, "IP", FAKE_IFNAME,
250                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
251                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
252                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
253                Arrays.asList(FAKE_PCSCF_ADDRESS),
254                1440);
255
256        AsyncResult ar = new AsyncResult(null, response, null);
257        assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
258
259        response = new DataCallResponse(0, 1000, 1, 2, "IP", FAKE_IFNAME,
260                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
261                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
262                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
263                Arrays.asList(FAKE_PCSCF_ADDRESS),
264                1440);
265        ar = new AsyncResult(null, response, null);
266        assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
267
268        response = new DataCallResponse(0, 9999, 1, 2, "IP", FAKE_IFNAME,
269                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
270                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
271                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
272                Arrays.asList(FAKE_PCSCF_ADDRESS),
273                1440);
274        ar = new AsyncResult(null, response, null);
275
276        assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
277    }
278
279    @Test
280    @SmallTest
281    public void testModemNotSuggestRetry() throws Exception {
282        DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME,
283                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
284                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
285                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
286                Arrays.asList(FAKE_PCSCF_ADDRESS),
287                1440);
288        AsyncResult ar = new AsyncResult(null, response, null);
289        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
290
291        response = new DataCallResponse(0, -5, 1, 2, "IP", FAKE_IFNAME,
292                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
293                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
294                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
295                Arrays.asList(FAKE_PCSCF_ADDRESS),
296                1440);
297        ar = new AsyncResult(null, response, null);
298        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
299
300        response = new DataCallResponse(0, Integer.MIN_VALUE, 1, 2, "IP", FAKE_IFNAME,
301                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
302                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
303                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
304                Arrays.asList(FAKE_PCSCF_ADDRESS),
305                1440);
306        ar = new AsyncResult(null, response, null);
307        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
308    }
309
310    @Test
311    @SmallTest
312    public void testModemSuggestNoRetry() throws Exception {
313        DataCallResponse response = new DataCallResponse(0, Integer.MAX_VALUE, 1, 2, "IP",
314                FAKE_IFNAME,
315                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
316                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
317                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
318                Arrays.asList(FAKE_PCSCF_ADDRESS),
319                1440);
320        AsyncResult ar = new AsyncResult(null, response, null);
321        assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(ar));
322    }
323
324    private NetworkInfo getNetworkInfo() throws Exception {
325        Field f = DataConnection.class.getDeclaredField("mNetworkInfo");
326        f.setAccessible(true);
327        return (NetworkInfo) f.get(mDc);
328    }
329
330    private NetworkCapabilities getNetworkCapabilities() throws Exception {
331        Method method = DataConnection.class.getDeclaredMethod("getNetworkCapabilities");
332        method.setAccessible(true);
333        return (NetworkCapabilities) method.invoke(mDc);
334    }
335
336    @Test
337    @SmallTest
338    public void testMeteredCapability() throws Exception {
339
340        mContextFixture.getCarrierConfigBundle().
341                putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
342                new String[] {"default"});
343
344        testConnectEvent();
345
346        assertFalse(getNetworkCapabilities()
347                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
348    }
349
350    @Test
351    @SmallTest
352    public void testNonMeteredCapability() throws Exception {
353
354        doReturn(2819).when(mPhone).getSubId();
355        mContextFixture.getCarrierConfigBundle().
356                putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
357                        new String[] {"mms"});
358
359        testConnectEvent();
360
361        assertTrue(getNetworkCapabilities()
362                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
363    }
364
365    @SmallTest
366    public void testIsIpAddress() throws Exception {
367        // IPv4
368        assertTrue(DataConnection.isIpAddress("1.2.3.4"));
369        assertTrue(DataConnection.isIpAddress("127.0.0.1"));
370
371        // IPv6
372        assertTrue(DataConnection.isIpAddress("::1"));
373        assertTrue(DataConnection.isIpAddress("2001:4860:800d::68"));
374    }
375
376    @Test
377    @SmallTest
378    public void testSetLinkProperties() throws Exception {
379
380        DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME,
381                Arrays.asList(new InterfaceAddress(FAKE_ADDRESS, 0)),
382                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
383                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
384                Arrays.asList(FAKE_PCSCF_ADDRESS),
385                1440);
386
387        LinkProperties linkProperties = new LinkProperties();
388        assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
389        logd(linkProperties.toString());
390        assertEquals(response.getIfname(), linkProperties.getInterfaceName());
391        assertEquals(response.getAddresses().size(), linkProperties.getAddresses().size());
392        for (int i = 0; i < response.getAddresses().size(); ++i) {
393            assertEquals(response.getAddresses().get(i).getAddress(),
394                    NetworkUtils.numericToInetAddress(linkProperties.getLinkAddresses().get(i)
395                            .getAddress().getHostAddress()));
396        }
397
398        assertEquals(response.getDnses().size(), linkProperties.getDnsServers().size());
399        for (int i = 0; i < response.getDnses().size(); ++i) {
400            assertEquals("i = " + i, response.getDnses().get(i), NetworkUtils.numericToInetAddress(
401                    linkProperties.getDnsServers().get(i).getHostAddress()));
402        }
403
404        assertEquals(response.getGateways().size(), linkProperties.getRoutes().size());
405        for (int i = 0; i < response.getGateways().size(); ++i) {
406            assertEquals("i = " + i, response.getGateways().get(i),
407                    NetworkUtils.numericToInetAddress(linkProperties.getRoutes().get(i)
408                            .getGateway().getHostAddress()));
409        }
410
411        assertEquals(response.getMtu(), linkProperties.getMtu());
412    }
413
414    @Test
415    @SmallTest
416    public void testSetLinkPropertiesInvalidAddress() throws Exception {
417
418        // 224.224.224.224 is an invalid address.
419        DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME,
420                Arrays.asList(new InterfaceAddress("224.224.224.224", 0)),
421                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
422                Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
423                Arrays.asList(FAKE_PCSCF_ADDRESS),
424                1440);
425
426        LinkProperties linkProperties = new LinkProperties();
427        assertEquals(SetupResult.ERR_UnacceptableParameter,
428                setLinkProperties(response, linkProperties));
429    }
430}
431