Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4c200f5 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Don't give the IME child window focus when switching tasks

When switching the app task, we keep the IME window visibility for
better transitioning experiences.

However, in case IME created a child window without dismissing
during the task switching to keep the window focus because the IME
window has higher window hierarchy.

Hence, we don't give it focus if the next IME layering target
doesn't actually request the IME visible.

Fix: 186329504
Test: manual as issue steps:
  1) Tap any text box to bring up Gboard.
  2) Tap access point -> '..' -> Share Gboard or Quality Bug Report.
  3) Swipe up to Home screen.
  4) Tap another text box.
  6) Verify if the IME can shown as expected after editor focused
Test: atest DisplayContentTests#\
      testImeChildWindowFocusWhenImeLayeringTargetChanges
Change-Id: I72618745542f33bcbb1001bd3b812e79f7652dda
parent 63a14538
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -724,6 +724,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            return false;
        }

        // When switching the app task, we keep the IME window visibility for better
        // transitioning experiences.
        // However, in case IME created a child window without dismissing during the task
        // switching to keep the window focus because IME window has higher window hierarchy,
        // we don't give it focus if the next IME layering target doesn't request IME visible.
        if (w.mIsImWindow && w.isChildWindow() && (mImeLayeringTarget == null
                || !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) {
            return false;
        }

        final ActivityRecord activity = w.mActivityRecord;

        if (focusedApp == null) {
+26 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.Surface.ROTATION_0;
@@ -2136,6 +2137,31 @@ public class DisplayContentTests extends WindowTestsBase {
                ACTIVITY_TYPE_STANDARD));
    }

    @UseTestDisplay(addWindows = W_INPUT_METHOD)
    @Test
    public void testImeChildWindowFocusWhenImeLayeringTargetChanges() {
        final WindowState imeChildWindow =
                createWindow(mImeWindow, TYPE_APPLICATION_ATTACHED_DIALOG, "imeChildWindow");
        makeWindowVisibleAndDrawn(imeChildWindow, mImeWindow);
        assertTrue(imeChildWindow.canReceiveKeys());
        mDisplayContent.setInputMethodWindowLocked(mImeWindow);

        // Verify imeChildWindow can be focused window if the next IME target requests IME visible.
        final WindowState imeAppTarget =
                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
        mDisplayContent.setImeLayeringTarget(imeAppTarget);
        spyOn(imeAppTarget);
        doReturn(true).when(imeAppTarget).getRequestedVisibility(ITYPE_IME);
        assertEquals(imeChildWindow, mDisplayContent.findFocusedWindow());

        // Verify imeChildWindow doesn't be focused window if the next IME target does not
        // request IME visible.
        final WindowState nextImeAppTarget =
                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "nextImeAppTarget");
        mDisplayContent.setImeLayeringTarget(nextImeAppTarget);
        assertNotEquals(imeChildWindow, mDisplayContent.findFocusedWindow());
    }

    private void removeRootTaskTests(Runnable runnable) {
        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
        final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,