From 1a6f4c79f2a74d2c895650c4cb06e1c00b4cc477 Mon Sep 17 00:00:00 2001 From: Guliz Tuncay Date: Fri, 14 Jul 2017 10:19:45 -0700 Subject: [PATCH] removeAll unregisters callbacks in the wrong order, causing exception If we switch from a user with active SpellCheckerBindGroups to another user, an exception is thrown and the system reports that the user switch was not successful. The source of this exception is removeAll() method used in unbindServiceLocked(). It seems that removeAll() retrieves the number of callbacks of mListeners object and removes the registered callbacks of this object one by one in a loop. However, this causes the size of the mListeners change along the way and each element's index decreases by one at each iteration, causing the loop to eventually try to operate on a null object. This error was introduced by I38942765ed6bec6713757b1d5f325e7a633c2ba7 Fixes: 63703656 Test: Manually tested as follows 1. Flash a new OS image with this change 2. Complete the setup wizard (if any) 3. make ApiDemos -j 4. adb install -r out/target/product/marlin/data/app/ApiDemos/ApiDemos.apk 5. Open "Api Demos" app 6. Go to Views/Text/EditText 7. Focus in to the first EditText then type "aaa" 8. Focus in to the second EditText then type "aaa" 9. Run `adb shell dumpsys textservices` to confirm that there are multiple listener in one of the items in "Spell Checker Bind Groups" section. 10. Switch to the Guest user. 11. Run `adb logcat -s SystemServiceManager:E` to confirm that there is no NullPointerException Change-Id: Ibfdb07266a5a9127425b7ecffa9afbb8718eca62 --- .../java/com/android/server/TextServicesManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java index 6d9d874d08993..80d39f585c12b 100644 --- a/services/core/java/com/android/server/TextServicesManagerService.java +++ b/services/core/java/com/android/server/TextServicesManagerService.java @@ -857,7 +857,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.e(TAG, "Remove the spell checker bind unexpectedly."); synchronized (mLock) { final int size = mListeners.getRegisteredCallbackCount(); - for (int i = 0; i < size; ++i) { + for (int i = size - 1; i >= 0; --i) { mListeners.unregister(mListeners.getRegisteredCallbackItem(i)); } mPendingSessionRequests.clear();