From 4a011f69ec86dfcc409ea76d140c0263f287fdfa Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 14 May 2021 10:47:24 -0700 Subject: [PATCH] Let "ime enable/set" return exit code 255 when failed This is a follow up CL to my previous CL [1], which added -u option to "adb shell ime set " command. As noted in its commit message, that CL made specifying non existent IME ID a graceful success rather than a hard failure. However, such a change made it quite difficult to diagnose race conditions when the specified IME is not yet recognized by InputMethodManagerService. This is especially annoying when diagnosing CTS failures happening only on reporters' devices. With this CL, "adb shell ime set " at least returns 255 as its exit code when the specified IME ID cannot be recognized by the InputMethodManagerService (yet). If the multiple users are involved (e.g. by adding "-u all" option), then 255 will be returned if the specified IME ID is invalid to at least one user. This CL also does the same thing for adb shell ime enable command. Also, those two shell commands now show error messages in logcat when they failed for better debugability. Other than exit code and logcat messages from those shell commands, there should be no behavior change in this CL. [1]: I397cf0fb418a395dcafc0ab0d8d4e553b0f2eaab 099f80ce9762e8b20998759fd6082bdcd6291103 Bug: 186526091 Fix: 188094681 Test: Manually verified as follows: 1. adb shell ime enable com.example.android.nonexistentime/.Ime 2. echo $? # confirm this is 255 3. adb logcat -s InputMethodManagerService:* # Confirm the msg. 4. adb shell ime set com.example.android.nonexistentime/.Ime 5. echo $? # confirm this is 255 6. adb logcat -s InputMethodManagerService:* # Confirm the msg. 7. adb shell ime disable com.example.android.nonexistentime/.Ime 8. echo $? # confirm this is 0 9. adb logcat -s InputMethodManagerService:* # Confirm no msg. Change-Id: I3a544eb79c068ea692200b2e25484b56a628ceb0 --- .../InputMethodManagerService.java | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 518c4287deab6..94e669a5eed2d 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -5761,6 +5761,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String imeId = shellCommand.getNextArgRequired(); final PrintWriter out = shellCommand.getOutPrintWriter(); final PrintWriter error = shellCommand.getErrPrintWriter(); + boolean hasFailed = false; synchronized (mMethodMap) { final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved, mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter()); @@ -5768,11 +5769,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!userHasDebugPriv(userId, shellCommand)) { continue; } - handleShellCommandEnableDisableInputMethodInternalLocked(userId, imeId, enabled, - out, error); + hasFailed |= !handleShellCommandEnableDisableInputMethodInternalLocked( + userId, imeId, enabled, out, error); } } - return ShellCommandResult.SUCCESS; + return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS; } /** @@ -5804,8 +5805,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return UserHandle.USER_CURRENT; } + /** + * Handles core logic of {@code adb shell ime enable} and {@code adb shell ime disable}. + * + * @param userId user ID specified to the command. Pseudo user IDs are not supported. + * @param imeId IME ID specified to the command. + * @param enabled {@code true} for {@code adb shell ime enable}. {@code false} otherwise. + * @param out {@link PrintWriter} to output standard messages. + * @param error {@link PrintWriter} to output error messages. + * @return {@code false} if it fails to enable the IME. {@code false} otherwise. + */ @BinderThread - private void handleShellCommandEnableDisableInputMethodInternalLocked( + private boolean handleShellCommandEnableDisableInputMethodInternalLocked( @UserIdInt int userId, String imeId, boolean enabled, PrintWriter out, PrintWriter error) { boolean failedToEnableUnknownIme = false; @@ -5851,15 +5862,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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); + // Also print this failure into logcat for better debuggability. + Slog.e(TAG, "\"ime enable " + imeId + "\" for user #" + userId + + " failed due to its unrecognized IME ID."); + return false; } + + 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); + return true; } /** @@ -5874,6 +5890,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String imeId = shellCommand.getNextArgRequired(); final PrintWriter out = shellCommand.getOutPrintWriter(); final PrintWriter error = shellCommand.getErrPrintWriter(); + boolean hasFailed = false; synchronized (mMethodMap) { final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved, mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter()); @@ -5887,15 +5904,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub error.print(imeId); error.print(" cannot be selected for user #"); error.println(userId); + // Also print this failure into logcat for better debuggability. + Slog.e(TAG, "\"ime set " + imeId + "\" for user #" + userId + + " failed due to its unrecognized IME ID."); } else { out.print("Input method "); out.print(imeId); out.print(" selected for user #"); out.println(userId); } + hasFailed |= failedToSelectUnknownIme; } } - return ShellCommandResult.SUCCESS; + return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS; } /**