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 241 private static final String COMMAND_DELETE_IMSI_KEY = "cmd phone delete_imsi_key"; 242 addTestEmergencyNumber(Instrumentation instr, String testNumber)243 public static void addTestEmergencyNumber(Instrumentation instr, String testNumber) 244 throws Exception { 245 executeShellCommand(instr, COMMAND_ADD_TEST_EMERGENCY_NUMBER + testNumber); 246 } 247 removeTestEmergencyNumber(Instrumentation instr, String testNumber)248 public static void removeTestEmergencyNumber(Instrumentation instr, String testNumber) 249 throws Exception { 250 executeShellCommand(instr, COMMAND_REMOVE_TEST_EMERGENCY_NUMBER + testNumber); 251 } 252 endBlockSuppression(Instrumentation instr)253 public static void endBlockSuppression(Instrumentation instr) throws Exception { 254 executeShellCommand(instr, COMMAND_END_BLOCK_SUPPRESSION); 255 } 256 flushTelephonyMetrics(Instrumentation instr)257 public static void flushTelephonyMetrics(Instrumentation instr) throws Exception { 258 executeShellCommand(instr, COMMAND_FLUSH_TELEPHONY_METRICS); 259 } 260 enableCompatCommand(Instrumentation instr, String pkgName, String commandName)261 public static void enableCompatCommand(Instrumentation instr, String pkgName, 262 String commandName) throws Exception { 263 executeShellCommand(instr, COMMAND_AM_COMPAT + "enable --no-kill " + commandName + " " 264 + pkgName); 265 } 266 disableCompatCommand(Instrumentation instr, String pkgName, String commandName)267 public static void disableCompatCommand(Instrumentation instr, String pkgName, 268 String commandName) throws Exception { 269 executeShellCommand(instr, COMMAND_AM_COMPAT + "disable --no-kill " + commandName + " " 270 + pkgName); 271 } 272 resetCompatCommand(Instrumentation instr, String pkgName, String commandName)273 public static void resetCompatCommand(Instrumentation instr, String pkgName, 274 String commandName) throws Exception { 275 executeShellCommand(instr, COMMAND_AM_COMPAT + "reset --no-kill " + commandName + " " 276 + pkgName); 277 } 278 isSkt(TelephonyManager telephonyManager)279 public static boolean isSkt(TelephonyManager telephonyManager) { 280 return isOperator(telephonyManager, "45005"); 281 } 282 isKt(TelephonyManager telephonyManager)283 public static boolean isKt(TelephonyManager telephonyManager) { 284 return isOperator(telephonyManager, "45002") 285 || isOperator(telephonyManager, "45004") 286 || isOperator(telephonyManager, "45008"); 287 } 288 isOperator(TelephonyManager telephonyManager, String operator)289 private static boolean isOperator(TelephonyManager telephonyManager, String operator) { 290 String simOperator = telephonyManager.getSimOperator(); 291 return simOperator != null && simOperator.equals(operator); 292 } 293 parseErrorCodeToString(int errorCode, Class<?> containingClass, String prefix)294 public static String parseErrorCodeToString(int errorCode, 295 Class<?> containingClass, String prefix) { 296 for (Field field : containingClass.getDeclaredFields()) { 297 if (field.getName().startsWith(prefix)) { 298 if (field.getType() == Integer.TYPE) { 299 field.setAccessible(true); 300 try { 301 if (field.getInt(null) == errorCode) { 302 return field.getName(); 303 } 304 } catch (IllegalAccessException e) { 305 continue; 306 } 307 } 308 } 309 } 310 return String.format("??%d??", errorCode); 311 } 312 313 /** 314 * Executes the given shell command and returns the output in a string. Note that even 315 * if we don't care about the output, we have to read the stream completely to make the 316 * command execute. 317 */ executeShellCommand(Instrumentation instrumentation, String command)318 public static String executeShellCommand(Instrumentation instrumentation, 319 String command) throws Exception { 320 final ParcelFileDescriptor pfd = 321 instrumentation.getUiAutomation().executeShellCommand(command); 322 BufferedReader br = null; 323 try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) { 324 br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); 325 String str = null; 326 StringBuilder out = new StringBuilder(); 327 while ((str = br.readLine()) != null) { 328 out.append(str); 329 } 330 return out.toString(); 331 } finally { 332 if (br != null) { 333 closeQuietly(br); 334 } 335 closeQuietly(pfd); 336 } 337 } 338 closeQuietly(AutoCloseable closeable)339 private static void closeQuietly(AutoCloseable closeable) { 340 if (closeable != null) { 341 try { 342 closeable.close(); 343 } catch (RuntimeException rethrown) { 344 throw rethrown; 345 } catch (Exception ignored) { 346 } 347 } 348 } 349 pollUntilTrue(BooleanSupplier s, int times, int timeoutMs)350 public static boolean pollUntilTrue(BooleanSupplier s, int times, int timeoutMs) { 351 boolean successful = false; 352 for (int i = 0; i < times; i++) { 353 successful = s.getAsBoolean(); 354 if (successful) break; 355 try { 356 Thread.sleep(timeoutMs); 357 } catch (InterruptedException e) { } 358 } 359 return successful; 360 } 361 toHexString(byte[] array)362 public static String toHexString(byte[] array) { 363 int length = array.length; 364 char[] buf = new char[length * 2]; 365 366 int bufIndex = 0; 367 for (byte b : array) { 368 buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F]; 369 buf[bufIndex++] = HEX_DIGITS[b & 0x0F]; 370 } 371 372 return new String(buf); 373 } 374 toByte(char c)375 private static int toByte(char c) { 376 if (c >= '0' && c <= '9') return (c - '0'); 377 if (c >= 'A' && c <= 'F') return (c - 'A' + 10); 378 if (c >= 'a' && c <= 'f') return (c - 'a' + 10); 379 380 throw new RuntimeException("Invalid hex char '" + c + "'"); 381 } 382 hexStringToByteArray(String hexString)383 public static byte[] hexStringToByteArray(String hexString) { 384 int length = hexString.length(); 385 byte[] buffer = new byte[length / 2]; 386 387 for (int i = 0; i < length; i += 2) { 388 buffer[i / 2] = 389 (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1))); 390 } 391 392 return buffer; 393 } 394 395 /** 396 * Sets the allowlist package to the Json parsed data in CarrierAllowListInfo.java 397 * 398 * @param instr Test Instrumentation 399 * @param packageName caller packageName 400 * @param carrierId carrierId to match with 401 * @param shaId shaId of the caller 402 */ addCarrierRestrictionStatusAllowList(Instrumentation instr, String packageName, int carrierId, String shaId)403 public static void addCarrierRestrictionStatusAllowList(Instrumentation instr, 404 String packageName, int carrierId, String shaId) throws Exception { 405 if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(shaId)) { 406 return; 407 } 408 409 String allowList = "package:" + packageName + "," + "carrierIds:" + carrierId + "," 410 + "callerSHA256Ids:" + shaId; 411 executeShellCommand(instr, COMMAND_CARRIER_RESTRICTION_STATUS + allowList); 412 } 413 resetCarrierRestrictionStatusAllowList(Instrumentation instr)414 public static void resetCarrierRestrictionStatusAllowList(Instrumentation instr) 415 throws Exception { 416 executeShellCommand(instr, COMMAND_CARRIER_RESTRICTION_STATUS); 417 } 418 forceDeleteImsiEncryptionKey(Instrumentation instr)419 public static void forceDeleteImsiEncryptionKey(Instrumentation instr) 420 throws Exception { 421 executeShellCommand(instr, COMMAND_DELETE_IMSI_KEY); 422 } 423 424 425 } 426