1 /* 2 * Copyright (C) 2024 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.server.telecom; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.net.Uri; 22 import android.os.Binder; 23 import android.os.Process; 24 import android.os.RemoteException; 25 import android.os.UserHandle; 26 import android.os.UserManager; 27 import android.sysprop.TelephonyProperties; 28 import android.telecom.Log; 29 import android.telecom.PhoneAccount; 30 import android.telecom.PhoneAccountHandle; 31 import android.telephony.TelephonyManager; 32 import android.text.TextUtils; 33 34 import com.android.internal.telecom.ITelecomService; 35 import com.android.modules.utils.BasicShellCommandHandler; 36 37 import java.util.Arrays; 38 import java.util.stream.Collectors; 39 40 /** 41 * Implements shell commands sent to telecom using the "adb shell cmd telecom..." command from shell 42 * or CTS. 43 */ 44 public class TelecomShellCommand extends BasicShellCommandHandler { 45 private static final String CALLING_PACKAGE = TelecomShellCommand.class.getPackageName(); 46 private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled"; 47 private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled"; 48 private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account"; 49 private static final String COMMAND_SET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT = 50 "set-user-selected-outgoing-phone-account"; 51 private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account"; 52 private static final String COMMAND_SET_TEST_CALL_REDIRECTION_APP = 53 "set-test-call-redirection-app"; 54 private static final String COMMAND_SET_TEST_CALL_SCREENING_APP = "set-test-call-screening-app"; 55 private static final String COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP = 56 "add-or-remove-call-companion-app"; 57 private static final String COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT = 58 "set-phone-acct-suggestion-component"; 59 private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account"; 60 private static final String COMMAND_SET_CALL_DIAGNOSTIC_SERVICE = "set-call-diagnostic-service"; 61 private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer"; 62 private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer"; 63 private static final String COMMAND_STOP_BLOCK_SUPPRESSION = "stop-block-suppression"; 64 private static final String COMMAND_CLEANUP_STUCK_CALLS = "cleanup-stuck-calls"; 65 private static final String COMMAND_CLEANUP_ORPHAN_PHONE_ACCOUNTS = 66 "cleanup-orphan-phone-accounts"; 67 private static final String COMMAND_RESET_CAR_MODE = "reset-car-mode"; 68 private static final String COMMAND_IS_NON_IN_CALL_SERVICE_BOUND = 69 "is-non-ui-in-call-service-bound"; 70 private static final String COMMAND_WAIT_FOR_AUDIO_OPS_COMPLETION = 71 "wait-for-audio-ops-complete"; 72 private static final String COMMAND_WAIT_FOR_AUDIO_ACTIVE_COMPLETION = 73 "wait-for-audio-active"; 74 75 /** 76 * Change the system dialer package name if a package name was specified, 77 * Example: adb shell telecom set-system-dialer <PACKAGE> 78 * 79 * Restore it to the default if if argument is "default" or no argument is passed. 80 * Example: adb shell telecom set-system-dialer default 81 */ 82 private static final String COMMAND_SET_SYSTEM_DIALER = "set-system-dialer"; 83 private static final String COMMAND_GET_SYSTEM_DIALER = "get-system-dialer"; 84 private static final String COMMAND_WAIT_ON_HANDLERS = "wait-on-handlers"; 85 private static final String COMMAND_SET_SIM_COUNT = "set-sim-count"; 86 private static final String COMMAND_GET_SIM_CONFIG = "get-sim-config"; 87 private static final String COMMAND_GET_MAX_PHONES = "get-max-phones"; 88 private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER = 89 "set-test-emergency-phone-account-package-filter"; 90 private static final String COMMAND_SET_METRICS_TEST_ENABLED = "set-metrics-test-enabled"; 91 private static final String COMMAND_SET_METRICS_TEST_DISABLED = "set-metrics-test-disabled"; 92 /** 93 * Command used to emit a distinct "mark" in the logs. 94 */ 95 private static final String COMMAND_LOG_MARK = "log-mark"; 96 97 private final Context mContext; 98 private final ITelecomService mTelecomService; 99 private TelephonyManager mTelephonyManager; 100 private UserManager mUserManager; 101 TelecomShellCommand(ITelecomService binder, Context context)102 public TelecomShellCommand(ITelecomService binder, Context context) { 103 mTelecomService = binder; 104 mContext = context; 105 } 106 107 @Override onCommand(String command)108 public int onCommand(String command) { 109 if (command == null || command.isEmpty()) { 110 onHelp(); 111 return 0; 112 } 113 try { 114 switch (command) { 115 case COMMAND_SET_PHONE_ACCOUNT_ENABLED: 116 runSetPhoneAccountEnabled(true); 117 break; 118 case COMMAND_SET_PHONE_ACCOUNT_DISABLED: 119 runSetPhoneAccountEnabled(false); 120 break; 121 case COMMAND_REGISTER_PHONE_ACCOUNT: 122 runRegisterPhoneAccount(); 123 break; 124 case COMMAND_SET_TEST_CALL_REDIRECTION_APP: 125 runSetTestCallRedirectionApp(); 126 break; 127 case COMMAND_SET_TEST_CALL_SCREENING_APP: 128 runSetTestCallScreeningApp(); 129 break; 130 case COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP: 131 runAddOrRemoveCallCompanionApp(); 132 break; 133 case COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT: 134 runSetTestPhoneAcctSuggestionComponent(); 135 break; 136 case COMMAND_SET_CALL_DIAGNOSTIC_SERVICE: 137 runSetCallDiagnosticService(); 138 break; 139 case COMMAND_REGISTER_SIM_PHONE_ACCOUNT: 140 runRegisterSimPhoneAccount(); 141 break; 142 case COMMAND_SET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT: 143 runSetUserSelectedOutgoingPhoneAccount(); 144 break; 145 case COMMAND_UNREGISTER_PHONE_ACCOUNT: 146 runUnregisterPhoneAccount(); 147 break; 148 case COMMAND_STOP_BLOCK_SUPPRESSION: 149 runStopBlockSuppression(); 150 break; 151 case COMMAND_CLEANUP_STUCK_CALLS: 152 runCleanupStuckCalls(); 153 break; 154 case COMMAND_CLEANUP_ORPHAN_PHONE_ACCOUNTS: 155 runCleanupOrphanPhoneAccounts(); 156 break; 157 case COMMAND_RESET_CAR_MODE: 158 runResetCarMode(); 159 break; 160 case COMMAND_SET_DEFAULT_DIALER: 161 runSetDefaultDialer(); 162 break; 163 case COMMAND_GET_DEFAULT_DIALER: 164 runGetDefaultDialer(); 165 break; 166 case COMMAND_SET_SYSTEM_DIALER: 167 runSetSystemDialer(); 168 break; 169 case COMMAND_GET_SYSTEM_DIALER: 170 runGetSystemDialer(); 171 break; 172 case COMMAND_WAIT_ON_HANDLERS: 173 runWaitOnHandler(); 174 break; 175 case COMMAND_SET_SIM_COUNT: 176 runSetSimCount(); 177 break; 178 case COMMAND_GET_SIM_CONFIG: 179 runGetSimConfig(); 180 break; 181 case COMMAND_GET_MAX_PHONES: 182 runGetMaxPhones(); 183 break; 184 case COMMAND_IS_NON_IN_CALL_SERVICE_BOUND: 185 runIsNonUiInCallServiceBound(); 186 break; 187 case COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER: 188 runSetEmergencyPhoneAccountPackageFilter(); 189 break; 190 case COMMAND_LOG_MARK: 191 runLogMark(); 192 break; 193 case COMMAND_SET_METRICS_TEST_ENABLED: 194 mTelecomService.setMetricsTestMode(true); 195 break; 196 case COMMAND_SET_METRICS_TEST_DISABLED: 197 mTelecomService.setMetricsTestMode(false); 198 break; 199 case COMMAND_WAIT_FOR_AUDIO_OPS_COMPLETION: 200 mTelecomService.waitForAudioToUpdate(false); 201 break; 202 case COMMAND_WAIT_FOR_AUDIO_ACTIVE_COMPLETION: 203 mTelecomService.waitForAudioToUpdate(true); 204 break; 205 default: 206 return handleDefaultCommands(command); 207 } 208 } catch (Exception e) { 209 getErrPrintWriter().println("Command["+ command + "]: Error: " + e); 210 return -1; 211 } 212 return 0; 213 } 214 215 @Override onHelp()216 public void onHelp() { 217 getOutPrintWriter().println("usage: telecom [subcommand] [options]\n" 218 + "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" 219 + "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" 220 + "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" 221 + "usage: telecom register-sim-phone-account [-e] <COMPONENT> <ID> <USER_SN>" 222 + " <LABEL>: registers a PhoneAccount with CAPABILITY_SIM_SUBSCRIPTION" 223 + " and optionally CAPABILITY_PLACE_EMERGENCY_CALLS if \"-e\" is provided\n" 224 + "usage: telecom set-user-selected-outgoing-phone-account [-e] <COMPONENT> <ID> " 225 + "<USER_SN>\n" 226 + "usage: telecom set-test-call-redirection-app <PACKAGE>\n" 227 + "usage: telecom set-test-call-screening-app <PACKAGE>\n" 228 + "usage: telecom set-phone-acct-suggestion-component <COMPONENT>\n" 229 + "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n" 230 + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN>" 231 + " <LABEL> <ADDRESS>\n" 232 + "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n" 233 + "usage: telecom set-call-diagnostic-service <PACKAGE>\n" 234 + "usage: telecom set-default-dialer <PACKAGE>\n" 235 + "usage: telecom get-default-dialer\n" 236 + "usage: telecom get-system-dialer\n" 237 + "usage: telecom wait-on-handlers\n" 238 + "usage: telecom set-sim-count <COUNT>\n" 239 + "usage: telecom get-sim-config\n" 240 + "usage: telecom get-max-phones\n" 241 + "usage: telecom stop-block-suppression: Stop suppressing the blocked number" 242 + " provider after a call to emergency services.\n" 243 + "usage: telecom cleanup-stuck-calls: Clear any disconnected calls that have" 244 + " gotten wedged in Telecom.\n" 245 + "usage: telecom cleanup-orphan-phone-accounts: remove any phone accounts that" 246 + " no longer have a valid UserHandle or accounts that no longer belongs to an" 247 + " installed package.\n" 248 + "usage: telecom set-emer-phone-account-filter <PACKAGE>\n" 249 + "\n" 250 + "telecom set-phone-account-enabled: Enables the given phone account, if it has" 251 + " already been registered with Telecom.\n" 252 + "\n" 253 + "telecom set-phone-account-disabled: Disables the given phone account, if it" 254 + " has already been registered with telecom.\n" 255 + "\n" 256 + "telecom set-call-diagnostic-service: overrides call diagnostic service.\n" 257 + "telecom set-default-dialer: Sets the override default dialer to the given" 258 + " component; this will override whatever the dialer role is set to.\n" 259 + "\n" 260 + "telecom get-default-dialer: Displays the current default dialer.\n" 261 + "\n" 262 + "telecom get-system-dialer: Displays the current system dialer.\n" 263 + "telecom set-system-dialer: Set the override system dialer to the given" 264 + " component. To remove the override, send \"default\"\n" 265 + "\n" 266 + "telecom wait-on-handlers: Wait until all handlers finish their work.\n" 267 + "\n" 268 + "telecom set-sim-count: Set num SIMs (2 for DSDS, 1 for single SIM." 269 + " This may restart the device.\n" 270 + "\n" 271 + "telecom get-sim-config: Get the mSIM config string. \"DSDS\" for DSDS mode," 272 + " or \"\" for single SIM\n" 273 + "\n" 274 + "telecom get-max-phones: Get the max supported phones from the modem.\n" 275 + "telecom set-test-emergency-phone-account-package-filter <PACKAGE>: sets a" 276 + " package name that will be used for test emergency calls. To clear," 277 + " send an empty package name. Real emergency calls will still be placed" 278 + " over Telephony.\n" 279 + "telecom log-mark <MESSAGE>: emits a message into the telecom logs. Useful for " 280 + "testers to indicate where in the logs various test steps take place.\n" 281 + "telecom is-non-ui-in-call-service-bound <PACKAGE>: queries a particular " 282 + "non-ui-InCallService in InCallController to determine if it is bound \n" 283 + "telecom set-metrics-test-enabled: Enable the metrics test mode.\n" 284 + "telecom set-metrics-test-disabled: Disable the metrics test mode.\n" 285 ); 286 } runSetPhoneAccountEnabled(boolean enabled)287 private void runSetPhoneAccountEnabled(boolean enabled) throws RemoteException { 288 final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); 289 final boolean success = mTelecomService.enablePhoneAccount(handle, enabled); 290 if (success) { 291 getOutPrintWriter().println("Success - " + handle 292 + (enabled ? " enabled." : " disabled.")); 293 } else { 294 getOutPrintWriter().println("Error - is " + handle + " a valid PhoneAccount?"); 295 } 296 } 297 runRegisterPhoneAccount()298 private void runRegisterPhoneAccount() throws RemoteException { 299 final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); 300 final String label = getNextArgRequired(); 301 PhoneAccount account = PhoneAccount.builder(handle, label) 302 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build(); 303 mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE); 304 getOutPrintWriter().println("Success - " + handle + " registered."); 305 } 306 runRegisterSimPhoneAccount()307 private void runRegisterSimPhoneAccount() throws RemoteException { 308 boolean isEmergencyAccount = false; 309 String opt; 310 while ((opt = getNextOption()) != null) { 311 switch (opt) { 312 case "-e": { 313 isEmergencyAccount = true; 314 break; 315 } 316 } 317 } 318 final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); 319 final String label = getNextArgRequired(); 320 final String address = getNextArgRequired(); 321 int capabilities = PhoneAccount.CAPABILITY_CALL_PROVIDER 322 | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION 323 | (isEmergencyAccount ? PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS : 0); 324 PhoneAccount account = PhoneAccount.builder( 325 handle, label) 326 .setAddress(Uri.parse(address)) 327 .setSubscriptionAddress(Uri.parse(address)) 328 .setCapabilities(capabilities) 329 .setShortDescription(label) 330 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 331 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 332 .build(); 333 mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE); 334 getOutPrintWriter().println("Success - " + handle + " registered."); 335 } 336 runSetTestCallRedirectionApp()337 private void runSetTestCallRedirectionApp() throws RemoteException { 338 final String packageName = getNextArg(); 339 mTelecomService.setTestDefaultCallRedirectionApp(packageName); 340 } 341 runSetTestCallScreeningApp()342 private void runSetTestCallScreeningApp() throws RemoteException { 343 final String packageName = getNextArg(); 344 mTelecomService.setTestDefaultCallScreeningApp(packageName); 345 } 346 runAddOrRemoveCallCompanionApp()347 private void runAddOrRemoveCallCompanionApp() throws RemoteException { 348 final String packageName = getNextArgRequired(); 349 String isAdded = getNextArgRequired(); 350 boolean isAddedBool = "1".equals(isAdded); 351 mTelecomService.addOrRemoveTestCallCompanionApp(packageName, isAddedBool); 352 } 353 runSetCallDiagnosticService()354 private void runSetCallDiagnosticService() throws RemoteException { 355 String packageName = getNextArg(); 356 if ("default".equals(packageName)) packageName = null; 357 mTelecomService.setTestCallDiagnosticService(packageName); 358 getOutPrintWriter().println("Success - " + packageName 359 + " set as call diagnostic service."); 360 } 361 runSetTestPhoneAcctSuggestionComponent()362 private void runSetTestPhoneAcctSuggestionComponent() throws RemoteException { 363 final String componentName = getNextArg(); 364 final UserHandle userHandle = getUserHandleFromArgs(); 365 mTelecomService.setTestPhoneAcctSuggestionComponent(componentName, userHandle); 366 } 367 runSetUserSelectedOutgoingPhoneAccount()368 private void runSetUserSelectedOutgoingPhoneAccount() throws RemoteException { 369 Log.i(this, "runSetUserSelectedOutgoingPhoneAccount"); 370 final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); 371 mTelecomService.setUserSelectedOutgoingPhoneAccount(handle); 372 getOutPrintWriter().println("Success - " + handle + " set as default outgoing account."); 373 } 374 runUnregisterPhoneAccount()375 private void runUnregisterPhoneAccount() throws RemoteException { 376 final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); 377 mTelecomService.unregisterPhoneAccount(handle, CALLING_PACKAGE); 378 getOutPrintWriter().println("Success - " + handle + " unregistered."); 379 } 380 runStopBlockSuppression()381 private void runStopBlockSuppression() throws RemoteException { 382 mTelecomService.stopBlockSuppression(); 383 } 384 runCleanupStuckCalls()385 private void runCleanupStuckCalls() throws RemoteException { 386 mTelecomService.cleanupStuckCalls(); 387 } 388 runCleanupOrphanPhoneAccounts()389 private void runCleanupOrphanPhoneAccounts() throws RemoteException { 390 getOutPrintWriter().println("Success - cleaned up " 391 + mTelecomService.cleanupOrphanPhoneAccounts() 392 + " phone accounts."); 393 } 394 runResetCarMode()395 private void runResetCarMode() throws RemoteException { 396 mTelecomService.resetCarMode(); 397 } 398 runSetDefaultDialer()399 private void runSetDefaultDialer() throws RemoteException { 400 String packageName = getNextArg(); 401 if ("default".equals(packageName)) packageName = null; 402 mTelecomService.setTestDefaultDialer(packageName); 403 getOutPrintWriter().println("Success - " + packageName 404 + " set as override default dialer."); 405 } 406 runSetSystemDialer()407 private void runSetSystemDialer() throws RemoteException { 408 final String flatComponentName = getNextArg(); 409 final ComponentName componentName = (flatComponentName.equals("default") 410 ? null : parseComponentName(flatComponentName)); 411 mTelecomService.setSystemDialer(componentName); 412 getOutPrintWriter().println("Success - " + componentName + " set as override system dialer."); 413 } 414 runGetDefaultDialer()415 private void runGetDefaultDialer() throws RemoteException { 416 getOutPrintWriter().println(mTelecomService.getDefaultDialerPackage(CALLING_PACKAGE)); 417 } 418 runGetSystemDialer()419 private void runGetSystemDialer() throws RemoteException { 420 getOutPrintWriter().println(mTelecomService.getSystemDialerPackage(CALLING_PACKAGE)); 421 } 422 runWaitOnHandler()423 private void runWaitOnHandler() throws RemoteException { 424 425 } 426 runSetSimCount()427 private void runSetSimCount() throws RemoteException { 428 if (!callerIsRoot()) { 429 getOutPrintWriter().println("set-sim-count requires adb root"); 430 return; 431 } 432 int numSims = Integer.parseInt(getNextArgRequired()); 433 getOutPrintWriter().println("Setting sim count to " + numSims + ". Device may reboot"); 434 getTelephonyManager().switchMultiSimConfig(numSims); 435 } 436 437 /** 438 * prints out whether a particular non-ui InCallServices is bound in a call 439 */ runIsNonUiInCallServiceBound()440 public void runIsNonUiInCallServiceBound() throws RemoteException { 441 if (TextUtils.isEmpty(peekNextArg())) { 442 getOutPrintWriter().println("No Argument passed. Please pass a <PACKAGE_NAME> to " 443 + "lookup."); 444 } else { 445 getOutPrintWriter().println( 446 String.valueOf(mTelecomService.isNonUiInCallServiceBound(getNextArg()))); 447 } 448 } 449 450 /** 451 * Prints the mSIM config to the console. 452 * "DSDS" for a phone in DSDS mode 453 * "" (empty string) for a phone in SS mode 454 */ runGetSimConfig()455 private void runGetSimConfig() throws RemoteException { 456 getOutPrintWriter().println(TelephonyProperties.multi_sim_config().orElse("")); 457 } 458 runGetMaxPhones()459 private void runGetMaxPhones() throws RemoteException { 460 // how many logical modems can be potentially active simultaneously 461 getOutPrintWriter().println(getTelephonyManager().getSupportedModemCount()); 462 } 463 runSetEmergencyPhoneAccountPackageFilter()464 private void runSetEmergencyPhoneAccountPackageFilter() throws RemoteException { 465 String packageName = getNextArg(); 466 if (TextUtils.isEmpty(packageName)) { 467 mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(null); 468 getOutPrintWriter().println("Success - filter cleared"); 469 } else { 470 mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(packageName); 471 getOutPrintWriter().println("Success = filter set to " + packageName); 472 } 473 474 } 475 runLogMark()476 private void runLogMark() throws RemoteException { 477 String message = Arrays.stream(peekRemainingArgs()).collect(Collectors.joining(" ")); 478 mTelecomService.requestLogMark(message); 479 } 480 getUserHandleFromArgs()481 private UserHandle getUserHandleFromArgs() throws RemoteException { 482 if (TextUtils.isEmpty(peekNextArg())) { 483 return null; 484 } 485 final String userSnInStr = getNextArgRequired(); 486 UserHandle userHandle; 487 try { 488 final int userSn = Integer.parseInt(userSnInStr); 489 userHandle = UserHandle.of(getUserManager().getUserHandle(userSn)); 490 } catch (NumberFormatException ex) { 491 Log.w(this, "getPhoneAccountHandleFromArgs - invalid user %s", userSnInStr); 492 throw new IllegalArgumentException ("Invalid user serial number " + userSnInStr); 493 } 494 return userHandle; 495 } 496 getPhoneAccountHandleFromArgs()497 private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException { 498 if (TextUtils.isEmpty(peekNextArg())) { 499 return null; 500 } 501 final ComponentName component = parseComponentName(getNextArgRequired()); 502 final String accountId = getNextArgRequired(); 503 final String userSnInStr = getNextArgRequired(); 504 UserHandle userHandle; 505 try { 506 final int userSn = Integer.parseInt(userSnInStr); 507 userHandle = UserHandle.of(getUserManager().getUserHandle(userSn)); 508 } catch (NumberFormatException ex) { 509 Log.w(this, "getPhoneAccountHandleFromArgs - invalid user %s", userSnInStr); 510 throw new IllegalArgumentException ("Invalid user serial number " + userSnInStr); 511 } 512 return new PhoneAccountHandle(component, accountId, userHandle); 513 } 514 callerIsRoot()515 private boolean callerIsRoot() { 516 return Process.ROOT_UID == Process.myUid(); 517 } 518 parseComponentName(String component)519 private ComponentName parseComponentName(String component) { 520 ComponentName cn = ComponentName.unflattenFromString(component); 521 if (cn == null) { 522 throw new IllegalArgumentException ("Invalid component " + component); 523 } 524 return cn; 525 } 526 getTelephonyManager()527 private TelephonyManager getTelephonyManager() throws IllegalStateException { 528 if (mTelephonyManager == null) { 529 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 530 } 531 if (mTelephonyManager == null) { 532 Log.w(this, "getTelephonyManager: Can't access telephony service."); 533 throw new IllegalStateException("Could not access the Telephony Service. Is the system " 534 + "running?"); 535 } 536 return mTelephonyManager; 537 } 538 getUserManager()539 private UserManager getUserManager() throws IllegalStateException { 540 if (mUserManager == null) { 541 mUserManager = mContext.getSystemService(UserManager.class); 542 } 543 if (mUserManager == null) { 544 Log.w(this, "getUserManager: Can't access UserManager service."); 545 throw new IllegalStateException("Could not access the UserManager Service. Is the " 546 + "system running?"); 547 } 548 return mUserManager; 549 } 550 } 551