From 787aa8c0db993e8f624769382c7395dd2f369ac4 Mon Sep 17 00:00:00 2001 From: Guliz Tuncay Date: Mon, 19 Jun 2017 17:15:40 -0700 Subject: [PATCH] Eliminate the inconsistency between the states of AMS and TSMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If spell checker service (SCS) is killed for some reason, TSMS accidentally clears the internal bindings to SCS even though it does not programmatically unbind them. When SCS is restarted, the seemingly-dead connections are re-established but TSMS’s internal bind groups structures do not keep track of them anymore. This results in inconsistency between the internal data structures of activity manager services (AMS) and TSMS. TSMS shows no bindings anymore, whereas AMS shows there is active spell checker service connections. The fix is to not remove a bind group at onServiceDisconnect and only set the bind group's connected state to false. Fixes: 37434113 Test: Manual as follows. 1. Build and flash an OS image. 2. Complete the setup wizard (if any). 3. Make sure AOSP Keyboard (com.android.inputmethod.latin) is installed. 4. adb shell settings put secure selected_spell_checker com.android.inputmethod.latin/.spellcheck.AndroidSpellCheckerService 5. Observe that there are no bindings to spell checker service (SCS) by running adb shell dumpsys textservices 6. Observe that there is no connection to SCS by running adb shell dumpsys activity services com.android.inputmethod.latin There should be no ConnectionRecord for AndroidSpellCheckerService 7. Run a test program that has TextView and tap on one of the TextViews and type some text. 8. Repeat steps 5 and 6 to observe there are now bindings and connection to SCS. 9. Kill SCS adb shell ps -A | grep com.android.inputmethod.latin | awk '{print $2}' | xargs adb shell kill -KILL 10. Repeat steps 5 and 6 to observe that the bindings are the same as of Step 8 and there is still a connection to SCS. Change-Id: I66de244f184ab0618944c129db4062d09f72e6d1 --- .../server/TextServicesManagerService.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java index 9068745c1ef35..18108234c004b 100644 --- a/services/core/java/com/android/server/TextServicesManagerService.java +++ b/services/core/java/com/android/server/TextServicesManagerService.java @@ -865,6 +865,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } + public void onServiceDisconnected() { + if (DBG) { + Slog.d(TAG, "onServiceDisconnected"); + } + + synchronized(mSpellCheckerMap) { + mSpellChecker = null; + mConnected = false; + } + } + public void removeListener(ISpellCheckerSessionListener listener) { if (DBG) { Slog.w(TAG, "remove listener: " + listener.hashCode()); @@ -1019,10 +1030,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { @Override public void onServiceDisconnected(ComponentName name) { synchronized(mSpellCheckerMap) { - final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId); - if (group != null && this == group.mInternalConnection) { - mSpellCheckerBindGroups.remove(mSciId); - } + onServiceDisconnectedInnerLocked(name); + } + } + + private void onServiceDisconnectedInnerLocked(ComponentName name) { + if (DBG) { + Slog.w(TAG, "onServiceDisconnected: " + name); + } + final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId); + if (group != null && this == group.mInternalConnection) { + group.onServiceDisconnected(); } } }