blob: 8b94d00cd007b09e27592034ead5fac5746f9277 [file] [log] [blame]
Phil Dubach781d2da2009-07-15 14:45:26 -07001/*
2 * Copyright (C) 2009 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 android.telephony.cts;
18
Adam Lesinski82ac6a22014-06-06 14:09:56 -070019import android.bluetooth.BluetoothAdapter;
Phil Dubach781d2da2009-07-15 14:45:26 -070020import android.content.Context;
Madan Ankapura138292c2010-12-09 18:25:29 -080021import android.content.pm.PackageManager;
Chenjie Luod82745f2014-09-26 12:49:43 -070022import android.cts.util.ReadElf;
23import android.cts.util.TestThread;
bsc9ba1c72012-06-22 20:59:53 +090024import android.net.ConnectivityManager;
Brian Muramatsu5eed71e2010-05-19 15:52:03 -070025import android.net.wifi.WifiInfo;
26import android.net.wifi.WifiManager;
Andreas Huber30393d22010-09-30 09:33:24 -070027import android.os.Build;
Phil Dubach781d2da2009-07-15 14:45:26 -070028import android.os.Looper;
Phil Dubach781d2da2009-07-15 14:45:26 -070029import android.telephony.CellLocation;
30import android.telephony.PhoneStateListener;
31import android.telephony.TelephonyManager;
32import android.test.AndroidTestCase;
xinhea5c70e12014-10-02 11:07:49 -070033import android.util.Log;
Phil Dubach781d2da2009-07-15 14:45:26 -070034
Catherine Liu9b742b12012-08-23 16:41:56 -050035import com.android.internal.telephony.PhoneConstants;
36
Brian Muramatsu5eed71e2010-05-19 15:52:03 -070037import java.util.regex.Pattern;
38
Phil Dubach781d2da2009-07-15 14:45:26 -070039public class TelephonyManagerTest extends AndroidTestCase {
40 private TelephonyManager mTelephonyManager;
41 private boolean mOnCellLocationChangedCalled = false;
42 private final Object mLock = new Object();
43 private static final int TOLERANCE = 1000;
Phil Dubach781d2da2009-07-15 14:45:26 -070044 private PhoneStateListener mListener;
bsc9ba1c72012-06-22 20:59:53 +090045 private static ConnectivityManager mCm;
xinhea5c70e12014-10-02 11:07:49 -070046 private static final String TAG = "android.telephony.cts.TelephonyManagerTest";
Phil Dubach781d2da2009-07-15 14:45:26 -070047
48 @Override
49 protected void setUp() throws Exception {
50 super.setUp();
51 mTelephonyManager =
52 (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
xinhea5c70e12014-10-02 11:07:49 -070053 mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
Phil Dubach781d2da2009-07-15 14:45:26 -070054 }
55
56 @Override
57 protected void tearDown() throws Exception {
58 if (mListener != null) {
59 // unregister the listener
60 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
61 }
62 super.tearDown();
63 }
64
Phil Dubach781d2da2009-07-15 14:45:26 -070065 public void testListen() throws Throwable {
xinhea5c70e12014-10-02 11:07:49 -070066 if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
67 Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
68 return;
69 }
70
Brett Chabot45d71632009-11-06 20:22:55 -080071 if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
72 // TODO: temp workaround, need to adjust test to for CDMA
73 return;
74 }
Phil Dubach781d2da2009-07-15 14:45:26 -070075
76 // Test register
77 TestThread t = new TestThread(new Runnable() {
78 public void run() {
79 Looper.prepare();
80
Phil Dubach781d2da2009-07-15 14:45:26 -070081 mListener = new PhoneStateListener() {
82 @Override
83 public void onCellLocationChanged(CellLocation location) {
Mateusz Madetko2c66b382015-03-09 15:32:20 +010084 if(!mOnCellLocationChangedCalled) {
85 synchronized (mLock) {
86 mOnCellLocationChangedCalled = true;
87 mLock.notify();
88 }
Phil Dubach781d2da2009-07-15 14:45:26 -070089 }
90 }
91 };
92 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
xinhea91e7432014-10-06 15:48:12 -070093 CellLocation.requestLocationUpdate();
Phil Dubach781d2da2009-07-15 14:45:26 -070094 Looper.loop();
95 }
96 });
97 t.start();
Phil Dubach781d2da2009-07-15 14:45:26 -070098 synchronized (mLock) {
99 while (!mOnCellLocationChangedCalled) {
100 mLock.wait();
101 }
102 }
Phil Dubach781d2da2009-07-15 14:45:26 -0700103 assertTrue(mOnCellLocationChangedCalled);
104
105 // Test unregister
106 t = new TestThread(new Runnable() {
107 public void run() {
108 Looper.prepare();
Phil Dubach781d2da2009-07-15 14:45:26 -0700109 // unregister the listener
110 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
111 mOnCellLocationChangedCalled = false;
112 // unregister again, to make sure doing so does not call the listener
113 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
xinhea91e7432014-10-06 15:48:12 -0700114 CellLocation.requestLocationUpdate();
Phil Dubach781d2da2009-07-15 14:45:26 -0700115 Looper.loop();
116 }
117 });
Phil Dubach781d2da2009-07-15 14:45:26 -0700118
xinhea91e7432014-10-06 15:48:12 -0700119 t.start();
Phil Dubach781d2da2009-07-15 14:45:26 -0700120 synchronized (mLock) {
Brett Chabotec611462009-12-22 15:54:34 -0800121 mLock.wait(TOLERANCE);
Phil Dubach781d2da2009-07-15 14:45:26 -0700122 }
xinhea91e7432014-10-06 15:48:12 -0700123 assertFalse(mOnCellLocationChangedCalled);
Phil Dubach781d2da2009-07-15 14:45:26 -0700124 }
125
126 /**
127 * The getter methods here are all related to the information about the telephony.
128 * These getters are related to concrete location, phone, service provider company, so
129 * it's no need to get details of these information, just make sure they are in right
130 * condition(>0 or not null).
131 */
Phil Dubach781d2da2009-07-15 14:45:26 -0700132 public void testTelephonyManager() {
133 assertTrue(mTelephonyManager.getNetworkType() >= TelephonyManager.NETWORK_TYPE_UNKNOWN);
134 assertTrue(mTelephonyManager.getPhoneType() >= TelephonyManager.PHONE_TYPE_NONE);
135 assertTrue(mTelephonyManager.getSimState() >= TelephonyManager.SIM_STATE_UNKNOWN);
136 assertTrue(mTelephonyManager.getDataActivity() >= TelephonyManager.DATA_ACTIVITY_NONE);
137 assertTrue(mTelephonyManager.getDataState() >= TelephonyManager.DATA_DISCONNECTED);
138 assertTrue(mTelephonyManager.getCallState() >= TelephonyManager.CALL_STATE_IDLE);
139
Yuhao Zhengb71fbd42013-10-04 10:22:43 -0700140 // Make sure devices without MMS service won't fail on this
141 if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) {
142 assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty());
143 assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty());
144 }
145
Phil Dubach781d2da2009-07-15 14:45:26 -0700146 // The following methods may return null. Simply call them to make sure they do not
147 // throw any exceptions.
148 mTelephonyManager.getVoiceMailNumber();
149 mTelephonyManager.getSimOperatorName();
150 mTelephonyManager.getNetworkCountryIso();
151 mTelephonyManager.getCellLocation();
152 mTelephonyManager.getSimSerialNumber();
153 mTelephonyManager.getSimOperator();
154 mTelephonyManager.getNetworkOperatorName();
155 mTelephonyManager.getSubscriberId();
156 mTelephonyManager.getLine1Number();
157 mTelephonyManager.getNetworkOperator();
158 mTelephonyManager.getSimCountryIso();
159 mTelephonyManager.getVoiceMailAlphaTag();
160 mTelephonyManager.getNeighboringCellInfo();
161 mTelephonyManager.isNetworkRoaming();
162 mTelephonyManager.getDeviceId();
Amit Mahajan82267c42015-06-15 12:13:25 -0700163 mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
Phil Dubach781d2da2009-07-15 14:45:26 -0700164 mTelephonyManager.getDeviceSoftwareVersion();
Amit Mahajan82267c42015-06-15 12:13:25 -0700165 mTelephonyManager.getPhoneCount();
166 }
167
168 /**
169 * Tests that the phone count returned is valid.
170 */
171 public void testGetPhoneCount() {
172 int phoneCount = mTelephonyManager.getPhoneCount();
173 int phoneType = mTelephonyManager.getPhoneType();
174 switch (phoneType) {
175 case TelephonyManager.PHONE_TYPE_GSM:
176 case TelephonyManager.PHONE_TYPE_CDMA:
177 assertTrue("Phone count should be > 0", phoneCount > 0);
178 break;
179 case TelephonyManager.PHONE_TYPE_NONE:
Amit Mahajan4dad5952015-08-06 13:47:28 -0700180 assertTrue("Phone count should be 0", phoneCount == 0 || phoneCount == 1);
Amit Mahajan82267c42015-06-15 12:13:25 -0700181 break;
182 default:
183 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
184 }
Phil Dubach781d2da2009-07-15 14:45:26 -0700185 }
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700186
187 /**
Doug Zongkerfeb81e92010-08-24 13:17:13 -0700188 * Tests that the device properly reports either a valid IMEI if
189 * GSM, a valid MEID or ESN if CDMA, or a valid MAC address if
190 * only a WiFi device.
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700191 */
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700192 public void testGetDeviceId() {
193 String deviceId = mTelephonyManager.getDeviceId();
Amit Mahajan82267c42015-06-15 12:13:25 -0700194 verifyDeviceId(deviceId);
195 }
196
197 /**
198 * Tests that the device properly reports either a valid IMEI if
199 * GSM, a valid MEID or ESN if CDMA, or a valid MAC address if
200 * only a WiFi device.
201 */
202 public void testGetDeviceIdForSlotId() {
203 String deviceId = mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
204 verifyDeviceId(deviceId);
205 // Also verify that no exception is thrown for any slot id (including invalid ones)
206 for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
207 mTelephonyManager.getDeviceId(i);
208 }
209 }
210
211 private void verifyDeviceId(String deviceId) {
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700212 int phoneType = mTelephonyManager.getPhoneType();
213 switch (phoneType) {
214 case TelephonyManager.PHONE_TYPE_GSM:
Doug Zongkerd966f9e2011-03-03 16:59:02 -0800215 assertGsmDeviceId(deviceId);
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700216 break;
217
218 case TelephonyManager.PHONE_TYPE_CDMA:
Catherine Liu9b742b12012-08-23 16:41:56 -0500219 // LTE device is using IMEI as device id
220 if (mTelephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) {
221 assertGsmDeviceId(deviceId);
222 } else {
223 assertCdmaDeviceId(deviceId);
224 }
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700225 break;
226
227 case TelephonyManager.PHONE_TYPE_NONE:
bsc9ba1c72012-06-22 20:59:53 +0900228 boolean nwSupported = mCm.isNetworkSupported(mCm.TYPE_WIFI);
Hoang Van Tham2b599f02015-06-04 11:44:01 +0700229 PackageManager packageManager = getContext().getPackageManager();
Unsuk Jung7a31d612015-09-09 14:38:22 -0700230 // only check serial number & MAC address if device report wifi feature
Hoang Van Tham2b599f02015-06-04 11:44:01 +0700231 if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
bsc9ba1c72012-06-22 20:59:53 +0900232 assertSerialNumber();
Adam Lesinski82ac6a22014-06-06 14:09:56 -0700233 assertMacAddress(getWifiMacAddress());
xinhea5c70e12014-10-02 11:07:49 -0700234 } else if (mCm.getNetworkInfo(ConnectivityManager.TYPE_BLUETOOTH) != null) {
Adam Lesinski82ac6a22014-06-06 14:09:56 -0700235 assertSerialNumber();
236 assertMacAddress(getBluetoothMacAddress());
bsc9ba1c72012-06-22 20:59:53 +0900237 } else {
xinhea5c70e12014-10-02 11:07:49 -0700238 assertTrue(mCm.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET) != null);
bsc9ba1c72012-06-22 20:59:53 +0900239 }
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700240 break;
241
242 default:
243 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
244 }
245 }
246
Doug Zongkerd966f9e2011-03-03 16:59:02 -0800247 private static void assertGsmDeviceId(String deviceId) {
248 // IMEI may include the check digit
249 String imeiPattern = "[0-9]{14,15}";
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700250 assertTrue("IMEI device id " + deviceId + " does not match pattern " + imeiPattern,
251 Pattern.matches(imeiPattern, deviceId));
Doug Zongkerd966f9e2011-03-03 16:59:02 -0800252 if (deviceId.length() == 15) {
253 // if the ID is 15 digits, the 15th must be a check digit.
254 assertImeiCheckDigit(deviceId);
255 }
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700256 }
257
258 private static void assertImeiCheckDigit(String deviceId) {
259 int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14));
260 int actualCheckDigit = Character.digit(deviceId.charAt(14), 10);
261 assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit);
262 }
263
264 /**
265 * Use decimal value (0-9) to index into array to get sum of its digits
266 * needed by Lunh check.
267 *
268 * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3
269 */
270 private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
271
272 /**
273 * Calculate the check digit by starting from the right, doubling every
274 * each digit, summing all the digits including the doubled ones, and
275 * finding a number to make the sum divisible by 10.
276 *
277 * @param deviceId not including the check digit
278 * @return the check digit
279 */
280 private static int getLuhnCheckDigit(String deviceId) {
281 int sum = 0;
282 int dontDoubleModulus = deviceId.length() % 2;
283 for (int i = deviceId.length() - 1; i >= 0; --i) {
284 int digit = Character.digit(deviceId.charAt(i), 10);
285 if (i % 2 == dontDoubleModulus) {
286 sum += digit;
287 } else {
288 sum += DOUBLE_DIGIT_SUM[digit];
289 }
290 }
291 sum %= 10;
292 return sum == 0 ? 0 : 10 - sum;
293 }
294
Doug Zongkerfeb81e92010-08-24 13:17:13 -0700295 private static void assertCdmaDeviceId(String deviceId) {
Doug Zongkerd966f9e2011-03-03 16:59:02 -0800296 // CDMA device IDs may either be a 14-hex-digit MEID or an
297 // 8-hex-digit ESN. If it's an ESN, it may not be a
298 // pseudo-ESN.
Doug Zongkerfeb81e92010-08-24 13:17:13 -0700299 if (deviceId.length() == 14) {
Brian Muramatsude5f2102010-09-28 11:02:01 -0700300 assertMeidFormat(deviceId);
Doug Zongkerfeb81e92010-08-24 13:17:13 -0700301 } else if (deviceId.length() == 8) {
302 assertHexadecimalEsnFormat(deviceId);
303 } else {
304 fail("device id on CDMA must be 14-digit hex MEID or 8-digit hex ESN.");
305 }
306 }
307
308 private static void assertHexadecimalEsnFormat(String deviceId) {
309 String esnPattern = "[0-9a-fA-F]{8}";
310 assertTrue("ESN hex device id " + deviceId + " does not match pattern " + esnPattern,
311 Pattern.matches(esnPattern, deviceId));
312 assertFalse("ESN hex device id " + deviceId + " must not be a pseudo-ESN",
313 "80".equals(deviceId.substring(0, 2)));
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700314 }
315
Brian Muramatsude5f2102010-09-28 11:02:01 -0700316 private static void assertMeidFormat(String deviceId) {
Doug Zongkerd966f9e2011-03-03 16:59:02 -0800317 // MEID must NOT include the check digit.
318 String meidPattern = "[0-9a-fA-F]{14}";
319 assertTrue("MEID device id " + deviceId + " does not match pattern " + meidPattern,
320 Pattern.matches(meidPattern, deviceId));
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700321 }
322
Brian Muramatsuafcbb782010-08-17 13:53:59 -0700323 private void assertSerialNumber() {
324 assertNotNull("Non-telephony devices must have a Build.SERIAL number.",
325 Build.SERIAL);
326 assertTrue("Hardware id must be no longer than 20 characters.",
327 Build.SERIAL.length() <= 20);
328 assertTrue("Hardware id must be alphanumeric.",
329 Pattern.matches("[0-9A-Za-z]+", Build.SERIAL));
330 }
331
Adam Lesinski82ac6a22014-06-06 14:09:56 -0700332 private void assertMacAddress(String macAddress) {
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700333 String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
334 assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern,
335 Pattern.matches(macPattern, macAddress));
336 }
337
338 /** @return mac address which requires the WiFi system to be enabled */
Adam Lesinski82ac6a22014-06-06 14:09:56 -0700339 private String getWifiMacAddress() {
Brian Muramatsu5eed71e2010-05-19 15:52:03 -0700340 WifiManager wifiManager = (WifiManager) getContext()
341 .getSystemService(Context.WIFI_SERVICE);
342
343 boolean enabled = wifiManager.isWifiEnabled();
344
345 try {
346 if (!enabled) {
347 wifiManager.setWifiEnabled(true);
348 }
349
350 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
351 return wifiInfo.getMacAddress();
352
353 } finally {
354 if (!enabled) {
355 wifiManager.setWifiEnabled(false);
356 }
357 }
358 }
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700359
Adam Lesinski82ac6a22014-06-06 14:09:56 -0700360 private String getBluetoothMacAddress() {
361 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
362 if (adapter == null) {
363 return "";
364 }
365
366 return adapter.getAddress();
367 }
368
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700369 private static final String ISO_COUNTRY_CODE_PATTERN = "[a-z]{2}";
370
371 public void testGetNetworkCountryIso() {
Madan Ankapura138292c2010-12-09 18:25:29 -0800372 PackageManager packageManager = getContext().getPackageManager();
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700373 String countryCode = mTelephonyManager.getNetworkCountryIso();
Madan Ankapura138292c2010-12-09 18:25:29 -0800374 if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
375 assertTrue("Country code '" + countryCode + "' did not match "
376 + ISO_COUNTRY_CODE_PATTERN,
377 Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
378 } else {
Brian Muramatsubb7617c2010-12-14 15:27:22 -0800379 // Non-telephony may still have the property defined if it has a SIM.
Madan Ankapura138292c2010-12-09 18:25:29 -0800380 }
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700381 }
382
383 public void testGetSimCountryIso() {
Madan Ankapura138292c2010-12-09 18:25:29 -0800384 PackageManager packageManager = getContext().getPackageManager();
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700385 String countryCode = mTelephonyManager.getSimCountryIso();
Madan Ankapura138292c2010-12-09 18:25:29 -0800386 if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
387 assertTrue("Country code '" + countryCode + "' did not match "
388 + ISO_COUNTRY_CODE_PATTERN,
389 Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
390 } else {
Brian Muramatsubb7617c2010-12-14 15:27:22 -0800391 // Non-telephony may still have the property defined if it has a SIM.
Madan Ankapura138292c2010-12-09 18:25:29 -0800392 }
Brian Muramatsuef3a2ec2010-10-22 16:58:40 -0700393 }
Phil Dubach781d2da2009-07-15 14:45:26 -0700394}