1 /*
2  * Copyright (C) 2021 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.compatibility.common.util;
18 
19 import android.Manifest;
20 import android.telephony.TelephonyManager;
21 
22 import androidx.annotation.StringDef;
23 import androidx.test.InstrumentationRegistry;
24 
25 import java.util.List;
26 
27 /** Utility class for common UICC- and SIM-related operations. */
28 public final class UiccUtil {
29     /** The hashes of all supported CTS UICC test keys and their corresponding specification. */
30     @StringDef({UiccCertificate.CTS_UICC_LEGACY, UiccCertificate.CTS_UICC_2021})
31     public @interface UiccCertificate {
32 
33         /**
34          * Indicates compliance with the "legacy" CTS UICC specification (prior to 2021).
35          *
36          * <p>Deprecated as of 2021, support to be removed in 2022.
37          *
38          * <p>Corresponding certificate: {@code aosp-testkey}.
39          */
40         String CTS_UICC_LEGACY = "61ED377E85D386A8DFEE6B864BD85B0BFAA5AF81";
41 
42         /**
43          * Indicates compliance with the 2021 CTS UICC specification.
44          *
45          * <p>Strongly recommended as of 2021, required as of 2022.
46          *
47          * <p>Corresponding certificate: {@code cts-uicc-2021-testkey}.
48          */
49         String CTS_UICC_2021 = "CE7B2B47AE2B7552C8F92CC29124279883041FB623A5F194A82C9BF15D492AA0";
50     }
51 
52     /**
53      * A simple check for use with {@link org.junit.Assume#assumeTrue}. Checks the carrier privilege
54      * certificates stored on the SIM and returns {@code true} if {@code requiredCert} is present.
55      *
56      * <p>Can be used either in the {@code #setUp} method if an entire class requires a particular
57      * UICC, or at the top of a specific {@code @Test} method.
58      *
59      * <p>If we had JUnit 5, we could create a much cooler {@code @RequiresUiccCertificate}
60      * annotation using {@code ExtendWith} and {@code ExecutionCondition}, but that isn't available
61      * to us yet.
62      */
uiccHasCertificate(@iccCertificate String requiredCert)63     public static boolean uiccHasCertificate(@UiccCertificate String requiredCert) {
64         TelephonyManager tm =
65                 InstrumentationRegistry.getInstrumentation()
66                         .getTargetContext()
67                         .getSystemService(TelephonyManager.class);
68         List<String> uiccCerts =
69                 ShellIdentityUtils.invokeMethodWithShellPermissions(
70                         tm,
71                         TelephonyManager::getCertsFromCarrierPrivilegeAccessRules,
72                         Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
73         return uiccCerts == null ? false : uiccCerts.contains(requiredCert);
74     }
75 }
76