Attach IME screenshot to non-app main window
In case when dismissing dialog styled application window can see the IME animated with fade-out as a part of the dialog. Bug: 201139553 Bug: 212570341 Test: manual as steps with launching a dialog: 1) Launch Settings -> Network & internet -> Private DNS 2) Tap the editor to show IME 3) Press Cancel button to see if IME screenshot is anmating Change-Id: Ib4c38736908be52f8cbcfe522f4515c5b9aa4e63
This commit is contained in:
@@ -131,6 +131,7 @@ import static com.android.server.wm.DisplayContentProto.SLEEP_TOKENS;
|
||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
|
||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
|
||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
|
||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
|
||||
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
|
||||
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
|
||||
import static com.android.server.wm.WindowContainerChildProto.DISPLAY_CONTENT;
|
||||
@@ -4014,9 +4015,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
// If the IME target is the input target, before it changes, prepare the IME screenshot
|
||||
// for the last IME target when its task is applying app transition. This is for the
|
||||
// better IME transition to keep IME visibility when transitioning to the next task.
|
||||
if (mImeLayeringTarget != null && mImeLayeringTarget.inAppOrRecentsTransition()
|
||||
&& mImeLayeringTarget == mImeInputTarget) {
|
||||
showImeScreenshot();
|
||||
if (mImeLayeringTarget != null && mImeLayeringTarget == mImeInputTarget) {
|
||||
boolean nonAppImeTargetAnimatingExit = mImeLayeringTarget.mAnimatingExit
|
||||
&& mImeLayeringTarget.mAttrs.type != TYPE_BASE_APPLICATION
|
||||
&& mImeLayeringTarget.isSelfAnimating(0, ANIMATION_TYPE_WINDOW_ANIMATION);
|
||||
if (mImeLayeringTarget.inAppOrRecentsTransition() || nonAppImeTargetAnimatingExit) {
|
||||
showImeScreenshot();
|
||||
}
|
||||
}
|
||||
|
||||
ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target);
|
||||
@@ -4078,6 +4083,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
mImeTarget = imeTarget;
|
||||
}
|
||||
|
||||
WindowState getImeTarget() {
|
||||
return mImeTarget;
|
||||
}
|
||||
|
||||
private SurfaceControl createImeSurface(SurfaceControl.ScreenshotHardwareBuffer b,
|
||||
Transaction t) {
|
||||
final HardwareBuffer buffer = b.getHardwareBuffer();
|
||||
@@ -4088,11 +4097,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
}
|
||||
final WindowState imeWindow = mImeTarget.getDisplayContent().mInputMethodWindow;
|
||||
final ActivityRecord activity = mImeTarget.mActivityRecord;
|
||||
final SurfaceControl imeParent = mImeTarget.mAttrs.type == TYPE_BASE_APPLICATION
|
||||
? activity.getSurfaceControl()
|
||||
: mImeTarget.getSurfaceControl();
|
||||
final SurfaceControl imeSurface = mSurfaceBuilder
|
||||
.setName("IME-snapshot-surface")
|
||||
.setBLASTLayer()
|
||||
.setFormat(buffer.getFormat())
|
||||
.setParent(activity.getSurfaceControl())
|
||||
// Attaching IME snapshot to the associated IME layering target on the
|
||||
// activity when:
|
||||
// - The target is activity main window: attaching on top of the activity.
|
||||
// - The target is non-activity main window (e.g. activity overlay or
|
||||
// dialog-themed activity): attaching on top of the target since the layer has
|
||||
// already above the activity.
|
||||
.setParent(imeParent)
|
||||
.setCallsite("DisplayContent.attachAndShowImeScreenshotOnTarget")
|
||||
.build();
|
||||
// Make IME snapshot as trusted overlay
|
||||
@@ -4101,9 +4119,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
t.setBuffer(imeSurface, buffer);
|
||||
t.setColorSpace(activity.mSurfaceControl, ColorSpace.get(ColorSpace.Named.SRGB));
|
||||
t.setLayer(imeSurface, 1);
|
||||
t.setPosition(imeSurface, imeWindow.getFrame().left - mImeTarget.getFrame().left,
|
||||
imeWindow.getFrame().top - mImeTarget.getFrame().top);
|
||||
|
||||
final Point surfacePosition = new Point(
|
||||
imeWindow.getFrame().left - mImeTarget.getFrame().left,
|
||||
imeWindow.getFrame().top - mImeTarget.getFrame().top);
|
||||
if (imeParent == activity.getSurfaceControl()) {
|
||||
t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
|
||||
} else {
|
||||
surfacePosition.offset(mImeTarget.mAttrs.surfaceInsets.left,
|
||||
mImeTarget.mAttrs.surfaceInsets.top);
|
||||
t.setPosition(imeSurface, surfacePosition.x, surfacePosition.y);
|
||||
}
|
||||
return imeSurface;
|
||||
}
|
||||
|
||||
@@ -4195,7 +4221,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
/** Removes the IME screenshot immediately. */
|
||||
void removeImeSurfaceImmediately() {
|
||||
if (mImeScreenshot != null) {
|
||||
if (DEBUG_INPUT_METHOD) Slog.d(TAG, "remove IME snapshot");
|
||||
mImeScreenshot.detach(getSyncTransaction());
|
||||
mImeScreenshot = null;
|
||||
}
|
||||
@@ -4509,7 +4534,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
* hierarchy.
|
||||
*/
|
||||
void onWindowAnimationFinished(@NonNull WindowContainer wc, int type) {
|
||||
if (type == ANIMATION_TYPE_APP_TRANSITION || type == ANIMATION_TYPE_RECENTS) {
|
||||
if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
|
||||
|| wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
|
||||
&& (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
|
||||
removeImeSurfaceImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1968,6 +1968,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
|
||||
appWin2.setHasSurface(true);
|
||||
assertTrue(appWin2.canBeImeTarget());
|
||||
doReturn(true).when(appWin1).isClosing();
|
||||
doReturn(true).when(appWin1).inAppOrRecentsTransition();
|
||||
|
||||
// Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
|
||||
|
||||
Reference in New Issue
Block a user