Merge "Move Telecom shell commands to TelecomShellCommand" into main
diff --git a/Android.bp b/Android.bp
index 68a8e39..94654a6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -11,6 +11,14 @@
out: ["com/android/server/telecom/TelecomStatsLog.java"],
}
+filegroup {
+ name: "telecom-shell-commands-src",
+ srcs: [
+ "src/com/android/server/telecom/TelecomShellCommand.java",
+ ],
+ path: "src",
+}
+
android_library {
name: "TelecomLib",
manifest: "AndroidManifestLib.xml",
@@ -33,7 +41,6 @@
platform_apis: true,
}
-
// Build the Telecom service.
android_app {
name: "Telecom",
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index f3d91f1..780db19 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -53,8 +53,11 @@
import android.os.Build;
import android.os.Bundle;
import android.os.OutcomeReceiver;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
import android.os.UserHandle;
import android.provider.BlockedNumberContract;
import android.provider.Settings;
@@ -72,12 +75,14 @@
import android.util.EventLog;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telecom.ICallControl;
import com.android.internal.telecom.ICallEventCallback;
import com.android.internal.telecom.ITelecomService;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.modules.utils.BasicShellCommandHandler;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.flags.FeatureFlags;
import com.android.server.telecom.settings.BlockedNumbersActivity;
@@ -2092,6 +2097,14 @@
}
}
+ @Override
+ public int handleShellCommand(@NonNull ParcelFileDescriptor in,
+ @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
+ @NonNull String[] args) {
+ return new TelecomShellCommand(this, mContext).exec(this,
+ in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args);
+ }
+
/**
* Print all feature flag configurations that Telecom is using for debugging purposes.
*/
diff --git a/src/com/android/server/telecom/TelecomShellCommand.java b/src/com/android/server/telecom/TelecomShellCommand.java
new file mode 100644
index 0000000..557002c
--- /dev/null
+++ b/src/com/android/server/telecom/TelecomShellCommand.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.sysprop.TelephonyProperties;
+import android.telecom.Log;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.telecom.ITelecomService;
+import com.android.modules.utils.BasicShellCommandHandler;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * Implements shell commands sent to telecom using the "adb shell cmd telecom..." command from shell
+ * or CTS.
+ */
+public class TelecomShellCommand extends BasicShellCommandHandler {
+ private static final String CALLING_PACKAGE = TelecomShellCommand.class.getPackageName();
+ private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled";
+ private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
+ private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
+ private static final String COMMAND_SET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT =
+ "set-user-selected-outgoing-phone-account";
+ private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account";
+ private static final String COMMAND_SET_TEST_CALL_REDIRECTION_APP =
+ "set-test-call-redirection-app";
+ private static final String COMMAND_SET_TEST_CALL_SCREENING_APP = "set-test-call-screening-app";
+ private static final String COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP =
+ "add-or-remove-call-companion-app";
+ private static final String COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT =
+ "set-phone-acct-suggestion-component";
+ private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account";
+ private static final String COMMAND_SET_CALL_DIAGNOSTIC_SERVICE = "set-call-diagnostic-service";
+ private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer";
+ private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer";
+ private static final String COMMAND_STOP_BLOCK_SUPPRESSION = "stop-block-suppression";
+ private static final String COMMAND_CLEANUP_STUCK_CALLS = "cleanup-stuck-calls";
+ private static final String COMMAND_CLEANUP_ORPHAN_PHONE_ACCOUNTS =
+ "cleanup-orphan-phone-accounts";
+ private static final String COMMAND_RESET_CAR_MODE = "reset-car-mode";
+ private static final String COMMAND_IS_NON_IN_CALL_SERVICE_BOUND =
+ "is-non-ui-in-call-service-bound";
+
+ /**
+ * Change the system dialer package name if a package name was specified,
+ * Example: adb shell telecom set-system-dialer <PACKAGE>
+ *
+ * Restore it to the default if if argument is "default" or no argument is passed.
+ * Example: adb shell telecom set-system-dialer default
+ */
+ private static final String COMMAND_SET_SYSTEM_DIALER = "set-system-dialer";
+ private static final String COMMAND_GET_SYSTEM_DIALER = "get-system-dialer";
+ private static final String COMMAND_WAIT_ON_HANDLERS = "wait-on-handlers";
+ private static final String COMMAND_SET_SIM_COUNT = "set-sim-count";
+ private static final String COMMAND_GET_SIM_CONFIG = "get-sim-config";
+ private static final String COMMAND_GET_MAX_PHONES = "get-max-phones";
+ private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER =
+ "set-test-emergency-phone-account-package-filter";
+ /**
+ * Command used to emit a distinct "mark" in the logs.
+ */
+ private static final String COMMAND_LOG_MARK = "log-mark";
+
+ private final Context mContext;
+ private final ITelecomService mTelecomService;
+ private TelephonyManager mTelephonyManager;
+ private UserManager mUserManager;
+
+ public TelecomShellCommand(ITelecomService binder, Context context) {
+ mTelecomService = binder;
+ mContext = context;
+ }
+
+ @Override
+ public int onCommand(String command) {
+ if (command == null || command.isEmpty()) {
+ onHelp();
+ return 0;
+ }
+ try {
+ switch (command) {
+ case COMMAND_SET_PHONE_ACCOUNT_ENABLED:
+ runSetPhoneAccountEnabled(true);
+ break;
+ case COMMAND_SET_PHONE_ACCOUNT_DISABLED:
+ runSetPhoneAccountEnabled(false);
+ break;
+ case COMMAND_REGISTER_PHONE_ACCOUNT:
+ runRegisterPhoneAccount();
+ break;
+ case COMMAND_SET_TEST_CALL_REDIRECTION_APP:
+ runSetTestCallRedirectionApp();
+ break;
+ case COMMAND_SET_TEST_CALL_SCREENING_APP:
+ runSetTestCallScreeningApp();
+ break;
+ case COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP:
+ runAddOrRemoveCallCompanionApp();
+ break;
+ case COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT:
+ runSetTestPhoneAcctSuggestionComponent();
+ break;
+ case COMMAND_SET_CALL_DIAGNOSTIC_SERVICE:
+ runSetCallDiagnosticService();
+ break;
+ case COMMAND_REGISTER_SIM_PHONE_ACCOUNT:
+ runRegisterSimPhoneAccount();
+ break;
+ case COMMAND_SET_USER_SELECTED_OUTGOING_PHONE_ACCOUNT:
+ runSetUserSelectedOutgoingPhoneAccount();
+ break;
+ case COMMAND_UNREGISTER_PHONE_ACCOUNT:
+ runUnregisterPhoneAccount();
+ break;
+ case COMMAND_STOP_BLOCK_SUPPRESSION:
+ runStopBlockSuppression();
+ break;
+ case COMMAND_CLEANUP_STUCK_CALLS:
+ runCleanupStuckCalls();
+ break;
+ case COMMAND_CLEANUP_ORPHAN_PHONE_ACCOUNTS:
+ runCleanupOrphanPhoneAccounts();
+ break;
+ case COMMAND_RESET_CAR_MODE:
+ runResetCarMode();
+ break;
+ case COMMAND_SET_DEFAULT_DIALER:
+ runSetDefaultDialer();
+ break;
+ case COMMAND_GET_DEFAULT_DIALER:
+ runGetDefaultDialer();
+ break;
+ case COMMAND_SET_SYSTEM_DIALER:
+ runSetSystemDialer();
+ break;
+ case COMMAND_GET_SYSTEM_DIALER:
+ runGetSystemDialer();
+ break;
+ case COMMAND_WAIT_ON_HANDLERS:
+ runWaitOnHandler();
+ break;
+ case COMMAND_SET_SIM_COUNT:
+ runSetSimCount();
+ break;
+ case COMMAND_GET_SIM_CONFIG:
+ runGetSimConfig();
+ break;
+ case COMMAND_GET_MAX_PHONES:
+ runGetMaxPhones();
+ break;
+ case COMMAND_IS_NON_IN_CALL_SERVICE_BOUND:
+ runIsNonUiInCallServiceBound();
+ break;
+ case COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER:
+ runSetEmergencyPhoneAccountPackageFilter();
+ break;
+ case COMMAND_LOG_MARK:
+ runLogMark();
+ break;
+ default:
+ return handleDefaultCommands(command);
+ }
+ } catch (Exception e) {
+ getErrPrintWriter().println("Command["+ command + "]: Error: " + e);
+ return -1;
+ }
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ getOutPrintWriter().println("usage: telecom [subcommand] [options]\n"
+ + "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n"
+ + "usage: telecom register-sim-phone-account [-e] <COMPONENT> <ID> <USER_SN>"
+ + " <LABEL>: registers a PhoneAccount with CAPABILITY_SIM_SUBSCRIPTION"
+ + " and optionally CAPABILITY_PLACE_EMERGENCY_CALLS if \"-e\" is provided\n"
+ + "usage: telecom set-user-selected-outgoing-phone-account [-e] <COMPONENT> <ID> "
+ + "<USER_SN>\n"
+ + "usage: telecom set-test-call-redirection-app <PACKAGE>\n"
+ + "usage: telecom set-test-call-screening-app <PACKAGE>\n"
+ + "usage: telecom set-phone-acct-suggestion-component <COMPONENT>\n"
+ + "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n"
+ + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN>"
+ + " <LABEL> <ADDRESS>\n"
+ + "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom set-call-diagnostic-service <PACKAGE>\n"
+ + "usage: telecom set-default-dialer <PACKAGE>\n"
+ + "usage: telecom get-default-dialer\n"
+ + "usage: telecom get-system-dialer\n"
+ + "usage: telecom wait-on-handlers\n"
+ + "usage: telecom set-sim-count <COUNT>\n"
+ + "usage: telecom get-sim-config\n"
+ + "usage: telecom get-max-phones\n"
+ + "usage: telecom stop-block-suppression: Stop suppressing the blocked number"
+ + " provider after a call to emergency services.\n"
+ + "usage: telecom cleanup-stuck-calls: Clear any disconnected calls that have"
+ + " gotten wedged in Telecom.\n"
+ + "usage: telecom cleanup-orphan-phone-accounts: remove any phone accounts that"
+ + " no longer have a valid UserHandle or accounts that no longer belongs to an"
+ + " installed package.\n"
+ + "usage: telecom set-emer-phone-account-filter <PACKAGE>\n"
+ + "\n"
+ + "telecom set-phone-account-enabled: Enables the given phone account, if it has"
+ + " already been registered with Telecom.\n"
+ + "\n"
+ + "telecom set-phone-account-disabled: Disables the given phone account, if it"
+ + " has already been registered with telecom.\n"
+ + "\n"
+ + "telecom set-call-diagnostic-service: overrides call diagnostic service.\n"
+ + "telecom set-default-dialer: Sets the override default dialer to the given"
+ + " component; this will override whatever the dialer role is set to.\n"
+ + "\n"
+ + "telecom get-default-dialer: Displays the current default dialer.\n"
+ + "\n"
+ + "telecom get-system-dialer: Displays the current system dialer.\n"
+ + "telecom set-system-dialer: Set the override system dialer to the given"
+ + " component. To remove the override, send \"default\"\n"
+ + "\n"
+ + "telecom wait-on-handlers: Wait until all handlers finish their work.\n"
+ + "\n"
+ + "telecom set-sim-count: Set num SIMs (2 for DSDS, 1 for single SIM."
+ + " This may restart the device.\n"
+ + "\n"
+ + "telecom get-sim-config: Get the mSIM config string. \"DSDS\" for DSDS mode,"
+ + " or \"\" for single SIM\n"
+ + "\n"
+ + "telecom get-max-phones: Get the max supported phones from the modem.\n"
+ + "telecom set-test-emergency-phone-account-package-filter <PACKAGE>: sets a"
+ + " package name that will be used for test emergency calls. To clear,"
+ + " send an empty package name. Real emergency calls will still be placed"
+ + " over Telephony.\n"
+ + "telecom log-mark <MESSAGE>: emits a message into the telecom logs. Useful for "
+ + "testers to indicate where in the logs various test steps take place.\n"
+ + "telecom is-non-ui-in-call-service-bound <PACKAGE>: queries a particular "
+ + "non-ui-InCallService in InCallController to determine if it is bound \n"
+ );
+ }
+ private void runSetPhoneAccountEnabled(boolean enabled) throws RemoteException {
+ final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
+ final boolean success = mTelecomService.enablePhoneAccount(handle, enabled);
+ if (success) {
+ getOutPrintWriter().println("Success - " + handle
+ + (enabled ? " enabled." : " disabled."));
+ } else {
+ getOutPrintWriter().println("Error - is " + handle + " a valid PhoneAccount?");
+ }
+ }
+
+ private void runRegisterPhoneAccount() throws RemoteException {
+ final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
+ final String label = getNextArgRequired();
+ PhoneAccount account = PhoneAccount.builder(handle, label)
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
+ getOutPrintWriter().println("Success - " + handle + " registered.");
+ }
+
+ private void runRegisterSimPhoneAccount() throws RemoteException {
+ boolean isEmergencyAccount = false;
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-e": {
+ isEmergencyAccount = true;
+ break;
+ }
+ }
+ }
+ final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
+ final String label = getNextArgRequired();
+ final String address = getNextArgRequired();
+ int capabilities = PhoneAccount.CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
+ | (isEmergencyAccount ? PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS : 0);
+ PhoneAccount account = PhoneAccount.builder(
+ handle, label)
+ .setAddress(Uri.parse(address))
+ .setSubscriptionAddress(Uri.parse(address))
+ .setCapabilities(capabilities)
+ .setShortDescription(label)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
+ .build();
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
+ getOutPrintWriter().println("Success - " + handle + " registered.");
+ }
+
+ private void runSetTestCallRedirectionApp() throws RemoteException {
+ final String packageName = getNextArg();
+ mTelecomService.setTestDefaultCallRedirectionApp(packageName);
+ }
+
+ private void runSetTestCallScreeningApp() throws RemoteException {
+ final String packageName = getNextArg();
+ mTelecomService.setTestDefaultCallScreeningApp(packageName);
+ }
+
+ private void runAddOrRemoveCallCompanionApp() throws RemoteException {
+ final String packageName = getNextArgRequired();
+ String isAdded = getNextArgRequired();
+ boolean isAddedBool = "1".equals(isAdded);
+ mTelecomService.addOrRemoveTestCallCompanionApp(packageName, isAddedBool);
+ }
+
+ private void runSetCallDiagnosticService() throws RemoteException {
+ String packageName = getNextArg();
+ if ("default".equals(packageName)) packageName = null;
+ mTelecomService.setTestCallDiagnosticService(packageName);
+ getOutPrintWriter().println("Success - " + packageName
+ + " set as call diagnostic service.");
+ }
+
+ private void runSetTestPhoneAcctSuggestionComponent() throws RemoteException {
+ final String componentName = getNextArg();
+ mTelecomService.setTestPhoneAcctSuggestionComponent(componentName);
+ }
+
+ private void runSetUserSelectedOutgoingPhoneAccount() throws RemoteException {
+ Log.i(this, "runSetUserSelectedOutgoingPhoneAccount");
+ final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
+ mTelecomService.setUserSelectedOutgoingPhoneAccount(handle);
+ getOutPrintWriter().println("Success - " + handle + " set as default outgoing account.");
+ }
+
+ private void runUnregisterPhoneAccount() throws RemoteException {
+ final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
+ mTelecomService.unregisterPhoneAccount(handle, CALLING_PACKAGE);
+ getOutPrintWriter().println("Success - " + handle + " unregistered.");
+ }
+
+ private void runStopBlockSuppression() throws RemoteException {
+ mTelecomService.stopBlockSuppression();
+ }
+
+ private void runCleanupStuckCalls() throws RemoteException {
+ mTelecomService.cleanupStuckCalls();
+ }
+
+ private void runCleanupOrphanPhoneAccounts() throws RemoteException {
+ getOutPrintWriter().println("Success - cleaned up "
+ + mTelecomService.cleanupOrphanPhoneAccounts()
+ + " phone accounts.");
+ }
+
+ private void runResetCarMode() throws RemoteException {
+ mTelecomService.resetCarMode();
+ }
+
+ private void runSetDefaultDialer() throws RemoteException {
+ String packageName = getNextArg();
+ if ("default".equals(packageName)) packageName = null;
+ mTelecomService.setTestDefaultDialer(packageName);
+ getOutPrintWriter().println("Success - " + packageName
+ + " set as override default dialer.");
+ }
+
+ private void runSetSystemDialer() throws RemoteException {
+ final String flatComponentName = getNextArg();
+ final ComponentName componentName = (flatComponentName.equals("default")
+ ? null : parseComponentName(flatComponentName));
+ mTelecomService.setSystemDialer(componentName);
+ getOutPrintWriter().println("Success - " + componentName + " set as override system dialer.");
+ }
+
+ private void runGetDefaultDialer() throws RemoteException {
+ getOutPrintWriter().println(mTelecomService.getDefaultDialerPackage(CALLING_PACKAGE));
+ }
+
+ private void runGetSystemDialer() throws RemoteException {
+ getOutPrintWriter().println(mTelecomService.getSystemDialerPackage(CALLING_PACKAGE));
+ }
+
+ private void runWaitOnHandler() throws RemoteException {
+
+ }
+
+ private void runSetSimCount() throws RemoteException {
+ if (!callerIsRoot()) {
+ getOutPrintWriter().println("set-sim-count requires adb root");
+ return;
+ }
+ int numSims = Integer.parseInt(getNextArgRequired());
+ getOutPrintWriter().println("Setting sim count to " + numSims + ". Device may reboot");
+ getTelephonyManager().switchMultiSimConfig(numSims);
+ }
+
+ /**
+ * prints out whether a particular non-ui InCallServices is bound in a call
+ */
+ public void runIsNonUiInCallServiceBound() throws RemoteException {
+ if (TextUtils.isEmpty(peekNextArg())) {
+ getOutPrintWriter().println("No Argument passed. Please pass a <PACKAGE_NAME> to "
+ + "lookup.");
+ } else {
+ getOutPrintWriter().println(
+ String.valueOf(mTelecomService.isNonUiInCallServiceBound(getNextArg())));
+ }
+ }
+
+ /**
+ * Prints the mSIM config to the console.
+ * "DSDS" for a phone in DSDS mode
+ * "" (empty string) for a phone in SS mode
+ */
+ private void runGetSimConfig() throws RemoteException {
+ getOutPrintWriter().println(TelephonyProperties.multi_sim_config().orElse(""));
+ }
+
+ private void runGetMaxPhones() throws RemoteException {
+ // how many logical modems can be potentially active simultaneously
+ getOutPrintWriter().println(getTelephonyManager().getSupportedModemCount());
+ }
+
+ private void runSetEmergencyPhoneAccountPackageFilter() throws RemoteException {
+ String packageName = getNextArg();
+ if (TextUtils.isEmpty(packageName)) {
+ mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(null);
+ getOutPrintWriter().println("Success - filter cleared");
+ } else {
+ mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(packageName);
+ getOutPrintWriter().println("Success = filter set to " + packageName);
+ }
+
+ }
+
+ private void runLogMark() throws RemoteException {
+ String message = Arrays.stream(peekRemainingArgs()).collect(Collectors.joining(" "));
+ mTelecomService.requestLogMark(message);
+ }
+
+ private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException {
+ if (TextUtils.isEmpty(peekNextArg())) {
+ return null;
+ }
+ final ComponentName component = parseComponentName(getNextArgRequired());
+ final String accountId = getNextArgRequired();
+ final String userSnInStr = getNextArgRequired();
+ UserHandle userHandle;
+ try {
+ final int userSn = Integer.parseInt(userSnInStr);
+ userHandle = UserHandle.of(getUserManager().getUserHandle(userSn));
+ } catch (NumberFormatException ex) {
+ Log.w(this, "getPhoneAccountHandleFromArgs - invalid user %s", userSnInStr);
+ throw new IllegalArgumentException ("Invalid user serial number " + userSnInStr);
+ }
+ return new PhoneAccountHandle(component, accountId, userHandle);
+ }
+
+ private boolean callerIsRoot() {
+ return Process.ROOT_UID == Process.myUid();
+ }
+
+ private ComponentName parseComponentName(String component) {
+ ComponentName cn = ComponentName.unflattenFromString(component);
+ if (cn == null) {
+ throw new IllegalArgumentException ("Invalid component " + component);
+ }
+ return cn;
+ }
+
+ private TelephonyManager getTelephonyManager() throws IllegalStateException {
+ if (mTelephonyManager == null) {
+ mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+ }
+ if (mTelephonyManager == null) {
+ Log.w(this, "getTelephonyManager: Can't access telephony service.");
+ throw new IllegalStateException("Could not access the Telephony Service. Is the system "
+ + "running?");
+ }
+ return mTelephonyManager;
+ }
+
+ private UserManager getUserManager() throws IllegalStateException {
+ if (mUserManager == null) {
+ mUserManager = mContext.getSystemService(UserManager.class);
+ }
+ if (mUserManager == null) {
+ Log.w(this, "getUserManager: Can't access UserManager service.");
+ throw new IllegalStateException("Could not access the UserManager Service. Is the "
+ + "system running?");
+ }
+ return mUserManager;
+ }
+}