• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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