summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorAdrian Roos <roosa@google.com>2020-07-02 18:57:22 +0200
committerAdrian Roos <roosa@google.com>2020-07-09 14:46:55 +0200
commit2260ce4dafdd1fdaf8cbaf7579119ed7ecded088 (patch)
tree95035f79185dc4191a09b4690a79c48332ae9fab /core/java/android
parentf1f700094c8100b9a4a67815bf57ae50db1efab5 (diff)
Fix IME flicker: move hiding the surface into the control target
Fixes a flicker that occurs during transitions between windows. This happens for two reasons: 1.) Control is immediately transferred to the new window, and the previous window didn't get a chance to play the animation. This is addressed by adding logic to keep control on the exiting window for the duration of the transition - similar to what we do with the target for z-ordering purposes. 2.) Upon the input connection being severed, the InputMethodService immediately hides its window, preventing any animations whenever the input connection changes This is addressed by moving hiding of the surface into the controlling windows - where upon receiving control, we now trigger removal of the IME surface if we don't show it. Additionally: - Now ensures that any requests from the ImeInsetsSourceConsumer ensure that they come from the window that is currently served by IMM. - Removes the transparancy clause from isImeTargetFromDisplayContentAndImeSame to match the updated IME target computation in DisplayContent in [1]. [1]: Iedd5f7407926167f4891ce9b7e9a79e22751e668 Fixes: 153145997 Fixes: 150902448 Test: atest WindowInsetsAnimationControllerTests Test: atest DisplayContentTests InsetsSourceConsumerTest Test: Open app with IME, press HOME button, verify IME smoothly animates away Test: Open Messages, open a thread, open IME. Click search icon, verify IME opens in the search activity Change-Id: I4910c2a06cc67b0470477b245fc1de54b75f10f9
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java3
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java12
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java3
-rw-r--r--core/java/android/view/ViewRootImpl.java5
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java30
5 files changed, 35 insertions, 18 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5647bf90d2fb..c5a11abe1136 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -605,9 +605,6 @@ public class InputMethodService extends AbstractInputMethodService {
if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
+ " ic=" + mInputConnection);
// Unbind input is per process per display.
- // TODO(b/150902448): free-up IME surface when target is changing.
- // e.g. DisplayContent#setInputMethodTarget()
- removeImeSurface();
onUnbindInput();
mInputBinding = null;
mInputConnection = null;
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index ef9d990168d2..c1998c6009cf 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -119,11 +119,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
// If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
// this code here means that we now got control, so we can start the animation immediately.
// If client window is trying to control IME and IME is already visible, it is immediate.
- if (fromIme || mState.getSource(getType()).isVisible()) {
+ if (fromIme || mState.getSource(getType()).isVisible() && getControl() != null) {
return ShowResult.SHOW_IMMEDIATELY;
}
- return getImm().requestImeShow(null /* resultReceiver */)
+ return getImm().requestImeShow(mController.getHost().getWindowToken())
? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED;
}
@@ -132,12 +132,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
*/
@Override
void notifyHidden() {
- getImm().notifyImeHidden();
+ getImm().notifyImeHidden(mController.getHost().getWindowToken());
}
@Override
public void removeSurface() {
- getImm().removeImeSurface();
+ final IBinder window = mController.getHost().getWindowToken();
+ if (window != null) {
+ getImm().removeImeSurface(window);
+ }
}
@Override
@@ -146,6 +149,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
super.setControl(control, showTypes, hideTypes);
if (control == null && !mIsRequestedVisibleAwaitingControl) {
hide();
+ removeSurface();
}
}
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 40e6f4b2fce8..700dc66fab55 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -153,6 +153,9 @@ public class InsetsSourceConsumer {
if (oldLeash == null || newLeash == null || !oldLeash.isSameSurface(newLeash)) {
applyHiddenToControl();
}
+ if (!requestedVisible && !mIsAnimationPending) {
+ removeSurface();
+ }
}
}
if (lastControl != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a58642517a20..1a15230413d6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -9377,6 +9377,11 @@ public final class ViewRootImpl implements ViewParent,
return mInputEventReceiver.getToken();
}
+ @NonNull
+ public IBinder getWindowToken() {
+ return mAttachInfo.mWindowToken;
+ }
+
/**
* Class for managing the accessibility interaction connection
* based on the global accessibility state.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index aedb59bfee42..3be0a4d39a56 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2109,28 +2109,36 @@ public final class InputMethodManager {
/**
* Call showSoftInput with currently focused view.
- * @return {@code true} if IME can be shown.
+ *
+ * @param windowToken the window from which this request originates. If this doesn't match the
+ * currently served view, the request is ignored and returns {@code false}.
+ *
+ * @return {@code true} if IME can (eventually) be shown, {@code false} otherwise.
* @hide
*/
- public boolean requestImeShow(ResultReceiver resultReceiver) {
+ public boolean requestImeShow(IBinder windowToken) {
synchronized (mH) {
final View servedView = getServedViewLocked();
- if (servedView == null) {
+ if (servedView == null || servedView.getWindowToken() != windowToken) {
return false;
}
- showSoftInput(servedView, 0 /* flags */, resultReceiver);
+ showSoftInput(servedView, 0 /* flags */, null /* resultReceiver */);
return true;
}
}
/**
* Notify IME directly that it is no longer visible.
+ *
+ * @param windowToken the window from which this request originates. If this doesn't match the
+ * currently served view, the request is ignored.
* @hide
*/
- public void notifyImeHidden() {
+ public void notifyImeHidden(IBinder windowToken) {
synchronized (mH) {
try {
- if (mCurMethod != null) {
+ if (mCurMethod != null && mCurRootView != null
+ && mCurRootView.getWindowToken() == windowToken) {
mCurMethod.notifyImeHidden();
}
} catch (RemoteException re) {
@@ -2140,15 +2148,15 @@ public final class InputMethodManager {
/**
* Notify IME directly to remove surface as it is no longer visible.
+ * @param windowToken The client window token that requests the IME to remove its surface.
* @hide
*/
- public void removeImeSurface() {
+ public void removeImeSurface(IBinder windowToken) {
synchronized (mH) {
try {
- if (mCurMethod != null) {
- mCurMethod.removeImeSurface();
- }
- } catch (RemoteException re) {
+ mService.removeImeSurfaceFromWindow(windowToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}