From ad78a615b7d3715c63f25c123c52f0ddbec853ea Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 4 Aug 2017 01:57:27 -0700 Subject: [PATCH] Bind SpellCheckerService as IMPORTANT_BACKGROUND If both InputMethodService (IME) and SpellCheckerService (SCS) are implemented in the same package and used at the same time, typing something on an EditText can easily create an active spell checker connection, which is likely to be kept alive even after the software keyboard gets dismissed by the user. Since currently TextServicesManagerService (TSMS) binds SCS with BIND_FOREGROUND_SERVICE_WHILE_AWAKE flag, the IME process continues to be PROCESS_STATE_BOUND_FOREGROUND_SERVICE even after software keyboard gets dismissed and InputMethodManagerService no longer binds IME with BIND_FOREGROUND_SERVICE [1]. As a result, the IME process less frequently receives UI_HIDDEN, with which HWUI heavily relies on to purge its internal caches. The idea of this CL is to reduce the process state bonus from TSMS to SCS so that it can match with what IMMS does to IME when software keyboard is not shown. Hopefully this would not cause priority inversion provlems between the focused application and SCS because IMEs with hardware keyborad with no software keyboard have already running on this process state. This CL also makes sure that IME starts receiving UI_HIDDEN only after it shows the software keyboard, like IME gains BIND_TREAT_LIKE_ACTIVITY characteristics [2] only after it shows the software keyboard. [1]: Id1f73de66dc93d63212183958a72119ad174318b 2c84cfc001fb92a71811bf7384b7f865ff31ff9d [2]: Ie5793fd9b40d980fa18f80246326511ed6ae0597 f0f94d129b6eb3c48624e915898d86d4f2de59ff Fixes: 64378148 Test: Manually tested as follows 1. make -j ApiDemos 2. adb install -r $ANDROID_PRODUCT_OUT/data/app/ApiDemos/ApiDemos.apk 3. tapas LatinIME 4. adb install -r $ANDROID_PRODUCT_OUT/system/app/LatinIME/LatinIME.apk 5. adb shell ime enable com.android.inputmethod.latin/.LatinIME 6. adb shell ime set com.android.inputmethod.latin/.LatinIME 7. adb shell "settings put secure selected_spell_checker 'com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService'" 8. adb shell dumpsys activity processes com.android.inputmethod.latin -> make sure curProcState=7 -> make sure there is no "pendingUiClean" entry. 9. adb shell dumpsys activity services com.android.inputmethod.latin -> Make sure there is only one connection to "com.android.inputmethod.latin/.LatinIME" -> It should have following flags: "CR !FG IMPB !VIS" 10. Open "Api Demos" app 11. Go to Views/Text/EditText -> make sure software keyboard shows up 12. adb shell dumpsys activity processes com.android.inputmethod.latin -> make sure curProcState=3 -> make sure pendingUiClean=true 13. adb shell dumpsys activity services com.android.inputmethod.latin -> Make sure there are two connections to "com.android.inputmethod.latin/.LatinIME" -> They should have following flags: "CR !FG IMPB !VIS" and "CR FGS LACT UI" 14. In the first EditText type "aaa" then hit the space key. 15. adb shell dumpsys activity processes com.android.inputmethod.latin -> make sure curProcState=3 -> make sure pendingUiClean=true 16. adb shell dumpsys activity services com.android.inputmethod.latin -> Make sure there are two connections to "com.android.inputmethod.latin/.LatinIME" -> They should have following flags: "CR !FG IMPB !VIS" and "CR FGS LACT UI" -> Make sure there is a connection to "com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService" -> It should have following flags: "CR IMPB" 17. Tap the down button on the NavBar to dismiss the keyboard 18. adb shell dumpsys activity processes com.android.inputmethod.latin -> make sure curProcState=7 -> make sure pendingUiClean=false 19. adb shell dumpsys activity services com.android.inputmethod.latin -> Make sure there is only one connection to "com.android.inputmethod.latin/.LatinIME" -> It should have following flags: "CR !FG IMPB !VIS" -> Make sure there is a connection to "com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService" -> It should have following flags: "CR IMPB" Change-Id: I91bc58675ce2e257af11efce5572bd9ecd4a37ac --- .../java/com/android/server/InputMethodManagerService.java | 6 +++--- .../java/com/android/server/TextServicesManagerService.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 814e4be28ffa6..c23757fca381e 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -214,8 +214,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Context.BIND_AUTO_CREATE | Context.BIND_NOT_VISIBLE | Context.BIND_NOT_FOREGROUND - | Context.BIND_IMPORTANT_BACKGROUND - | Context.BIND_SHOWING_UI; + | Context.BIND_IMPORTANT_BACKGROUND; /** * Binding flags used only while the {@link InputMethodService} is showing window. @@ -223,7 +222,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final int IME_VISIBLE_BIND_FLAGS = Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY - | Context.BIND_FOREGROUND_SERVICE; + | Context.BIND_FOREGROUND_SERVICE + | Context.BIND_SHOWING_UI; @Retention(SOURCE) @IntDef({HardKeyboardBehavior.WIRELESS_AFFORDANCE, HardKeyboardBehavior.WIRED_AFFORDANCE}) diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java index 80d39f585c12b..13e3ae60f1bff 100644 --- a/services/core/java/com/android/server/TextServicesManagerService.java +++ b/services/core/java/com/android/server/TextServicesManagerService.java @@ -598,7 +598,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.w(TAG, "bind service: " + info.getId()); } if (!bindCurrentSpellCheckerService(serviceIntent, connection, - Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) { + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT_BACKGROUND)) { Slog.e(TAG, "Failed to get a spell checker service."); return null; }