diff options
| author | 2019-04-10 23:20:51 -0700 | |
|---|---|---|
| committer | 2019-04-10 23:20:51 -0700 | |
| commit | e177170f6432631d54788a37f4fb468a02468ed0 (patch) | |
| tree | 8dec6b0d13857e828c99d95dddacd632553ac59a | |
| parent | ce1acbc526056d736937fd1d67c0e02397442cb7 (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.java | 126 |
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. |