DisplayImeController: reapply visibility when leash changes
Fixes an issue where the DisplayImeController did not re-apply the visibility
if it receives a new leash.
This lead to focusable IME dialogs not being visible sometimes upon relaunching
the IME target activity, such as during rotation.
Fixes: 162875596
Bug: 160672060
Test: Enable Braille keyboard, open Settings, click on search box, switch to Braille keyboard, on the confirmation dialog rotate the screen; verify the dialog does not disappear.
Change-Id: Ia40a682ca8a9ba669454892e2b453f736c55929c
Merged-In: Ia40a682ca8a9ba669454892e2b453f736c55929c
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
index 89f469a..dd4ea57 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
@@ -228,12 +228,22 @@
mHandler.post(() -> {
final Point lastSurfacePosition = mImeSourceControl != null
? mImeSourceControl.getSurfacePosition() : null;
+ final boolean positionChanged =
+ !activeControl.getSurfacePosition().equals(lastSurfacePosition);
+ final boolean leashChanged =
+ !haveSameLeash(mImeSourceControl, activeControl);
mImeSourceControl = activeControl;
- if (!activeControl.getSurfacePosition().equals(lastSurfacePosition)
- && mAnimation != null) {
- startAnimation(mImeShowing, true /* forceRestart */);
- } else if (!mImeShowing) {
- removeImeSurface();
+ if (mAnimation != null) {
+ if (positionChanged) {
+ startAnimation(mImeShowing, true /* forceRestart */);
+ }
+ } else {
+ if (leashChanged) {
+ applyVisibilityToLeash();
+ }
+ if (!mImeShowing) {
+ removeImeSurface();
+ }
}
});
}
@@ -241,6 +251,20 @@
}
}
+ private void applyVisibilityToLeash() {
+ SurfaceControl leash = mImeSourceControl.getLeash();
+ if (leash != null) {
+ SurfaceControl.Transaction t = mTransactionPool.acquire();
+ if (mImeShowing) {
+ t.show(leash);
+ } else {
+ t.hide(leash);
+ }
+ t.apply();
+ mTransactionPool.release(t);
+ }
+ }
+
@Override
public void showInsets(int types, boolean fromIme) {
if ((types & WindowInsets.Type.ime()) == 0) {
@@ -492,4 +516,20 @@
return IInputMethodManager.Stub.asInterface(
ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
}
+
+ private static boolean haveSameLeash(InsetsSourceControl a, InsetsSourceControl b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ if (a.getLeash() == b.getLeash()) {
+ return true;
+ }
+ if (a.getLeash() == null || b.getLeash() == null) {
+ return false;
+ }
+ return a.getLeash().isSameSurface(b.getLeash());
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 03834c34..b7a2eb3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6187,7 +6187,7 @@
}
if (inputMethodControlTarget != null) {
pw.print(" inputMethodControlTarget in display# "); pw.print(displayId);
- pw.print(' '); pw.println(inputMethodControlTarget.getWindow());
+ pw.print(' '); pw.println(inputMethodControlTarget);
}
});
pw.print(" mInTouchMode="); pw.println(mInTouchMode);