Merge "Polish IME transition from fullscreen task to split-screen task" into tm-dev
This commit is contained in:
@@ -4270,17 +4270,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
*/
|
||||
@VisibleForTesting
|
||||
SurfaceControl computeImeParent() {
|
||||
if (mImeLayeringTarget != null && mImeInputTarget != null
|
||||
&& mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
|
||||
// Do not change parent if the window hasn't requested IME.
|
||||
return null;
|
||||
}
|
||||
// Attach it to app if the target is part of an app and such app is covering the entire
|
||||
// screen. If it's not covering the entire screen the IME might extend beyond the apps
|
||||
// bounds.
|
||||
if (shouldImeAttachedToApp()) {
|
||||
if (mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
|
||||
// Do not change parent if the window hasn't requested IME.
|
||||
return null;
|
||||
}
|
||||
return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
|
||||
}
|
||||
|
||||
// Otherwise, we just attach it to where the display area policy put it.
|
||||
return mImeWindowsContainer.getParent() != null
|
||||
? mImeWindowsContainer.getParent().getSurfaceControl() : null;
|
||||
|
||||
@@ -424,14 +424,12 @@ class InsetsPolicy {
|
||||
return state;
|
||||
}
|
||||
} else if (w.mActivityRecord != null && w.mActivityRecord.mImeInsetsFrozenUntilStartInput) {
|
||||
// During switching tasks with gestural navigation, if the IME is attached to
|
||||
// one app window on that time, even the next app window is behind the IME window,
|
||||
// conceptually the window should not receive the IME insets if the next window is
|
||||
// not eligible IME requester and ready to show IME on top of it.
|
||||
final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp();
|
||||
// During switching tasks with gestural navigation, before the next IME input target
|
||||
// starts the input, we should adjust and freeze the last IME visibility of the window
|
||||
// in case delivering obsoleted IME insets state during transitioning.
|
||||
final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);
|
||||
|
||||
if (shouldImeAttachedToApp && originalImeSource != null) {
|
||||
if (originalImeSource != null) {
|
||||
final boolean imeVisibility =
|
||||
w.mActivityRecord.mLastImeShown || w.getRequestedVisibility(ITYPE_IME);
|
||||
final InsetsState state = copyState ? new InsetsState(originalState)
|
||||
|
||||
@@ -3101,11 +3101,11 @@ public class ActivityRecordTests extends WindowTestsBase {
|
||||
|
||||
// Simulate app re-start input or turning screen off/on then unlocked by un-secure
|
||||
// keyguard to back to the app, expect IME insets is not frozen
|
||||
mDisplayContent.updateImeInputAndControlTarget(app);
|
||||
assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
|
||||
imeSource.setFrame(new Rect(100, 400, 500, 500));
|
||||
app.getInsetsState().addSource(imeSource);
|
||||
app.getInsetsState().setSourceVisible(ITYPE_IME, true);
|
||||
mDisplayContent.updateImeInputAndControlTarget(app);
|
||||
assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
|
||||
|
||||
// Verify when IME is visible and the app can receive the right IME insets from policy.
|
||||
makeWindowVisibleAndDrawn(app, mImeWindow);
|
||||
|
||||
@@ -1102,6 +1102,21 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
|
||||
}
|
||||
|
||||
@UseTestDisplay(addWindows = W_ACTIVITY)
|
||||
@Test
|
||||
public void testComputeImeParent_inputTargetNotUpdate() throws Exception {
|
||||
WindowState app1 = createWindow(null, TYPE_BASE_APPLICATION, "app1");
|
||||
WindowState app2 = createWindow(null, TYPE_BASE_APPLICATION, "app2");
|
||||
doReturn(true).when(mDisplayContent).shouldImeAttachedToApp();
|
||||
mDisplayContent.setImeLayeringTarget(app1);
|
||||
mDisplayContent.setImeInputTarget(app1);
|
||||
assertEquals(app1.mActivityRecord.getSurfaceControl(), mDisplayContent.computeImeParent());
|
||||
mDisplayContent.setImeLayeringTarget(app2);
|
||||
// Expect null means no change IME parent when the IME layering target not yet
|
||||
// request IME to be the input target.
|
||||
assertNull(mDisplayContent.computeImeParent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
|
||||
@@ -945,6 +945,46 @@ public class WindowStateTests extends WindowTestsBase {
|
||||
assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdjustImeInsetsVisibilityWhenSwitchingApps_toAppInMultiWindowMode() {
|
||||
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
|
||||
final WindowState app2 = createWindow(null, WINDOWING_MODE_MULTI_WINDOW,
|
||||
ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app2");
|
||||
final WindowState imeWindow = createWindow(null, TYPE_APPLICATION, "imeWindow");
|
||||
spyOn(imeWindow);
|
||||
doReturn(true).when(imeWindow).isVisible();
|
||||
mDisplayContent.mInputMethodWindow = imeWindow;
|
||||
|
||||
final InsetsStateController controller = mDisplayContent.getInsetsStateController();
|
||||
controller.getImeSourceProvider().setWindowContainer(imeWindow, null, null);
|
||||
|
||||
// Simulate app2 in multi-window mode is going to background to switch to the fullscreen
|
||||
// app which requests IME with updating all windows Insets State when IME is above app.
|
||||
app2.mActivityRecord.mImeInsetsFrozenUntilStartInput = true;
|
||||
mDisplayContent.setImeLayeringTarget(app);
|
||||
mDisplayContent.setImeInputTarget(app);
|
||||
assertTrue(mDisplayContent.shouldImeAttachedToApp());
|
||||
controller.getImeSourceProvider().scheduleShowImePostLayout(app);
|
||||
controller.getImeSourceProvider().getSource().setVisible(true);
|
||||
controller.updateAboveInsetsState(false);
|
||||
|
||||
// Expect app windows behind IME can receive IME insets visible,
|
||||
// but not for app2 in background.
|
||||
assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
|
||||
assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
|
||||
|
||||
// Simulate app plays closing transition to app2.
|
||||
// And app2 is now IME layering target but not yet to be the IME input target.
|
||||
mDisplayContent.setImeLayeringTarget(app2);
|
||||
app.mActivityRecord.commitVisibility(false, false);
|
||||
assertTrue(app.mActivityRecord.mLastImeShown);
|
||||
assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
|
||||
|
||||
// Verify the IME insets is still visible on app, but not for app2 during task switching.
|
||||
assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
|
||||
assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
|
||||
}
|
||||
|
||||
@UseTestDisplay(addWindows = {W_ACTIVITY})
|
||||
@Test
|
||||
public void testUpdateImeControlTargetWhenLeavingMultiWindow() {
|
||||
|
||||
Reference in New Issue
Block a user