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