summaryrefslogtreecommitdiff
path: root/core/java/android/inputmethodservice/InputMethodService.java
diff options
context:
space:
mode:
authorTaran Singh <tarandeep@google.com>2021-01-12 18:51:10 +0000
committerTaran Singh <tarandeep@google.com>2021-01-12 18:58:44 +0000
commit533596c71d2502ff8b4d99ae4d1b4201d84d4c4a (patch)
tree30922718c8ce00e8d7fd71dda5398404a66df2d4 /core/java/android/inputmethodservice/InputMethodService.java
parentd47c351b8dc9cf8d0827eaae5e8eb1388aead273 (diff)
Retain IME surface with a timeout
As of today, IME surface is removed immidiately after its hidden. This causes IME surface to be recreated when next time its requested, which takes noticeable amount of time ~30ms on a typical phone [1] In order to improve IME latency, we keep the surface in memory a little longer. This is ideal for use cases where IME has to move between DisplayAreas OR when IME is closed only briefly. While there could be other strategies to hold IME surface in memory, timeout is simplistic and is also unaffected by IMF lifecycle, which could vary when moving between DisplayAreas or Displays. Bug: 167948419 Bug: 167948123 Test: atest CtsInputMethodTestCases [1] refer design doc in bug 167947940 Change-Id: Ib062640b68164efbb647e7bf27b7f8eb5ed252dc
Diffstat (limited to 'core/java/android/inputmethodservice/InputMethodService.java')
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java36
1 files changed, 33 insertions, 3 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index df9a7c2cb586..44a2e97e6f04 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -410,6 +410,11 @@ public class InputMethodService extends AbstractInputMethodService {
private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT;
private static final int BACK_DISPOSITION_MAX = BACK_DISPOSITION_ADJUST_NOTHING;
+ /**
+ * Timeout after which hidden IME surface will be removed from memory
+ */
+ private static final long TIMEOUT_SURFACE_REMOVAL_MILLIS = 5000;
+
InputMethodManager mImm;
private InputMethodPrivilegedOperations mPrivOps = new InputMethodPrivilegedOperations();
@@ -506,6 +511,8 @@ public class InputMethodService extends AbstractInputMethodService {
private boolean mAutomotiveHideNavBarForKeyboard;
private boolean mIsAutomotive;
+ private Handler mHandler;
+ private boolean mImeSurfaceScheduledForRemoval;
/**
* An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
@@ -903,11 +910,31 @@ public class InputMethodService extends AbstractInputMethodService {
requestHideSelf(0);
}
+ private void scheduleImeSurfaceRemoval() {
+ if (mShowInputRequested || mWindowVisible || mWindow == null
+ || mImeSurfaceScheduledForRemoval) {
+ return;
+ }
+ if (mHandler == null) {
+ mHandler = new Handler(getMainLooper());
+ }
+ mImeSurfaceScheduledForRemoval = true;
+ mHandler.postDelayed(() -> removeImeSurface(), TIMEOUT_SURFACE_REMOVAL_MILLIS);
+ }
+
private void removeImeSurface() {
- if (!mShowInputRequested && !mWindowVisible) {
- // hiding a window removes its surface.
+ // hiding a window removes its surface.
+ if (mWindow != null) {
mWindow.hide();
}
+ mImeSurfaceScheduledForRemoval = false;
+ }
+
+ private void cancelImeSurfaceRemoval() {
+ if (mHandler != null && mImeSurfaceScheduledForRemoval) {
+ mHandler.removeCallbacksAndMessages(null /* token */);
+ mImeSurfaceScheduledForRemoval = false;
+ }
}
private void setImeWindowStatus(int visibilityFlags, int backDisposition) {
@@ -1043,7 +1070,7 @@ public class InputMethodService extends AbstractInputMethodService {
* @hide
*/
public final void removeImeSurface() {
- InputMethodService.this.removeImeSurface();
+ InputMethodService.this.scheduleImeSurfaceRemoval();
}
}
@@ -2271,6 +2298,9 @@ public class InputMethodService extends AbstractInputMethodService {
ImeTracing.getInstance().triggerServiceDump(
"InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this,
null /* icProto */);
+ if (setVisible) {
+ cancelImeSurfaceRemoval();
+ }
mPrivOps.applyImeVisibility(setVisible
? mCurShowInputToken : mCurHideInputToken, setVisible);
}