1 /*
2  * Copyright (C) 2018 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.telephony3.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNull;
21 import static org.junit.Assert.fail;
22 
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.os.Build;
26 import android.platform.test.annotations.AsbSecurityTest;
27 import android.telephony.SubscriptionInfo;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyManager;
30 
31 import androidx.test.InstrumentationRegistry;
32 import androidx.test.runner.AndroidJUnit4;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 /**
39  * Verifies the APIs for apps with the READ_PHONE_STATE permission targeting pre-Q.
40  *
41  * @see android.telephony.cts.TelephonyManagerTest
42 
43  */
44 @RunWith(AndroidJUnit4.class)
45 public class TelephonyManagerTest {
46     private Context mContext;
47     private TelephonyManager mTelephonyManager;
48 
49     @Before
setUp()50     public void setUp() throws Exception {
51         mContext = InstrumentationRegistry.getContext();
52         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
53     }
54 
55     @Test
56     @AsbSecurityTest(cveBugId = 173421434)
testDeviceIdentifiersAreNotAccessible()57     public void testDeviceIdentifiersAreNotAccessible() throws Exception {
58         // Apps with the READ_PHONE_STATE permission should no longer have access to device
59         // identifiers. If an app's target SDK is less than Q and it has been granted the
60         // READ_PHONE_STATE permission then a null value should be returned when querying for device
61         // identifiers; this test verifies a null value is returned for device identifier queries.
62         try {
63             assertNull(
64                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
65                             + "receive null when invoking getDeviceId",
66                     mTelephonyManager.getDeviceId());
67             assertNull(
68                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
69                             + "receive null when invoking getImei",
70                     mTelephonyManager.getImei());
71             assertNull(
72                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
73                             + "receive null when invoking getMeid",
74                     mTelephonyManager.getMeid());
75             assertNull(
76                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
77                             + "receive null when invoking getSubscriberId",
78                     mTelephonyManager.getSubscriberId());
79             assertNull(
80                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
81                             + "receive null when invoking getSimSerialNumber",
82                     mTelephonyManager.getSimSerialNumber());
83             assertNull(
84                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
85                             + "receive null when invoking getNai",
86                     mTelephonyManager.getNai());
87             // Since Build.getSerial is not documented to return null in previous releases this test
88             // verifies that the Build.UNKNOWN value is returned when the caller does not have
89             // permission to access the device identifier.
90             assertEquals(
91                     "An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
92                             + "receive " + Build.UNKNOWN + " when invoking Build.getSerial",
93                     Build.getSerial(), Build.UNKNOWN);
94             // Previous getIccId documentation does not indicate the value returned if the ICC ID is
95             // not available, so to prevent NPEs SubscriptionInfo#getIccId will return an empty
96             // string if the caller does not have permission to access this identifier.
97             if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
98                 SubscriptionManager subscriptionManager =
99                         (SubscriptionManager) mContext.getSystemService(
100                                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
101                 int subId = subscriptionManager.getDefaultSubscriptionId();
102                 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
103                     SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(
104                             subId);
105                     assertEquals(
106                             "An app targeting pre-Q with the READ_PHONE_STATE permission granted "
107                                     + "must receive an empty string when invoking getIccId",
108                             "", subInfo.getIccId());
109                 }
110             }
111         } catch (SecurityException e) {
112             fail("An app targeting pre-Q with the READ_PHONE_STATE permission granted must "
113                     + "receive null (or "
114                     + Build.UNKNOWN
115                     + " for Build#getSerial) when querying for device identifiers, caught "
116                     + "SecurityException instead: " + e);
117         }
118     }
119 }
120