diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2019-11-26 19:42:45 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-11-26 19:42:45 +0000 |
| commit | a79e16c82cca3045192fcc6b01e3660e74f4eaeb (patch) | |
| tree | 356cf302916f7f02640b8199f785fca903271d55 /core/java/android | |
| parent | fc3f1408daf55561a6c8ed247b02d90092175b63 (diff) | |
| parent | 4b6acb4f39a628eef9710a2a4e235dd9f56d9cab (diff) | |
Merge "DO NOT MERGE: Move startInput for WINDOW_FOCUS_GAIN to background thread" into qt-qpr1-dev
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/inputmethod/InputMethodManager.java | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 032af1c5c7b5..d75810ad0e37 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -92,7 +92,10 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** @@ -422,6 +425,13 @@ public final class InputMethodManager { int mCursorCandEnd; /** + * Initial startInput with {@link StartInputReason.WINDOW_FOCUS_GAIN} is executed + * in a background thread. Later, if there is an actual startInput it will wait on + * main thread till the background thread completes. + */ + private CompletableFuture<Void> mWindowFocusGainFuture; + + /** * The instance that has previously been sent to the input method. */ private CursorAnchorInfo mCursorAnchorInfo = null; @@ -1598,6 +1608,18 @@ public final class InputMethodManager { boolean startInputInner(@StartInputReason int startInputReason, @Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode, int windowFlags) { + if (startInputReason != StartInputReason.WINDOW_FOCUS_GAIN + && mWindowFocusGainFuture != null) { + try { + mWindowFocusGainFuture.get(); + } catch (ExecutionException | InterruptedException e) { + // do nothing + } catch (CancellationException e) { + // window no longer has focus. + return true; + } + } + final View view; synchronized (mH) { view = mServedView; @@ -1951,31 +1973,38 @@ public final class InputMethodManager { startInputFlags |= StartInputFlags.FIRST_WINDOW_FOCUS_GAIN; } - if (checkFocusNoStartInput(forceNewFocus)) { - // We need to restart input on the current focus view. This - // should be done in conjunction with telling the system service - // about the window gaining focus, to help make the transition - // smooth. - if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(), - startInputFlags, softInputMode, windowFlags)) { - return; - } + final boolean forceNewFocus1 = forceNewFocus; + final int startInputFlags1 = startInputFlags; + if (mWindowFocusGainFuture != null) { + mWindowFocusGainFuture.cancel(false/* mayInterruptIfRunning */); } + mWindowFocusGainFuture = CompletableFuture.runAsync(() -> { + if (checkFocusNoStartInput(forceNewFocus1)) { + // We need to restart input on the current focus view. This + // should be done in conjunction with telling the system service + // about the window gaining focus, to help make the transition + // smooth. + if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(), + startInputFlags1, softInputMode, windowFlags)) { + return; + } + } - // For some reason we didn't do a startInput + windowFocusGain, so - // we'll just do a window focus gain and call it a day. - synchronized (mH) { - try { - if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); - mService.startInputOrWindowGainedFocus( - StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, - rootView.getWindowToken(), startInputFlags, softInputMode, windowFlags, - null, null, 0 /* missingMethodFlags */, - rootView.getContext().getApplicationInfo().targetSdkVersion); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + // For some reason we didn't do a startInput + windowFocusGain, so + // we'll just do a window focus gain and call it a day. + synchronized (mH) { + try { + if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); + mService.startInputOrWindowGainedFocus( + StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient, + rootView.getWindowToken(), startInputFlags1, softInputMode, windowFlags, + null, null, 0 /* missingMethodFlags */, + rootView.getContext().getApplicationInfo().targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } - } + }); } /** @hide */ @@ -1990,6 +2019,10 @@ public final class InputMethodManager { // If the mCurRootView is losing window focus, release the strong reference to it // so as not to prevent it from being garbage-collected. mCurRootView = null; + if (mWindowFocusGainFuture != null) { + mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */); + mWindowFocusGainFuture = null; + } } else { if (DEBUG) { Log.v(TAG, "Ignoring onPreWindowFocus()." |
