Merge "Fix some IME transition issues" into sc-dev am: 66dc0f32ed

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14455599

Change-Id: I5699244bfa060c0d6aa7c674e1c1c0a8b5c840c3
This commit is contained in:
Ming-Shin Lu
2021-05-14 13:27:28 +00:00
committed by Automerger Merge Worker
7 changed files with 29 additions and 13 deletions

View File

@@ -6865,7 +6865,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
// An activity in size compatibility mode may have override bounds which equals to its
// parent bounds, so the exact bounds should also be checked to allow IME window to attach
// to the activity. See {@link DisplayContent#isImeAttachedToApp}.
// to the activity. See {@link DisplayContent#shouldImeAttachedToApp}.
final WindowContainer parent = getParent();
return parent == null || parent.getBounds().equals(overrideBounds);
}

View File

@@ -1539,7 +1539,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// to cover the activity configuration change.
return false;
}
if (r.mStartingData != null && r.mStartingData.hasImeSurface()) {
if ((r.mStartingData != null && r.mStartingData.hasImeSurface())
|| (mInsetsStateController.getImeSourceProvider()
.getSource().getVisibleFrame() != null)) {
// Currently it is unknown that when will IME window be ready. Reject the case to
// avoid flickering by showing IME in inconsistent orientation.
return false;
@@ -3633,7 +3635,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return mImeInputTarget != null && !mImeInputTarget.inMultiWindowMode();
}
boolean isImeAttachedToApp() {
boolean shouldImeAttachedToApp() {
return isImeControlledByApp()
&& mImeLayeringTarget != null
&& mImeLayeringTarget.mActivityRecord != null
@@ -3646,6 +3648,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
&& mImeLayeringTarget.matchesDisplayAreaBounds();
}
/**
* Unlike {@link #shouldImeAttachedToApp()}, this method returns {@code @true} only when both
* the IME layering target is valid to attach the IME surface to the app, and the
* {@link #mInputMethodSurfaceParent} of the {@link ImeContainer} has actually attached to
* the app. (i.e. Even if {@link #shouldImeAttachedToApp()} returns {@code true}, calling this
* method will return {@code false} if the IME surface doesn't actually attach to the app.)
*/
boolean isImeAttachedToApp() {
return shouldImeAttachedToApp()
&& mInputMethodSurfaceParent != null
&& mInputMethodSurfaceParent.isSameSurface(
mImeLayeringTarget.mActivityRecord.getSurfaceControl());
}
/**
* Finds the window which can host IME if IME target cannot host it.
* e.g. IME target cannot host IME when it's display has a parent display OR when display
@@ -3774,7 +3790,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@VisibleForTesting
void attachAndShowImeScreenshotOnTarget() {
// No need to attach screenshot if the IME target not exists or screen is off.
if (!isImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
return;
}
@@ -3942,7 +3958,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// 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 (allowAttachToApp && isImeAttachedToApp()) {
if (allowAttachToApp && shouldImeAttachedToApp()) {
return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
}

View File

@@ -425,7 +425,7 @@ class TaskSnapshotController {
final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;
// Exclude IME window snapshot when IME isn't proper to attach to app.
final boolean excludeIme = imeWindow != null && imeWindow.getSurfaceControl() != null
&& !task.getDisplayContent().isImeAttachedToApp();
&& !task.getDisplayContent().shouldImeAttachedToApp();
final WindowState navWindow =
task.getDisplayContent().getDisplayPolicy().getNavigationBar();
// If config_attachNavBarToAppDuringTransition is true, the nav bar will be reparent to the

View File

@@ -2309,7 +2309,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// When the window configuration changed, we need to update the IME control target in
// case the app may lose the IME inets control when exiting from split-screen mode, or the
// IME parent may failed to attach to the app during rotating the screen.
// See DisplayContent#isImeAttachedToApp, DisplayContent#isImeControlledByApp
// See DisplayContent#shouldImeAttachedToApp, DisplayContent#isImeControlledByApp
if (windowConfigChanged) {
getDisplayContent().updateImeControlTarget();
}

View File

@@ -1904,7 +1904,7 @@ public class DisplayContentTests extends WindowTestsBase {
mDisplayContent.setImeInputTarget(appWin2);
mDisplayContent.computeImeTarget(true);
assertEquals(appWin2, mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
assertTrue(mDisplayContent.isImeAttachedToApp());
assertTrue(mDisplayContent.shouldImeAttachedToApp());
verify(mDisplayContent, atLeast(1)).attachAndShowImeScreenshotOnTarget();
verify(mWm.mTaskSnapshotController).snapshotImeFromAttachedTask(appWin1.getTask());

View File

@@ -316,14 +316,14 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
assertFalse(mActivity.mDisplayContent.shouldImeAttachedToApp());
// Recompute the natural configuration without resolving size compat configuration.
mActivity.clearSizeCompatMode();
mActivity.onConfigurationChanged(mTask.getConfiguration());
// It should keep non-attachable because the resolved bounds will be computed according to
// the aspect ratio that won't match its parent bounds.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
assertFalse(mActivity.mDisplayContent.shouldImeAttachedToApp());
// Activity max bounds should be sandboxed since it is letterboxed.
assertActivityMaxBoundsSandboxed();
}
@@ -358,7 +358,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Because the aspect ratio of display doesn't exceed the max aspect ratio of activity.
// The activity should still fill its parent container and IME can attach to the activity.
assertTrue(mActivity.matchParentBounds());
assertTrue(mActivity.mDisplayContent.isImeAttachedToApp());
assertTrue(mActivity.mDisplayContent.shouldImeAttachedToApp());
final Rect letterboxInnerBounds = new Rect();
mActivity.getLetterboxInnerBounds(letterboxInnerBounds);

View File

@@ -193,7 +193,7 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
Task task = mAppWindow.mActivityRecord.getTask();
spyOn(task);
spyOn(mDisplayContent);
when(task.getDisplayContent().isImeAttachedToApp()).thenReturn(false);
when(task.getDisplayContent().shouldImeAttachedToApp()).thenReturn(false);
// Intentionally set the SurfaceControl of input method window as null.
mDisplayContent.mInputMethodWindow.setSurfaceControl(null);
// Verify no NPE happens when calling createTaskSnapshot.
@@ -213,7 +213,7 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
spyOn(task);
spyOn(mDisplayContent);
spyOn(mDisplayContent.mInputMethodWindow);
when(task.getDisplayContent().isImeAttachedToApp()).thenReturn(true);
when(task.getDisplayContent().shouldImeAttachedToApp()).thenReturn(true);
// Intentionally set the IME window is in drawn state.
doReturn(true).when(mDisplayContent.mInputMethodWindow).isDrawn();
// Verify no NPE happens when calling createTaskSnapshot.