From cc97ebd031b4d4be6f69e3163c362bce6878baf1 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Mon, 11 Dec 2017 17:54:43 -0800 Subject: [PATCH] Add a shell command to reset selected/enabled IMEs With this CL, you can reset currently selected/enabled IMEs with a shell command as follows: adb shell ime reset-ime This should be useful for end-to-end tests where often we want to clean up persistent IME state to the default ones as if the device is initially booted. Fixes: 70475949 Test: Manually tested as follows: 1. make -j SoftKeyboard 2. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk 3. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard 4. adb shell ime set com.example.android.softkeyboard/.SoftKeyboard 5. Make sure that SoftKeyboard is enabled and selected 6. adb shell ime reset-ime 7. Make sure that SoftKeyboard is no longer enabled and selected Change-Id: I1e27aa1c9edf5d9a6d529c469ad42fd1e42b13b1 --- .../server/InputMethodManagerService.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index e1d6b5da0db82..5fed93b1b0b1a 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -4655,6 +4655,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mService.handleShellCommandEnableDisableInputMethod(this, false); case "set": return mService.handleShellCommandSetInputMethod(this); + case "reset-ime": + return mService.handleShellCommandResetInputMethod(this); default: return handleDefaultCommands(cmd); } @@ -4679,6 +4681,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pw.println(" disallows the given input method ID to be used."); pw.println(" set "); pw.println(" switches to the given input method ID."); + pw.println(" reset-ime"); + pw.println(" reset currently selected/enabled IMEs to the default ones as if"); + pw.println(" the device is initially booted with the current locale."); } } } @@ -4788,4 +4793,84 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pr.println(" selected"); return ShellCommandResult.SUCCESS; } + + /** + * Handles {@code adb shell ime reset-ime}. + * @param shellCommand {@link ShellCommand} object that is handling this command. + * @return Exit code of the command. + */ + @BinderThread + @ShellCommandResult + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + private int handleShellCommandResetInputMethod(@NonNull ShellCommand shellCommand) { + if (!calledFromValidUser()) { + shellCommand.getErrPrintWriter().print( + "Must be called from the foreground user or with INTERACT_ACROSS_USERS_FULL"); + return ShellCommandResult.FAILURE; + } + synchronized (mMethodMap) { + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + shellCommand.getErrPrintWriter().print( + "Caller must have WRITE_SECURE_SETTINGS permission"); + throw new SecurityException( + "Requires permission " + + android.Manifest.permission.WRITE_SECURE_SETTINGS); + } + final String nextIme; + final List nextEnabledImes; + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mMethodMap) { + hideCurrentInputLocked(0, null); + unbindCurrentMethodLocked(false); + // Reset the current IME + resetSelectedInputMethodAndSubtypeLocked(null); + // Also reset the settings of the current IME + mSettings.putSelectedInputMethod(null); + // Disable all enabled IMEs. + { + final ArrayList enabledImes = + mSettings.getEnabledInputMethodListLocked(); + final int N = enabledImes.size(); + for (int i = 0; i < N; ++i) { + setInputMethodEnabledLocked(enabledImes.get(i).getId(), false); + } + } + // Re-enable with default enabled IMEs. + { + final ArrayList defaultEnabledIme = + InputMethodUtils.getDefaultEnabledImes(mContext, mMethodList); + final int N = defaultEnabledIme.size(); + for (int i = 0; i < N; ++i) { + setInputMethodEnabledLocked(defaultEnabledIme.get(i).getId(), true); + } + } + updateInputMethodsFromSettingsLocked(true /* enabledMayChange */); + InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager, + mSettings.getEnabledInputMethodListLocked(), + mSettings.getCurrentUserId(), + mContext.getBasePackageName()); + nextIme = mSettings.getSelectedInputMethod(); + nextEnabledImes = getEnabledInputMethodList(); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + final PrintWriter pr = shellCommand.getOutPrintWriter(); + pr.println("Reset current and enabled IMEs"); + pr.println("Newly selected IME:"); + pr.print(" "); pr.println(nextIme); + pr.println("Newly enabled IMEs:"); + { + final int N = nextEnabledImes.size(); + for (int i = 0; i < N; ++i) { + pr.print(" "); + pr.println(nextEnabledImes.get(i).getId()); + } + } + return ShellCommandResult.SUCCESS; + } + } }