1 /*
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 
17 package android.telephony.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 
26 import android.bluetooth.BluetoothAdapter;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.net.ConnectivityManager;
31 import android.net.wifi.WifiInfo;
32 import android.net.wifi.WifiManager;
33 import android.os.Build;
34 import android.os.Looper;
35 import android.support.test.InstrumentationRegistry;
36 import android.support.test.runner.AndroidJUnit4;
37 import android.telecom.PhoneAccount;
38 import android.telecom.PhoneAccountHandle;
39 import android.telecom.TelecomManager;
40 import android.telephony.CellLocation;
41 import android.telephony.PhoneStateListener;
42 import android.telephony.ServiceState;
43 import android.telephony.TelephonyManager;
44 import android.text.TextUtils;
45 import android.util.Log;
46 
47 import com.android.compatibility.common.util.TestThread;
48 
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 
54 import java.util.List;
55 import java.util.regex.Pattern;
56 
57 /**
58  * Build, install and run the tests by running the commands below:
59  *  make cts -j64
60  *  cts-tradefed run cts -m CtsTelephonyTestCases --test android.telephony.cts.TelephonyManagerTest
61  */
62 @RunWith(AndroidJUnit4.class)
63 public class TelephonyManagerTest {
64     private TelephonyManager mTelephonyManager;
65     private PackageManager mPackageManager;
66     private boolean mOnCellLocationChangedCalled = false;
67     private ServiceState mServiceState;
68     private final Object mLock = new Object();
69     private static final int TOLERANCE = 1000;
70     private PhoneStateListener mListener;
71     private static ConnectivityManager mCm;
72     private static final String TAG = "TelephonyManagerTest";
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         mTelephonyManager =
77                 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
78         mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
79         mPackageManager = getContext().getPackageManager();
80     }
81 
82     @After
tearDown()83     public void tearDown() throws Exception {
84         if (mListener != null) {
85             // unregister the listener
86             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
87         }
88     }
89 
90     @Test
testListen()91     public void testListen() throws Throwable {
92         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
93             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
94             return;
95         }
96 
97         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
98             // TODO: temp workaround, need to adjust test to for CDMA
99             return;
100         }
101 
102         TestThread t = new TestThread(new Runnable() {
103             public void run() {
104                 Looper.prepare();
105                 mListener = new PhoneStateListener() {
106                     @Override
107                     public void onCellLocationChanged(CellLocation location) {
108                         if(!mOnCellLocationChangedCalled) {
109                             synchronized (mLock) {
110                                 mOnCellLocationChangedCalled = true;
111                                 mLock.notify();
112                             }
113                         }
114                     }
115                 };
116 
117                 synchronized (mLock) {
118                     mLock.notify(); // mListener is ready
119                 }
120 
121                 Looper.loop();
122             }
123         });
124 
125         synchronized (mLock) {
126             t.start();
127             mLock.wait(TOLERANCE); // wait for mListener
128         }
129 
130         // Test register
131         synchronized (mLock) {
132             // .listen generates an onCellLocationChanged event
133             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
134             mLock.wait(TOLERANCE);
135 
136             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
137                 mOnCellLocationChangedCalled);
138         }
139 
140         synchronized (mLock) {
141             mOnCellLocationChangedCalled = false;
142             CellLocation.requestLocationUpdate();
143             mLock.wait(TOLERANCE);
144 
145             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
146                 mOnCellLocationChangedCalled);
147         }
148 
149         // unregister the listener
150         mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
151         Thread.sleep(TOLERANCE);
152 
153         // Test unregister
154         synchronized (mLock) {
155             mOnCellLocationChangedCalled = false;
156             // unregister again, to make sure doing so does not call the listener
157             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
158             CellLocation.requestLocationUpdate();
159             mLock.wait(TOLERANCE);
160 
161             assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
162                 mOnCellLocationChangedCalled);
163         }
164     }
165 
166     /**
167      * The getter methods here are all related to the information about the telephony.
168      * These getters are related to concrete location, phone, service provider company, so
169      * it's no need to get details of these information, just make sure they are in right
170      * condition(>0 or not null).
171      */
172     @Test
testTelephonyManager()173     public void testTelephonyManager() {
174         assertTrue(mTelephonyManager.getNetworkType() >= TelephonyManager.NETWORK_TYPE_UNKNOWN);
175         assertTrue(mTelephonyManager.getPhoneType() >= TelephonyManager.PHONE_TYPE_NONE);
176         assertTrue(mTelephonyManager.getSimState() >= TelephonyManager.SIM_STATE_UNKNOWN);
177         assertTrue(mTelephonyManager.getDataActivity() >= TelephonyManager.DATA_ACTIVITY_NONE);
178         assertTrue(mTelephonyManager.getDataState() >= TelephonyManager.DATA_DISCONNECTED);
179         assertTrue(mTelephonyManager.getCallState() >= TelephonyManager.CALL_STATE_IDLE);
180 
181         for (int i = 0; i < mTelephonyManager.getPhoneCount(); ++i) {
182             assertTrue(mTelephonyManager.getSimState(i) >= TelephonyManager.SIM_STATE_UNKNOWN);
183         }
184 
185         // Make sure devices without MMS service won't fail on this
186         if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) {
187             assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty());
188             assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty());
189         }
190 
191         // The following methods may return any value depending on the state of the device. Simply
192         // call them to make sure they do not throw any exceptions.
193         mTelephonyManager.getVoiceMailNumber();
194         mTelephonyManager.getSimOperatorName();
195         mTelephonyManager.getNetworkCountryIso();
196         mTelephonyManager.getCellLocation();
197         mTelephonyManager.getSimCarrierId();
198         mTelephonyManager.getSimCarrierIdName();
199         mTelephonyManager.getSimSerialNumber();
200         mTelephonyManager.getSimOperator();
201         mTelephonyManager.getSignalStrength();
202         mTelephonyManager.getNetworkOperatorName();
203         mTelephonyManager.getSubscriberId();
204         mTelephonyManager.getLine1Number();
205         mTelephonyManager.getNetworkOperator();
206         mTelephonyManager.getSimCountryIso();
207         mTelephonyManager.getVoiceMailAlphaTag();
208         mTelephonyManager.getNeighboringCellInfo();
209         mTelephonyManager.isNetworkRoaming();
210         mTelephonyManager.getDeviceId();
211         mTelephonyManager.getDeviceId(mTelephonyManager.getSlotIndex());
212         mTelephonyManager.getDeviceSoftwareVersion();
213         mTelephonyManager.getImei();
214         mTelephonyManager.getImei(mTelephonyManager.getSlotIndex());
215         mTelephonyManager.getPhoneCount();
216         mTelephonyManager.getDataEnabled();
217         mTelephonyManager.getNetworkSpecifier();
218         mTelephonyManager.getNai();
219         TelecomManager telecomManager = (TelecomManager) getContext()
220                 .getSystemService(Context.TELECOM_SERVICE);
221         PhoneAccountHandle defaultAccount = telecomManager
222                 .getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
223         mTelephonyManager.getVoicemailRingtoneUri(defaultAccount);
224         mTelephonyManager.isVoicemailVibrationEnabled(defaultAccount);
225         mTelephonyManager.getCarrierConfig();
226     }
227 
228     @Test
testCreateForPhoneAccountHandle()229     public void testCreateForPhoneAccountHandle(){
230         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
231             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
232             return;
233         }
234         TelecomManager telecomManager = getContext().getSystemService(TelecomManager.class);
235         PhoneAccountHandle handle =
236                 telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
237         TelephonyManager telephonyManager = mTelephonyManager.createForPhoneAccountHandle(handle);
238         assertEquals(mTelephonyManager.getSubscriberId(), telephonyManager.getSubscriberId());
239     }
240 
241     @Test
testCreateForPhoneAccountHandle_InvalidHandle()242     public void testCreateForPhoneAccountHandle_InvalidHandle(){
243         PhoneAccountHandle handle =
244                 new PhoneAccountHandle(new ComponentName("com.example.foo", "bar"), "baz");
245         assertNull(mTelephonyManager.createForPhoneAccountHandle(handle));
246     }
247 
248     /**
249      * Tests that the phone count returned is valid.
250      */
251     @Test
testGetPhoneCount()252     public void testGetPhoneCount() {
253         int phoneCount = mTelephonyManager.getPhoneCount();
254         int phoneType = mTelephonyManager.getPhoneType();
255         switch (phoneType) {
256             case TelephonyManager.PHONE_TYPE_GSM:
257             case TelephonyManager.PHONE_TYPE_CDMA:
258                 assertTrue("Phone count should be > 0", phoneCount > 0);
259                 break;
260             case TelephonyManager.PHONE_TYPE_NONE:
261                 assertTrue("Phone count should be 0", phoneCount == 0 || phoneCount == 1);
262                 break;
263             default:
264                 throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
265         }
266     }
267 
268     /**
269      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
270      * if only a WiFi device. At least one of them must be valid.
271      */
272     @Test
testGetDeviceId()273     public void testGetDeviceId() {
274         verifyDeviceId(mTelephonyManager.getDeviceId());
275     }
276 
277     /**
278      * Tests that the device properly reports either a valid IMEI, MEID/ESN, or a valid MAC address
279      * if only a WiFi device. At least one of them must be valid.
280      */
281     @Test
testGetDeviceIdForSlot()282     public void testGetDeviceIdForSlot() {
283         String deviceId = mTelephonyManager.getDeviceId(mTelephonyManager.getSlotIndex());
284         verifyDeviceId(deviceId);
285         // Also verify that no exception is thrown for any slot index (including invalid ones)
286         for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
287             mTelephonyManager.getDeviceId(i);
288         }
289     }
290 
verifyDeviceId(String deviceId)291     private void verifyDeviceId(String deviceId) {
292         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
293             // Either IMEI or MEID need to be valid.
294             try {
295                 assertImei(deviceId);
296             } catch (AssertionError e) {
297                 assertMeidEsn(deviceId);
298             }
299         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
300             assertSerialNumber();
301             assertMacAddress(getWifiMacAddress());
302         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
303             assertSerialNumber();
304             assertMacAddress(getBluetoothMacAddress());
305         } else if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
306             assertTrue(mCm.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET) != null);
307         }
308     }
309 
assertImei(String id)310     private static void assertImei(String id) {
311         assertFalse("Imei should not be empty or null", TextUtils.isEmpty(id));
312         // IMEI may include the check digit
313         String imeiPattern = "[0-9]{14,15}";
314         String invalidPattern = "[0]{14,15}";
315         assertTrue("IMEI " + id + " does not match pattern " + imeiPattern,
316                 Pattern.matches(imeiPattern, id));
317         assertFalse("IMEI " + id + " must not be a zero sequence" + invalidPattern,
318                 Pattern.matches(invalidPattern, id));
319         if (id.length() == 15) {
320             // if the ID is 15 digits, the 15th must be a check digit.
321             assertImeiCheckDigit(id);
322         }
323     }
324 
assertImeiCheckDigit(String deviceId)325     private static void assertImeiCheckDigit(String deviceId) {
326         int expectedCheckDigit = getLuhnCheckDigit(deviceId.substring(0, 14));
327         int actualCheckDigit = Character.digit(deviceId.charAt(14), 10);
328         assertEquals("Incorrect check digit for " + deviceId, expectedCheckDigit, actualCheckDigit);
329     }
330 
331     /**
332      * Use decimal value (0-9) to index into array to get sum of its digits
333      * needed by Lunh check.
334      *
335      * Example: DOUBLE_DIGIT_SUM[6] = 3 because 6 * 2 = 12 => 1 + 2 = 3
336      */
337     private static final int[] DOUBLE_DIGIT_SUM = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
338 
339     /**
340      * Calculate the check digit by starting from the right, doubling every
341      * each digit, summing all the digits including the doubled ones, and
342      * finding a number to make the sum divisible by 10.
343      *
344      * @param deviceId not including the check digit
345      * @return the check digit
346      */
getLuhnCheckDigit(String deviceId)347     private static int getLuhnCheckDigit(String deviceId) {
348         int sum = 0;
349         int dontDoubleModulus = deviceId.length() % 2;
350         for (int i = deviceId.length() - 1; i >= 0; --i) {
351             int digit = Character.digit(deviceId.charAt(i), 10);
352             if (i % 2 == dontDoubleModulus) {
353                 sum += digit;
354             } else {
355                 sum += DOUBLE_DIGIT_SUM[digit];
356             }
357         }
358         sum %= 10;
359         return sum == 0 ? 0 : 10 - sum;
360     }
361 
assertMeidEsn(String id)362     private static void assertMeidEsn(String id) {
363         // CDMA device IDs may either be a 14-hex-digit MEID or an
364         // 8-hex-digit ESN.  If it's an ESN, it may not be a
365         // pseudo-ESN.
366         assertFalse("Meid ESN should not be empty or null", TextUtils.isEmpty(id));
367         if (id.length() == 14) {
368             assertMeidFormat(id);
369         } else if (id.length() == 8) {
370             assertHexadecimalEsnFormat(id);
371         } else {
372             fail("device id on CDMA must be 14-digit hex MEID or 8-digit hex ESN.");
373         }
374     }
375 
assertHexadecimalEsnFormat(String deviceId)376     private static void assertHexadecimalEsnFormat(String deviceId) {
377         String esnPattern = "[0-9a-fA-F]{8}";
378         String invalidPattern = "[0]{8}";
379         assertTrue("ESN hex device id " + deviceId + " does not match pattern " + esnPattern,
380                    Pattern.matches(esnPattern, deviceId));
381         assertFalse("ESN hex device id " + deviceId + " must not be a pseudo-ESN",
382                     "80".equals(deviceId.substring(0, 2)));
383         assertFalse("ESN hex device id " + deviceId + "must not be a zero sequence",
384                 Pattern.matches(invalidPattern, deviceId));
385     }
386 
assertMeidFormat(String deviceId)387     private static void assertMeidFormat(String deviceId) {
388         // MEID must NOT include the check digit.
389         String meidPattern = "[0-9a-fA-F]{14}";
390         String invalidPattern = "[0]{14}";
391         assertTrue("MEID device id " + deviceId + " does not match pattern "
392                 + meidPattern, Pattern.matches(meidPattern, deviceId));
393         assertFalse("MEID device id " + deviceId + "must not be a zero sequence",
394                 Pattern.matches(invalidPattern, deviceId));
395     }
396 
assertSerialNumber()397     private void assertSerialNumber() {
398         assertNotNull("Non-telephony devices must have a Build.getSerial() number.",
399                 Build.getSerial());
400         assertTrue("Hardware id must be no longer than 20 characters.",
401                 Build.getSerial().length() <= 20);
402         assertTrue("Hardware id must be alphanumeric.",
403                 Pattern.matches("[0-9A-Za-z]+", Build.getSerial()));
404     }
405 
assertMacAddress(String macAddress)406     private void assertMacAddress(String macAddress) {
407         String macPattern = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}";
408         assertTrue("MAC Address " + macAddress + " does not match pattern " + macPattern,
409                 Pattern.matches(macPattern, macAddress));
410     }
411 
412     /** @return mac address which requires the WiFi system to be enabled */
getWifiMacAddress()413     private String getWifiMacAddress() {
414         WifiManager wifiManager = (WifiManager) getContext()
415                 .getSystemService(Context.WIFI_SERVICE);
416 
417         boolean enabled = wifiManager.isWifiEnabled();
418 
419         try {
420             if (!enabled) {
421                 wifiManager.setWifiEnabled(true);
422             }
423 
424             WifiInfo wifiInfo = wifiManager.getConnectionInfo();
425             return wifiInfo.getMacAddress();
426 
427         } finally {
428             if (!enabled) {
429                 wifiManager.setWifiEnabled(false);
430             }
431         }
432     }
433 
getBluetoothMacAddress()434     private String getBluetoothMacAddress() {
435         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
436         if (adapter == null) {
437             return "";
438         }
439 
440         return adapter.getAddress();
441     }
442 
443     private static final String ISO_COUNTRY_CODE_PATTERN = "[a-z]{2}";
444 
445     @Test
testGetNetworkCountryIso()446     public void testGetNetworkCountryIso() {
447         String countryCode = mTelephonyManager.getNetworkCountryIso();
448         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
449             assertTrue("Country code '" + countryCode + "' did not match "
450                     + ISO_COUNTRY_CODE_PATTERN,
451                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
452         } else {
453             // Non-telephony may still have the property defined if it has a SIM.
454         }
455     }
456 
457     @Test
testGetSimCountryIso()458     public void testGetSimCountryIso() {
459         String countryCode = mTelephonyManager.getSimCountryIso();
460         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
461             assertTrue("Country code '" + countryCode + "' did not match "
462                     + ISO_COUNTRY_CODE_PATTERN,
463                     Pattern.matches(ISO_COUNTRY_CODE_PATTERN, countryCode));
464         } else {
465             // Non-telephony may still have the property defined if it has a SIM.
466         }
467     }
468 
469     @Test
testGetServiceState()470     public void testGetServiceState() throws InterruptedException {
471         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
472             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
473             return;
474         }
475 
476         TestThread t = new TestThread(new Runnable() {
477             public void run() {
478                 Looper.prepare();
479 
480                 mListener = new PhoneStateListener() {
481                     @Override
482                     public void onServiceStateChanged(ServiceState serviceState) {
483                         synchronized (mLock) {
484                             mServiceState = serviceState;
485                             mLock.notify();
486                         }
487                     }
488                 };
489                 mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
490                 Looper.loop();
491             }
492         });
493 
494         synchronized (mLock) {
495             t.start();
496             mLock.wait(TOLERANCE);
497         }
498 
499         assertEquals(mServiceState, mTelephonyManager.getServiceState());
500     }
501 
502     /**
503      * Tests that the device properly reports either a valid IMEI or null.
504      */
505     @Test
testGetImei()506     public void testGetImei() {
507         String imei = mTelephonyManager.getImei();
508 
509         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
510             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
511                 assertImei(imei);
512             }
513         }
514     }
515 
516     /**
517      * Tests that the device properly reports either a valid IMEI or null.
518      */
519     @Test
testGetImeiForSlot()520     public void testGetImeiForSlot() {
521         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
522             return;
523         }
524 
525         for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
526             String imei = mTelephonyManager.getImei(i);
527             if (!TextUtils.isEmpty(imei)) {
528                 assertImei(imei);
529             }
530         }
531 
532         // Also verify that no exception is thrown for any slot index (including invalid ones)
533         mTelephonyManager.getImei(-1);
534         mTelephonyManager.getImei(mTelephonyManager.getPhoneCount());
535     }
536 
537     /**
538      * Tests that the device properly reports either a valid MEID or null.
539      */
540     @Test
testGetMeid()541     public void testGetMeid() {
542         String meid = mTelephonyManager.getMeid();
543 
544         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
545             if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
546                 assertMeidEsn(meid);
547             }
548         }
549     }
550 
551     /**
552      * Tests that the device properly reports either a valid MEID or null.
553      */
554     @Test
testGetMeidForSlot()555     public void testGetMeidForSlot() {
556         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
557             return;
558         }
559 
560         for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
561             String meid = mTelephonyManager.getMeid(i);
562             if (!TextUtils.isEmpty(meid)) {
563                 assertMeidEsn(meid);
564             }
565         }
566 
567         // Also verify that no exception is thrown for any slot index (including invalid ones)
568         mTelephonyManager.getMeid(-1);
569         mTelephonyManager.getMeid(mTelephonyManager.getPhoneCount());
570     }
571 
572     /**
573      * Tests sendDialerSpecialCode API.
574      * Expects a security exception since the caller does not have carrier privileges or is not the
575      * current default dialer app.
576      */
577     @Test
testSendDialerSpecialCode()578     public void testSendDialerSpecialCode() {
579         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
580             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
581             return;
582         }
583         try {
584             mTelephonyManager.sendDialerSpecialCode("4636");
585             fail("Expected SecurityException. App does not have carrier privileges or is not the "
586                     + "default dialer app");
587         } catch (SecurityException expected) {
588         }
589     }
590 
591     /**
592      * Tests that the device properly reports the contents of EF_FPLMN or null
593      */
594     @Test
testGetForbiddenPlmns()595     public void testGetForbiddenPlmns() {
596         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
597             return;
598         }
599         String[] plmns = mTelephonyManager.getForbiddenPlmns();
600 
601         int phoneType = mTelephonyManager.getPhoneType();
602         switch (phoneType) {
603             case TelephonyManager.PHONE_TYPE_GSM:
604                 assertNotNull("Forbidden PLMNs must be valid or an empty list!", plmns);
605             case TelephonyManager.PHONE_TYPE_CDMA:
606             case TelephonyManager.PHONE_TYPE_NONE:
607                 if (plmns == null) {
608                     return;
609                 }
610         }
611 
612         for(String plmn : plmns) {
613             if (plmn.length() > 6 || plmn.length() < 5) {
614                 fail("Invalid Length for PLMN-ID, must be 5 or 6: " + plmn);
615             }
616 
617             // A record which is written in the SIM but empty will
618             // be all f's
619             if(android.text.TextUtils.isDigitsOnly(plmn)) {
620                 assertTrue(
621                         "PLMNs must be strings of digits 0-9,F! " + plmn,
622                         android.text.TextUtils.isDigitsOnly(plmn));
623             } else {
624                 for (char c : plmn.toUpperCase().toCharArray()) {
625                     assertTrue("PLMNs must be strings of digits 0-9,F! " + plmn,
626                             Character.toUpperCase(c) == 'F');
627                 }
628             }
629         }
630     }
631 
getContext()632     private static Context getContext() {
633         return InstrumentationRegistry.getContext();
634     }
635 
636     /**
637      * Tests that the device properly sets the network selection mode to automatic.
638      * Expects a security exception since the caller does not have carrier privileges.
639      */
640     @Test
testSetNetworkSelectionModeAutomatic()641     public void testSetNetworkSelectionModeAutomatic() {
642         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
643             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
644             return;
645         }
646         try {
647             mTelephonyManager.setNetworkSelectionModeAutomatic();
648             fail("Expected SecurityException. App does not have carrier privileges.");
649         } catch (SecurityException expected) {
650         }
651     }
652 
653     /**
654      * Tests that the device properly asks the radio to connect to the input network and change
655      * selection mode to manual.
656      * Expects a security exception since the caller does not have carrier privileges.
657      */
658     @Test
testSetNetworkSelectionModeManual()659     public void testSetNetworkSelectionModeManual() {
660         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
661             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
662             return;
663         }
664         try {
665             mTelephonyManager.setNetworkSelectionModeManual(
666                     "" /* operatorNumeric */, false /* persistSelection */);
667             fail("Expected SecurityException. App does not have carrier privileges.");
668         } catch (SecurityException expected) {
669         }
670     }
671 }
672