Merge "RESTRICT AUTOMERGE: Polish IME transition from fullscreen task to split-screen task" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2022-03-25 19:52:44 +00:00
committed by Android (Google) Code Review
5 changed files with 67 additions and 13 deletions

View File

@@ -4193,17 +4193,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
@VisibleForTesting
SurfaceControl computeImeParent() {
if (mImeLayeringTarget != null && mImeInputTarget != null
&& mImeLayeringTarget.mActivityRecord != mImeInputTarget.mActivityRecord) {
// 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.mActivityRecord) {
// 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;

View File

@@ -265,14 +265,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)

View File

@@ -3065,11 +3065,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);

View File

@@ -1075,6 +1075,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();

View File

@@ -931,6 +931,47 @@ public class WindowStateTests extends WindowTestsBase {
@UseTestDisplay(addWindows = { W_ACTIVITY })
@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().setWindow(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(imeWindow, 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() {
WindowState app = createWindow(null, TYPE_BASE_APPLICATION,
mAppWindow.mToken, "app");