From d28e52b60862e3bad1ad65fa17072c714db635a8 Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Mon, 26 Jun 2023 22:01:03 +0000 Subject: [PATCH] Cache isStylusHandwritingAvailable for user InputMethodManager's isStylusHandwritingAvialable is called frequently from all toolkits before initiation. Caching this value on client app should help reduce the hover icon and initiation latency Refer to doc in bug for approach Bug: 288618291 Bug: 287109569 Test: atest StylusHandwritingTest Test: atest MultiUserTest Change-Id: I6d89d82589e4946e07bfbc4b97811fe4537b1a9b --- .../view/inputmethod/InputMethodManager.java | 34 +++++++++++++++++-- .../InputMethodManagerService.java | 8 ++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 3f308e6fcceea..b3233141f1267 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -50,6 +50,7 @@ import android.annotation.TestApi; import android.annotation.UiThread; import android.annotation.UserIdInt; import android.app.ActivityThread; +import android.app.PropertyInvalidatedCache; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; @@ -536,6 +537,13 @@ public final class InputMethodManager { @UnsupportedAppUsage Rect mCursorRect = new Rect(); + /** Cached value for {@link #isStylusHandwritingAvailable} for userId. */ + @GuardedBy("mH") + private PropertyInvalidatedCache mStylusHandwritingAvailableCache; + + private static final String CACHE_KEY_STYLUS_HANDWRITING_PROPERTY = + "cache_key.system_server.stylus_handwriting"; + @GuardedBy("mH") private int mCursorSelStart; @GuardedBy("mH") @@ -662,6 +670,15 @@ public final class InputMethodManager { private static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30; private static final int MSG_ON_SHOW_REQUESTED = 31; + /** + * Calling this will invalidate Local stylus handwriting availability Cache which + * forces the next query in any process to recompute the cache. + * @hide + */ + public static void invalidateLocalStylusHandwritingAvailabilityCaches() { + PropertyInvalidatedCache.invalidateCache(CACHE_KEY_STYLUS_HANDWRITING_PROPERTY); + } + private static boolean isAutofillUIShowing(View servedView) { AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class); return afm != null && afm.isAutofillUiShowing(); @@ -1577,8 +1594,21 @@ public final class InputMethodManager { if (fallbackContext == null) { return false; } - - return IInputMethodManagerGlobalInvoker.isStylusHandwritingAvailableAsUser(userId); + boolean isAvailable; + synchronized (mH) { + if (mStylusHandwritingAvailableCache == null) { + mStylusHandwritingAvailableCache = new PropertyInvalidatedCache<>( + 4 /* maxEntries */, CACHE_KEY_STYLUS_HANDWRITING_PROPERTY) { + @Override + public Boolean recompute(Integer userId) { + return IInputMethodManagerGlobalInvoker.isStylusHandwritingAvailableAsUser( + userId); + } + }; + } + isAvailable = mStylusHandwritingAvailableCache.query(userId); + } + return isAvailable; } /** diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 02ee96a04b1f8..7bda2c1fa5ab9 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1175,6 +1175,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this, userId); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE), false, this, userId); + resolver.registerContentObserver(Settings.Secure.getUriFor( + STYLUS_HANDWRITING_ENABLED), false, this); mRegistered = true; } @@ -1183,6 +1185,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD); final Uri accessibilityRequestingNoImeUri = Settings.Secure.getUriFor( Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE); + final Uri stylusHandwritingEnabledUri = Settings.Secure.getUriFor( + STYLUS_HANDWRITING_ENABLED); synchronized (ImfLock.class) { if (showImeUri.equals(uri)) { mMenuController.updateKeyboardFromSettingsLocked(); @@ -1200,6 +1204,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub showCurrentInputImplicitLocked(mCurFocusedWindow, SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE); } + } else if (stylusHandwritingEnabledUri.equals(uri)) { + InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches(); } else { boolean enabledChanged = false; String newEnabled = mSettings.getEnabledInputMethodsStr(); @@ -2363,7 +2369,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mCurVirtualDisplayToScreenMatrix = null; ImeTracker.forLogging().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); mCurStatsToken = null; - + InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches(); mMenuController.hideInputMethodMenuLocked(); } }