1 /*
2  * Copyright (C) 2022 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.util;
18 
19 import android.app.Instrumentation;
20 import android.os.ParcelFileDescriptor;
21 import android.telecom.TelecomManager;
22 import android.telephony.AccessNetworkConstants;
23 import android.telephony.TelephonyManager;
24 import android.text.TextUtils;
25 
26 import java.io.BufferedReader;
27 import java.io.FileInputStream;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.lang.reflect.Field;
31 import java.nio.charset.StandardCharsets;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.function.BooleanSupplier;
35 
36 public class TelephonyUtils {
37 
38     /**
39      * See {@link TelecomManager#ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION}
40      */
41     public static final String ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION_STRING =
42             "ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION";
43 
44     /**
45      * See com.android.services.telephony.rcs.DelegateStateTracker#
46      * SUPPORT_REGISTERING_DELEGATE_STATE
47      */
48     public static final String SUPPORT_REGISTERING_DELEGATE_STATE_STRING =
49             "SUPPORT_REGISTERING_DELEGATE_STATE";
50     /**
51      * See com.android.services.telephony.rcs.DelegateStateTracker#
52      * SUPPORT_DEREGISTERING_LOSING_PDN_STATE
53      */
54     public static final String SUPPORT_DEREGISTERING_LOSING_PDN_STATE_STRING =
55             "SUPPORT_DEREGISTERING_LOSING_PDN_STATE";
56 
57     /**
58      * A map of {@link AccessNetworkConstants.RadioAccessNetworkType}s and its associated bands.
59      */
60     public static final Map<Integer, List<Integer>> ALL_BANDS = Map.of(
61             AccessNetworkConstants.AccessNetworkType.GERAN, List.of(
62                     AccessNetworkConstants.GeranBand.BAND_T380,
63                     AccessNetworkConstants.GeranBand.BAND_T410,
64                     AccessNetworkConstants.GeranBand.BAND_450,
65                     AccessNetworkConstants.GeranBand.BAND_480,
66                     AccessNetworkConstants.GeranBand.BAND_710,
67                     AccessNetworkConstants.GeranBand.BAND_750,
68                     AccessNetworkConstants.GeranBand.BAND_T810,
69                     AccessNetworkConstants.GeranBand.BAND_850,
70                     AccessNetworkConstants.GeranBand.BAND_P900,
71                     AccessNetworkConstants.GeranBand.BAND_E900,
72                     AccessNetworkConstants.GeranBand.BAND_R900,
73                     AccessNetworkConstants.GeranBand.BAND_DCS1800,
74                     AccessNetworkConstants.GeranBand.BAND_PCS1900,
75                     AccessNetworkConstants.GeranBand.BAND_ER900),
76             AccessNetworkConstants.AccessNetworkType.UTRAN, List.of(
77                     AccessNetworkConstants.UtranBand.BAND_1,
78                     AccessNetworkConstants.UtranBand.BAND_2,
79                     AccessNetworkConstants.UtranBand.BAND_3,
80                     AccessNetworkConstants.UtranBand.BAND_4,
81                     AccessNetworkConstants.UtranBand.BAND_5,
82                     AccessNetworkConstants.UtranBand.BAND_6,
83                     AccessNetworkConstants.UtranBand.BAND_7,
84                     AccessNetworkConstants.UtranBand.BAND_8,
85                     AccessNetworkConstants.UtranBand.BAND_9,
86                     AccessNetworkConstants.UtranBand.BAND_10,
87                     AccessNetworkConstants.UtranBand.BAND_11,
88                     AccessNetworkConstants.UtranBand.BAND_12,
89                     AccessNetworkConstants.UtranBand.BAND_13,
90                     AccessNetworkConstants.UtranBand.BAND_14,
91                     AccessNetworkConstants.UtranBand.BAND_19,
92                     AccessNetworkConstants.UtranBand.BAND_20,
93                     AccessNetworkConstants.UtranBand.BAND_21,
94                     AccessNetworkConstants.UtranBand.BAND_22,
95                     AccessNetworkConstants.UtranBand.BAND_25,
96                     AccessNetworkConstants.UtranBand.BAND_26,
97                     AccessNetworkConstants.UtranBand.BAND_A,
98                     AccessNetworkConstants.UtranBand.BAND_B,
99                     AccessNetworkConstants.UtranBand.BAND_C,
100                     AccessNetworkConstants.UtranBand.BAND_D,
101                     AccessNetworkConstants.UtranBand.BAND_E,
102                     AccessNetworkConstants.UtranBand.BAND_F),
103             AccessNetworkConstants.AccessNetworkType.EUTRAN, List.of(
104                     AccessNetworkConstants.EutranBand.BAND_1,
105                     AccessNetworkConstants.EutranBand.BAND_2,
106                     AccessNetworkConstants.EutranBand.BAND_3,
107                     AccessNetworkConstants.EutranBand.BAND_4,
108                     AccessNetworkConstants.EutranBand.BAND_5,
109                     AccessNetworkConstants.EutranBand.BAND_6,
110                     AccessNetworkConstants.EutranBand.BAND_7,
111                     AccessNetworkConstants.EutranBand.BAND_8,
112                     AccessNetworkConstants.EutranBand.BAND_9,
113                     AccessNetworkConstants.EutranBand.BAND_10,
114                     AccessNetworkConstants.EutranBand.BAND_11,
115                     AccessNetworkConstants.EutranBand.BAND_12,
116                     AccessNetworkConstants.EutranBand.BAND_13,
117                     AccessNetworkConstants.EutranBand.BAND_14,
118                     AccessNetworkConstants.EutranBand.BAND_17,
119                     AccessNetworkConstants.EutranBand.BAND_18,
120                     AccessNetworkConstants.EutranBand.BAND_19,
121                     AccessNetworkConstants.EutranBand.BAND_20,
122                     AccessNetworkConstants.EutranBand.BAND_21,
123                     AccessNetworkConstants.EutranBand.BAND_22,
124                     AccessNetworkConstants.EutranBand.BAND_23,
125                     AccessNetworkConstants.EutranBand.BAND_24,
126                     AccessNetworkConstants.EutranBand.BAND_25,
127                     AccessNetworkConstants.EutranBand.BAND_26,
128                     AccessNetworkConstants.EutranBand.BAND_27,
129                     AccessNetworkConstants.EutranBand.BAND_28,
130                     AccessNetworkConstants.EutranBand.BAND_30,
131                     AccessNetworkConstants.EutranBand.BAND_31,
132                     AccessNetworkConstants.EutranBand.BAND_33,
133                     AccessNetworkConstants.EutranBand.BAND_34,
134                     AccessNetworkConstants.EutranBand.BAND_35,
135                     AccessNetworkConstants.EutranBand.BAND_36,
136                     AccessNetworkConstants.EutranBand.BAND_37,
137                     AccessNetworkConstants.EutranBand.BAND_38,
138                     AccessNetworkConstants.EutranBand.BAND_39,
139                     AccessNetworkConstants.EutranBand.BAND_40,
140                     AccessNetworkConstants.EutranBand.BAND_41,
141                     AccessNetworkConstants.EutranBand.BAND_42,
142                     AccessNetworkConstants.EutranBand.BAND_43,
143                     AccessNetworkConstants.EutranBand.BAND_44,
144                     AccessNetworkConstants.EutranBand.BAND_45,
145                     AccessNetworkConstants.EutranBand.BAND_46,
146                     AccessNetworkConstants.EutranBand.BAND_47,
147                     AccessNetworkConstants.EutranBand.BAND_48,
148                     AccessNetworkConstants.EutranBand.BAND_49,
149                     AccessNetworkConstants.EutranBand.BAND_50,
150                     AccessNetworkConstants.EutranBand.BAND_51,
151                     AccessNetworkConstants.EutranBand.BAND_52,
152                     AccessNetworkConstants.EutranBand.BAND_53,
153                     AccessNetworkConstants.EutranBand.BAND_65,
154                     AccessNetworkConstants.EutranBand.BAND_66,
155                     AccessNetworkConstants.EutranBand.BAND_68,
156                     AccessNetworkConstants.EutranBand.BAND_70,
157                     AccessNetworkConstants.EutranBand.BAND_71,
158                     AccessNetworkConstants.EutranBand.BAND_72,
159                     AccessNetworkConstants.EutranBand.BAND_73,
160                     AccessNetworkConstants.EutranBand.BAND_74,
161                     AccessNetworkConstants.EutranBand.BAND_85,
162                     AccessNetworkConstants.EutranBand.BAND_87,
163                     AccessNetworkConstants.EutranBand.BAND_88),
164             AccessNetworkConstants.AccessNetworkType.NGRAN, List.of(
165                     AccessNetworkConstants.NgranBands.BAND_1,
166                     AccessNetworkConstants.NgranBands.BAND_2,
167                     AccessNetworkConstants.NgranBands.BAND_3,
168                     AccessNetworkConstants.NgranBands.BAND_5,
169                     AccessNetworkConstants.NgranBands.BAND_7,
170                     AccessNetworkConstants.NgranBands.BAND_8,
171                     AccessNetworkConstants.NgranBands.BAND_12,
172                     AccessNetworkConstants.NgranBands.BAND_14,
173                     AccessNetworkConstants.NgranBands.BAND_18,
174                     AccessNetworkConstants.NgranBands.BAND_20,
175                     AccessNetworkConstants.NgranBands.BAND_25,
176                     AccessNetworkConstants.NgranBands.BAND_26,
177                     AccessNetworkConstants.NgranBands.BAND_28,
178                     AccessNetworkConstants.NgranBands.BAND_29,
179                     AccessNetworkConstants.NgranBands.BAND_30,
180                     AccessNetworkConstants.NgranBands.BAND_34,
181                     AccessNetworkConstants.NgranBands.BAND_38,
182                     AccessNetworkConstants.NgranBands.BAND_39,
183                     AccessNetworkConstants.NgranBands.BAND_40,
184                     AccessNetworkConstants.NgranBands.BAND_41,
185                     AccessNetworkConstants.NgranBands.BAND_46,
186                     AccessNetworkConstants.NgranBands.BAND_48,
187                     AccessNetworkConstants.NgranBands.BAND_50,
188                     AccessNetworkConstants.NgranBands.BAND_51,
189                     AccessNetworkConstants.NgranBands.BAND_53,
190                     AccessNetworkConstants.NgranBands.BAND_65,
191                     AccessNetworkConstants.NgranBands.BAND_66,
192                     AccessNetworkConstants.NgranBands.BAND_70,
193                     AccessNetworkConstants.NgranBands.BAND_71,
194                     AccessNetworkConstants.NgranBands.BAND_74,
195                     AccessNetworkConstants.NgranBands.BAND_75,
196                     AccessNetworkConstants.NgranBands.BAND_76,
197                     AccessNetworkConstants.NgranBands.BAND_77,
198                     AccessNetworkConstants.NgranBands.BAND_78,
199                     AccessNetworkConstants.NgranBands.BAND_79,
200                     AccessNetworkConstants.NgranBands.BAND_80,
201                     AccessNetworkConstants.NgranBands.BAND_81,
202                     AccessNetworkConstants.NgranBands.BAND_82,
203                     AccessNetworkConstants.NgranBands.BAND_83,
204                     AccessNetworkConstants.NgranBands.BAND_84,
205                     AccessNetworkConstants.NgranBands.BAND_86,
206                     AccessNetworkConstants.NgranBands.BAND_89,
207                     AccessNetworkConstants.NgranBands.BAND_90,
208                     AccessNetworkConstants.NgranBands.BAND_91,
209                     AccessNetworkConstants.NgranBands.BAND_92,
210                     AccessNetworkConstants.NgranBands.BAND_93,
211                     AccessNetworkConstants.NgranBands.BAND_94,
212                     AccessNetworkConstants.NgranBands.BAND_95,
213                     AccessNetworkConstants.NgranBands.BAND_96,
214                     AccessNetworkConstants.NgranBands.BAND_257,
215                     AccessNetworkConstants.NgranBands.BAND_258,
216                     AccessNetworkConstants.NgranBands.BAND_260,
217                     AccessNetworkConstants.NgranBands.BAND_261));
218 
219     private static final String COMMAND_ADD_TEST_EMERGENCY_NUMBER =
220             "cmd phone emergency-number-test-mode -a ";
221 
222     private static final String COMMAND_REMOVE_TEST_EMERGENCY_NUMBER =
223             "cmd phone emergency-number-test-mode -r ";
224 
225     private static final String COMMAND_END_BLOCK_SUPPRESSION = "cmd phone end-block-suppression";
226 
227     private static final String COMMAND_FLUSH_TELEPHONY_METRICS =
228             "/system/bin/dumpsys activity service TelephonyDebugService --metricsproto";
229 
230     private static final String COMMAND_AM_COMPAT = "am compat ";
231 
232     public static final String CTS_APP_PACKAGE = "android.telephony.cts";
233     public static final String CTS_APP_PACKAGE2 = "android.telephony2.cts";
234 
235     private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
236             'A', 'B', 'C', 'D', 'E', 'F' };
237 
238     private static final String COMMAND_CARRIER_RESTRICTION_STATUS =
239             "cmd phone carrier_restriction_status_test --";
240 
addTestEmergencyNumber(Instrumentation instr, String testNumber)241     public static void addTestEmergencyNumber(Instrumentation instr, String testNumber)
242             throws Exception {
243         executeShellCommand(instr, COMMAND_ADD_TEST_EMERGENCY_NUMBER + testNumber);
244     }
245 
removeTestEmergencyNumber(Instrumentation instr, String testNumber)246     public static void removeTestEmergencyNumber(Instrumentation instr, String testNumber)
247             throws Exception {
248         executeShellCommand(instr, COMMAND_REMOVE_TEST_EMERGENCY_NUMBER + testNumber);
249     }
250 
endBlockSuppression(Instrumentation instr)251     public static void endBlockSuppression(Instrumentation instr) throws Exception {
252         executeShellCommand(instr, COMMAND_END_BLOCK_SUPPRESSION);
253     }
254 
flushTelephonyMetrics(Instrumentation instr)255     public static void flushTelephonyMetrics(Instrumentation instr) throws Exception {
256         executeShellCommand(instr, COMMAND_FLUSH_TELEPHONY_METRICS);
257     }
258 
enableCompatCommand(Instrumentation instr, String pkgName, String commandName)259     public static void enableCompatCommand(Instrumentation instr, String pkgName,
260             String commandName) throws Exception {
261         executeShellCommand(instr, COMMAND_AM_COMPAT + "enable  --no-kill " + commandName + " "
262                 + pkgName);
263     }
264 
disableCompatCommand(Instrumentation instr, String pkgName, String commandName)265     public static void disableCompatCommand(Instrumentation instr, String pkgName,
266             String commandName) throws Exception {
267         executeShellCommand(instr, COMMAND_AM_COMPAT + "disable  --no-kill " + commandName + " "
268                 + pkgName);
269     }
270 
resetCompatCommand(Instrumentation instr, String pkgName, String commandName)271     public static void resetCompatCommand(Instrumentation instr, String pkgName,
272             String commandName) throws Exception {
273         executeShellCommand(instr, COMMAND_AM_COMPAT + "reset  --no-kill " + commandName + " "
274                 + pkgName);
275     }
276 
isSkt(TelephonyManager telephonyManager)277     public static boolean isSkt(TelephonyManager telephonyManager) {
278         return isOperator(telephonyManager, "45005");
279     }
280 
isKt(TelephonyManager telephonyManager)281     public static boolean isKt(TelephonyManager telephonyManager) {
282         return isOperator(telephonyManager, "45002")
283                 || isOperator(telephonyManager, "45004")
284                 || isOperator(telephonyManager, "45008");
285     }
286 
isOperator(TelephonyManager telephonyManager, String operator)287     private static boolean isOperator(TelephonyManager telephonyManager, String operator) {
288         String simOperator = telephonyManager.getSimOperator();
289         return simOperator != null && simOperator.equals(operator);
290     }
291 
parseErrorCodeToString(int errorCode, Class<?> containingClass, String prefix)292     public static String parseErrorCodeToString(int errorCode,
293             Class<?> containingClass, String prefix) {
294         for (Field field : containingClass.getDeclaredFields()) {
295             if (field.getName().startsWith(prefix)) {
296                 if (field.getType() == Integer.TYPE) {
297                     field.setAccessible(true);
298                     try {
299                         if (field.getInt(null) == errorCode) {
300                             return field.getName();
301                         }
302                     } catch (IllegalAccessException e) {
303                         continue;
304                     }
305                 }
306             }
307         }
308         return String.format("??%d??", errorCode);
309     }
310 
311     /**
312      * Executes the given shell command and returns the output in a string. Note that even
313      * if we don't care about the output, we have to read the stream completely to make the
314      * command execute.
315      */
executeShellCommand(Instrumentation instrumentation, String command)316     public static String executeShellCommand(Instrumentation instrumentation,
317             String command) throws Exception {
318         final ParcelFileDescriptor pfd =
319                 instrumentation.getUiAutomation().executeShellCommand(command);
320         BufferedReader br = null;
321         try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
322             br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
323             String str = null;
324             StringBuilder out = new StringBuilder();
325             while ((str = br.readLine()) != null) {
326                 out.append(str);
327             }
328             return out.toString();
329         } finally {
330             if (br != null) {
331                 closeQuietly(br);
332             }
333             closeQuietly(pfd);
334         }
335     }
336 
closeQuietly(AutoCloseable closeable)337     private static void closeQuietly(AutoCloseable closeable) {
338         if (closeable != null) {
339             try {
340                 closeable.close();
341             } catch (RuntimeException rethrown) {
342                 throw rethrown;
343             } catch (Exception ignored) {
344             }
345         }
346     }
347 
pollUntilTrue(BooleanSupplier s, int times, int timeoutMs)348     public static boolean pollUntilTrue(BooleanSupplier s, int times, int timeoutMs) {
349         boolean successful = false;
350         for (int i = 0; i < times; i++) {
351             successful = s.getAsBoolean();
352             if (successful) break;
353             try {
354                 Thread.sleep(timeoutMs);
355             } catch (InterruptedException e) { }
356         }
357         return successful;
358     }
359 
toHexString(byte[] array)360     public static String toHexString(byte[] array) {
361         int length = array.length;
362         char[] buf = new char[length * 2];
363 
364         int bufIndex = 0;
365         for (byte b : array) {
366             buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
367             buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
368         }
369 
370         return new String(buf);
371     }
372 
toByte(char c)373     private static int toByte(char c) {
374         if (c >= '0' && c <= '9') return (c - '0');
375         if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
376         if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
377 
378         throw new RuntimeException("Invalid hex char '" + c + "'");
379     }
380 
hexStringToByteArray(String hexString)381     public static byte[] hexStringToByteArray(String hexString) {
382         int length = hexString.length();
383         byte[] buffer = new byte[length / 2];
384 
385         for (int i = 0; i < length; i += 2) {
386             buffer[i / 2] =
387                     (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
388         }
389 
390         return buffer;
391     }
392 
393     /**
394      * Sets the allowlist package to the Json parsed data in CarrierAllowListInfo.java
395      *
396      * @param instr       Test Instrumentation
397      * @param packageName caller packageName
398      * @param carrierId   carrierId to match with
399      * @param shaId       shaId of the caller
400      */
addCarrierRestrictionStatusAllowList(Instrumentation instr, String packageName, int carrierId, String shaId)401     public static void addCarrierRestrictionStatusAllowList(Instrumentation instr,
402             String packageName, int carrierId, String shaId) throws Exception {
403         if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(shaId)) {
404             return;
405         }
406 
407         String allowList = "package:" + packageName + "," + "carrierIds:" + carrierId + ","
408                 + "callerSHA256Ids:" + shaId;
409         executeShellCommand(instr, COMMAND_CARRIER_RESTRICTION_STATUS + allowList);
410     }
411 
resetCarrierRestrictionStatusAllowList(Instrumentation instr)412     public static void resetCarrierRestrictionStatusAllowList(Instrumentation instr)
413             throws Exception {
414         executeShellCommand(instr, COMMAND_CARRIER_RESTRICTION_STATUS);
415     }
416 }
417