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.test.suitebuilder.annotation.SmallTest; 44 45import com.android.internal.telephony.PhoneConstants; 46import com.android.internal.telephony.RILConstants; 47import com.android.internal.telephony.RetryManager; 48import com.android.internal.telephony.TelephonyTest; 49import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams; 50import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams; 51import com.android.internal.util.IState; 52import com.android.internal.util.StateMachine; 53 54import org.junit.After; 55import org.junit.Before; 56import org.junit.Test; 57import org.mockito.ArgumentCaptor; 58import org.mockito.Mock; 59 60import java.lang.reflect.Field; 61import java.lang.reflect.Method; 62 63public 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.quit(); 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}