DataConnectionTest.java revision 3a953e80c4f83c153fcebc71a9814b77f320bc19
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.NetworkCapabilities;
36import android.net.NetworkInfo;
37import android.os.AsyncResult;
38import android.os.Handler;
39import android.os.HandlerThread;
40import android.os.Message;
41import android.telephony.CarrierConfigManager;
42import android.telephony.ServiceState;
43import android.telephony.data.DataProfile;
44import android.test.suitebuilder.annotation.SmallTest;
45
46import com.android.internal.telephony.PhoneConstants;
47import com.android.internal.telephony.RILConstants;
48import com.android.internal.telephony.RetryManager;
49import com.android.internal.telephony.TelephonyTest;
50import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
51import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
52import com.android.internal.util.IState;
53import com.android.internal.util.StateMachine;
54
55import org.junit.After;
56import org.junit.Before;
57import org.junit.Test;
58import org.mockito.ArgumentCaptor;
59import org.mockito.Mock;
60
61import java.lang.reflect.Field;
62import java.lang.reflect.Method;
63
64public class DataConnectionTest extends TelephonyTest {
65
66    @Mock
67    DcTesterFailBringUpAll mDcTesterFailBringUpAll;
68    @Mock
69    ConnectionParams mCp;
70    @Mock
71    DisconnectParams mDcp;
72    @Mock
73    ApnContext mApnContext;
74    @Mock
75    DcFailBringUp mDcFailBringUp;
76
77    private DataConnection mDc;
78    private DataConnectionTestHandler mDataConnectionTestHandler;
79    private DcController mDcc;
80
81    private ApnSetting mApn1 = new ApnSetting(
82            2163,                   // id
83            "44010",                // numeric
84            "sp-mode",              // name
85            "spmode.ne.jp",         // apn
86            "",                     // proxy
87            "",                     // port
88            "",                     // mmsc
89            "",                     // mmsproxy
90            "",                     // mmsport
91            "",                     // user
92            "",                     // password
93            -1,                     // authtype
94            new String[]{"default", "supl"},     // types
95            "IP",                   // protocol
96            "IP",                   // roaming_protocol
97            true,                   // carrier_enabled
98            0,                      // bearer
99            0,                      // bearer_bitmask
100            0,                      // profile_id
101            false,                  // modem_cognitive
102            0,                      // max_conns
103            0,                      // wait_time
104            0,                      // max_conns_time
105            0,                      // mtu
106            "",                     // mvno_type
107            "");                    // mnvo_match_data
108
109    private class DataConnectionTestHandler extends HandlerThread {
110
111        private DataConnectionTestHandler(String name) {
112            super(name);
113        }
114
115        @Override
116        public void onLooperPrepared() {
117            Handler h = new Handler();
118
119            mDcc = DcController.makeDcc(mPhone, mDcTracker, h);
120            mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDcTesterFailBringUpAll,
121                    mDcc);
122        }
123    }
124
125    @Before
126    public void setUp() throws Exception {
127        logd("+Setup!");
128        super.setUp(getClass().getSimpleName());
129
130        doReturn("fake.action_detached").when(mPhone).getActionDetached();
131        replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
132        replaceInstance(ConnectionParams.class, "mRilRat", mCp,
133                ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
134        doReturn(mApn1).when(mApnContext).getApnSetting();
135        doReturn(PhoneConstants.APN_TYPE_DEFAULT).when(mApnContext).getApnType();
136
137        mDcFailBringUp.saveParameters(0, 0, -2);
138        doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
139
140        mContextFixture.putStringArrayResource(com.android.internal.R.array.
141                config_mobile_tcp_buffers, new String[]{
142                "umts:131072,262144,1452032,4096,16384,399360",
143                "hspa:131072,262144,2441216,4096,16384,399360",
144                "hsupa:131072,262144,2441216,4096,16384,399360",
145                "hsdpa:131072,262144,2441216,4096,16384,399360",
146                "hspap:131072,262144,2441216,4096,16384,399360",
147                "edge:16384,32768,131072,4096,16384,65536",
148                "gprs:4096,8192,24576,4096,8192,24576",
149                "1xrtt:16384,32768,131070,4096,16384,102400",
150                "evdo:131072,262144,1048576,4096,16384,524288",
151                "lte:524288,1048576,8388608,262144,524288,4194304"});
152
153
154        mDcp.mApnContext = mApnContext;
155
156        mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName());
157        mDataConnectionTestHandler.start();
158
159        waitForMs(200);
160        logd("-Setup!");
161    }
162
163    @After
164    public void tearDown() throws Exception {
165        logd("tearDown");
166        mDc = null;
167        mDcc = null;
168        mDataConnectionTestHandler.quit();
169        super.tearDown();
170    }
171
172    private IState getCurrentState() throws Exception {
173        Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
174        method.setAccessible(true);
175        return (IState) method.invoke(mDc);
176    }
177
178    private long getSuggestedRetryDelay(AsyncResult ar) throws Exception {
179        Class[] cArgs = new Class[1];
180        cArgs[0] = AsyncResult.class;
181        Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs);
182        method.setAccessible(true);
183        return (long) method.invoke(mDc, ar);
184    }
185
186    @Test
187    @SmallTest
188    public void testSanity() throws Exception {
189        assertEquals("DcInactiveState", getCurrentState().getName());
190    }
191
192    @Test
193    @SmallTest
194    public void testConnectEvent() throws Exception {
195        testSanity();
196
197        mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
198        waitForMs(200);
199
200        verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
201                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
202        verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
203                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
204
205        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
206        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
207                eq(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS), dpCaptor.capture(),
208                eq(false), eq(false), any(Message.class));
209
210        assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
211
212        assertEquals("DcActiveState", getCurrentState().getName());
213    }
214
215    @Test
216    @SmallTest
217    public void testDisconnectEvent() throws Exception {
218        testConnectEvent();
219
220        mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
221        waitForMs(100);
222
223        verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(eq(1),
224                eq(RILConstants.DEACTIVATE_REASON_NONE), any(Message.class));
225
226        assertEquals("DcInactiveState", getCurrentState().getName());
227    }
228
229    @Test
230    @SmallTest
231    public void testModemSuggestRetry() throws Exception {
232        DataCallResponse response = new DataCallResponse(0, 0, 1, 2, "IP",
233                FAKE_IFNAME, FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
234        AsyncResult ar = new AsyncResult(null, response, null);
235        assertEquals(response.suggestedRetryTime, getSuggestedRetryDelay(ar));
236
237        response = new DataCallResponse(0, 1000, 1, 2, "IP",
238                FAKE_IFNAME, FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
239        ar = new AsyncResult(null, response, null);
240        assertEquals(response.suggestedRetryTime, getSuggestedRetryDelay(ar));
241
242        response = new DataCallResponse(0, 9999, 1, 2, "IP",
243                FAKE_IFNAME, FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
244        ar = new AsyncResult(null, response, null);
245        assertEquals(response.suggestedRetryTime, getSuggestedRetryDelay(ar));
246    }
247
248    @Test
249    @SmallTest
250    public void testModemNotSuggestRetry() throws Exception {
251        DataCallResponse response = new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME,
252                FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
253        AsyncResult ar = new AsyncResult(null, response, null);
254        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
255
256        response = new DataCallResponse(0, -5, 1, 2, "IP", FAKE_IFNAME,
257                FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
258        ar = new AsyncResult(null, response, null);
259        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
260
261        response = new DataCallResponse(0, Integer.MIN_VALUE, 1, 2, "IP", FAKE_IFNAME,
262                FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
263        ar = new AsyncResult(null, response, null);
264        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
265    }
266
267    @Test
268    @SmallTest
269    public void testModemSuggestNoRetry() throws Exception {
270        DataCallResponse response = new DataCallResponse(0, Integer.MAX_VALUE, 1, 2, "IP",
271                FAKE_IFNAME, FAKE_ADDRESS, FAKE_DNS, FAKE_GATEWAY, FAKE_PCSCF_ADDRESS, 1440);
272        AsyncResult ar = new AsyncResult(null, response, null);
273        assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(ar));
274    }
275
276    private NetworkInfo getNetworkInfo() throws Exception {
277        Field f = DataConnection.class.getDeclaredField("mNetworkInfo");
278        f.setAccessible(true);
279        return (NetworkInfo) f.get(mDc);
280    }
281
282    private NetworkCapabilities getNetworkCapabilities() throws Exception {
283        Method method = DataConnection.class.getDeclaredMethod("getNetworkCapabilities");
284        method.setAccessible(true);
285        return (NetworkCapabilities) method.invoke(mDc);
286    }
287
288    @Test
289    @SmallTest
290    public void testMeteredCapability() throws Exception {
291
292        mContextFixture.getCarrierConfigBundle().
293                putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
294                new String[] {"default"});
295
296        testConnectEvent();
297
298        assertFalse(getNetworkCapabilities()
299                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
300    }
301
302    @Test
303    @SmallTest
304    public void testNonMeteredCapability() throws Exception {
305
306        doReturn(2819).when(mPhone).getSubId();
307        mContextFixture.getCarrierConfigBundle().
308                putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
309                        new String[] {"mms"});
310
311        testConnectEvent();
312
313        assertTrue(getNetworkCapabilities()
314                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
315    }
316
317    @SmallTest
318    public void testIsIpAddress() throws Exception {
319        // IPv4
320        assertTrue(DataConnection.isIpAddress("1.2.3.4"));
321        assertTrue(DataConnection.isIpAddress("127.0.0.1"));
322
323        // IPv6
324        assertTrue(DataConnection.isIpAddress("::1"));
325        assertTrue(DataConnection.isIpAddress("2001:4860:800d::68"));
326    }
327}
328