summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yohei Yukawa <yukawa@google.com> 2019-04-10 23:20:51 -0700
committer Yohei Yukawa <yukawa@google.com> 2019-04-10 23:20:51 -0700
commite177170f6432631d54788a37f4fb468a02468ed0 (patch)
tree8dec6b0d13857e828c99d95dddacd632553ac59a
parentce1acbc526056d736937fd1d67c0e02397442cb7 (diff)
Add '-u <user id>' option to 'adb shell ime enable'
This is a preparation to add end-to-end CTS for per-profile IME mode. In order to allow CTS tests to enable/disable IMEs via shell command in multi-user environment, this CL adds '-u <user id>' option to adb shell ime enable <ime id> and adb shell ime disable <ime id> Note that '-u' option is already supposed in 'adb shell ime list' [1]. [1]: I192a0f5a1375170d17a4c08af94f23966dbaea8b 7f8ee4b9ddd31ad36a12c5278b27990dc76011cc Bug: 122924287 Test: Manually tested as follows: 1. Build aosp_blueline-userdebug and flash it 2. make -j SoftKeyboard 3. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk 4. adb shell pm create-user test 5. adb shell am switch-user 10 6. adb shell ime enable -u 0 com.example.android.softkeyboard/.SoftKeyboard -> Input method com.example.android.softkeyboard/.SoftKeyboard: now enabled for user #0 7. adb shell ime disable -u 0 com.example.android.softkeyboard/.SoftKeyboard -> Input method com.example.android.softkeyboard/.SoftKeyboard: now disabled for user #0 Test: Manually tested as follows. 1. Build aosp_blueline-userdebug and flash it 2. adb shell pm create-user test 3. adb shell pm create-user restricted_test 4. adb root 5. adb shell pm set-user-restriction --user 11 no_debugging_features 1 6. adb shell am switch-user 10 7. adb shell am switch-user 11 8. adb shell am switch-user 0 9. adb shell ime disable -u all com.android.inputmethod.latin/.LatinIME -> Input method com.android.inputmethod.latin/.LatinIME: now disabled for user #0 Input method com.android.inputmethod.latin/.LatinIME: now disabled for user #10 User #11 is restricted with DISALLOW_DEBUGGING_FEATURES. Change-Id: Ia0f873e4589a9fc3f549469e3d1d966640dc2df5
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java126
1 files changed, 105 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d360a6362464..6d0796ab28a6 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4589,14 +4589,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
pw.decreaseIndent();
pw.decreaseIndent();
- pw.println("enable <ID>");
+ pw.println("enable [--user <USER_ID>] <ID>");
pw.increaseIndent();
pw.println("allows the given input method ID to be used.");
+ pw.increaseIndent();
+ pw.print("--user <USER_ID>: Specify which user to enable.");
+ pw.println(" Assumes the current user if not specified.");
+ pw.decreaseIndent();
pw.decreaseIndent();
- pw.println("disable <ID>");
+ pw.println("disable [--user <USER_ID>] <ID>");
pw.increaseIndent();
pw.println("disallows the given input method ID to be used.");
+ pw.increaseIndent();
+ pw.print("--user <USER_ID>: Specify which user to disable.");
+ pw.println(" Assumes the current user if not specified.");
+ pw.decreaseIndent();
pw.decreaseIndent();
pw.println("set <ID>");
@@ -4693,32 +4701,108 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@ShellCommandResult
private int handleShellCommandEnableDisableInputMethod(
@NonNull ShellCommand shellCommand, boolean enabled) {
- final String id = shellCommand.getNextArgRequired();
- final boolean previouslyEnabled;
+ final String imeId = shellCommand.getNextArgRequired();
+ final PrintWriter out = shellCommand.getOutPrintWriter();
+ final PrintWriter error = shellCommand.getErrPrintWriter();
+ final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
synchronized (mMethodMap) {
- if (!userHasDebugPriv(mSettings.getCurrentUserId(), shellCommand)) {
- return ShellCommandResult.SUCCESS;
- }
- // Make sure this is a valid input method.
- if (enabled && !mMethodMap.containsKey(id)) {
- final PrintWriter error = shellCommand.getErrPrintWriter();
- error.print("Unknown input method ");
- error.print(id);
- error.println(" cannot be enabled");
- return ShellCommandResult.SUCCESS;
+ final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+ mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+ for (int userId : userIds) {
+ if (!userHasDebugPriv(userId, shellCommand)) {
+ continue;
+ }
+ handleShellCommandEnableDisableInputMethodInternalLocked(userId, imeId, enabled,
+ out, error);
}
- previouslyEnabled = setInputMethodEnabledLocked(id, enabled);
}
- final PrintWriter pr = shellCommand.getOutPrintWriter();
- pr.print("Input method ");
- pr.print(id);
- pr.print(": ");
- pr.print((enabled == previouslyEnabled) ? "already " : "now ");
- pr.println(enabled ? "enabled" : "disabled");
return ShellCommandResult.SUCCESS;
}
/**
+ * A special helper method for commands that only have {@code -u} and {@code --user} options.
+ *
+ * <p>You cannot use this helper method if the command has other options.</p>
+ *
+ * @param shellCommand {@link ShellCommand} from which options should be obtained.
+ * @return User ID to be resolved. {@link UserHandle#CURRENT} if not specified.
+ */
+ @BinderThread
+ @UserIdInt
+ private static int handleOptionsForCommandsThatOnlyHaveUserOption(ShellCommand shellCommand) {
+ while (true) {
+ final String nextOption = shellCommand.getNextOption();
+ if (nextOption == null) {
+ break;
+ }
+ switch (nextOption) {
+ case "-u":
+ case "--user":
+ return UserHandle.parseUserArg(shellCommand.getNextArgRequired());
+ }
+ }
+ return UserHandle.USER_CURRENT;
+ }
+
+ @BinderThread
+ private void handleShellCommandEnableDisableInputMethodInternalLocked(
+ @UserIdInt int userId, String imeId, boolean enabled, PrintWriter out,
+ PrintWriter error) {
+ boolean failedToEnableUnknownIme = false;
+ boolean previouslyEnabled = false;
+ if (userId == mSettings.getCurrentUserId()) {
+ if (enabled && !mMethodMap.containsKey(imeId)) {
+ failedToEnableUnknownIme = true;
+ } else {
+ previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled);
+ }
+ } else {
+ final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+ final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
+ final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
+ new ArrayMap<>();
+ AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
+ queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
+ methodMap, methodList);
+ final InputMethodSettings settings = new InputMethodSettings(mContext.getResources(),
+ mContext.getContentResolver(), methodMap, userId, false);
+ if (enabled) {
+ if (!methodMap.containsKey(imeId)) {
+ failedToEnableUnknownIme = true;
+ } else {
+ for (InputMethodInfo imi : settings.getEnabledInputMethodListLocked()) {
+ if (TextUtils.equals(imi.getId(), imeId)) {
+ previouslyEnabled = true;
+ break;
+ }
+ }
+ if (!previouslyEnabled) {
+ settings.appendAndPutEnabledInputMethodLocked(imeId, false);
+ }
+ }
+ } else {
+ previouslyEnabled =
+ settings.buildAndPutEnabledInputMethodsStrRemovingIdLocked(
+ new StringBuilder(),
+ settings.getEnabledInputMethodsAndSubtypeListLocked(), imeId);
+ }
+ }
+ if (failedToEnableUnknownIme) {
+ error.print("Unknown input method ");
+ error.print(imeId);
+ error.println(" cannot be enabled for user #" + userId);
+ } else {
+ out.print("Input method ");
+ out.print(imeId);
+ out.print(": ");
+ out.print((enabled == previouslyEnabled) ? "already " : "now ");
+ out.print(enabled ? "enabled" : "disabled");
+ out.print(" for user #");
+ out.println(userId);
+ }
+ }
+
+ /**
* Handles {@code adb shell ime set}.
* @param shellCommand {@link ShellCommand} object that is handling this command.
* @return Exit code of the command.