diff options
| author | 2024-07-01 12:50:34 +0000 | |
|---|---|---|
| committer | 2024-11-05 09:54:32 +0000 | |
| commit | f2ff9b6748bf266f64e204127b5d90380913ba80 (patch) | |
| tree | bce2167b31988e4f83f9d395d847d327ed81819e | |
| parent | e2e3170c546b5011927135d4a610c848c5a3538d (diff) | |
Fix NPE: due to race condition between KCM package update
Not reproducible bug, possible cause of the bug is Gboard
package getting updated while PK connected causing the keyboard
notification using stale KCM descriptor which points to no KCM file.
Bug: 349033234
Test: None
Flag: EXEMPT bugfix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:123a55e96bdc6321ef9df9bb6192ab1fd9042c1d)
Merged-In: I946848ab7b03945c9c1a234a18ba8ca9db3c86e6
Change-Id: I946848ab7b03945c9c1a234a18ba8ca9db3c86e6
| -rw-r--r-- | services/core/java/com/android/server/input/KeyboardLayoutManager.java | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java index 97c32b986d38..49934126ab8c 100644 --- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java +++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java @@ -255,17 +255,6 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener { } } - private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) { - // Different languages are never compatible - if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) { - return false; - } - // If both the system and the keyboard layout have a country specifier, they must be equal. - return TextUtils.isEmpty(systemLocale.getCountry()) - || TextUtils.isEmpty(keyboardLocale.getCountry()) - || systemLocale.getCountry().equals(keyboardLocale.getCountry()); - } - @MainThread private void updateKeyboardLayouts() { // Scan all input devices state for keyboard layouts that have been uninstalled. @@ -953,21 +942,33 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener { return; } + List<String> layoutNames = new ArrayList<>(); + for (String layoutDesc : config.getConfiguredLayouts()) { + KeyboardLayout kl = getKeyboardLayout(layoutDesc); + if (kl == null) { + // b/349033234: Weird state with stale keyboard layout configured. + // Possibly due to race condition between KCM providing package being removed and + // corresponding layouts being removed from Datastore and cache. + // {@see updateKeyboardLayouts()} + // + // Ideally notification will be correctly shown after the keyboard layouts are + // configured again with the new package state. + return; + } + layoutNames.add(kl.getLabel()); + } showKeyboardLayoutNotification( r.getString( R.string.keyboard_layout_notification_selected_title, inputDevice.getName()), - createConfiguredNotificationText(mContext, config.getConfiguredLayouts()), + createConfiguredNotificationText(mContext, layoutNames), inputDevice); } @MainThread private String createConfiguredNotificationText(@NonNull Context context, - @NonNull Set<String> selectedLayouts) { + @NonNull List<String> layoutNames) { final Resources r = context.getResources(); - List<String> layoutNames = new ArrayList<>(); - selectedLayouts.forEach( - (layoutDesc) -> layoutNames.add(getKeyboardLayout(layoutDesc).getLabel())); Collections.sort(layoutNames); switch (layoutNames.size()) { case 1: |