Merge "Provide startBounds for closing container with legacy transition" into tm-qpr-dev

This commit is contained in:
Chris Li
2022-12-03 02:26:52 +00:00
committed by Android (Google) Code Review
9 changed files with 173 additions and 39 deletions

View File

@@ -35,6 +35,7 @@ import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import android.annotation.ColorInt; import android.annotation.ColorInt;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.TaskInfo; import android.app.TaskInfo;
import android.app.WindowConfiguration; import android.app.WindowConfiguration;
@@ -175,10 +176,16 @@ public class RemoteAnimationTarget implements Parcelable {
public final Rect screenSpaceBounds; public final Rect screenSpaceBounds;
/** /**
* The starting bounds of the source container in screen space coordinates. This is {@code null} * The starting bounds of the source container in screen space coordinates.
* if the animation target isn't MODE_CHANGING. Since this is the starting bounds, it's size * For {@link #MODE_OPENING}, this will be equivalent to {@link #screenSpaceBounds}.
* should be equivalent to the size of the starting thumbnail. Note that sourceContainerBounds * For {@link #MODE_CLOSING}, this will be equivalent to {@link #screenSpaceBounds} unless the
* is the end bounds of a change transition. * closing container is also resizing. For example, when ActivityEmbedding split pair becomes
* stacked, the container on the back will be resized to fullscreen, but will also be covered
* (closing) by the container in the front.
* For {@link #MODE_CHANGING}, since this is the starting bounds, its size should be equivalent
* to the bounds of the starting thumbnail.
*
* Note that {@link #screenSpaceBounds} is the end bounds of a transition.
*/ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public final Rect startBounds; public final Rect startBounds;
@@ -247,7 +254,8 @@ public class RemoteAnimationTarget implements Parcelable {
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position, Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
Rect localBounds, Rect screenSpaceBounds, Rect localBounds, Rect screenSpaceBounds,
WindowConfiguration windowConfig, boolean isNotInRecents, WindowConfiguration windowConfig, boolean isNotInRecents,
SurfaceControl startLeash, Rect startBounds, ActivityManager.RunningTaskInfo taskInfo, SurfaceControl startLeash, @Nullable Rect startBounds,
ActivityManager.RunningTaskInfo taskInfo,
boolean allowEnterPip) { boolean allowEnterPip) {
this(taskId, mode, leash, isTranslucent, clipRect, contentInsets, prefixOrderIndex, this(taskId, mode, leash, isTranslucent, clipRect, contentInsets, prefixOrderIndex,
position, localBounds, screenSpaceBounds, windowConfig, isNotInRecents, startLeash, position, localBounds, screenSpaceBounds, windowConfig, isNotInRecents, startLeash,
@@ -258,7 +266,7 @@ public class RemoteAnimationTarget implements Parcelable {
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position, Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
Rect localBounds, Rect screenSpaceBounds, Rect localBounds, Rect screenSpaceBounds,
WindowConfiguration windowConfig, boolean isNotInRecents, WindowConfiguration windowConfig, boolean isNotInRecents,
SurfaceControl startLeash, Rect startBounds, SurfaceControl startLeash, @Nullable Rect startBounds,
ActivityManager.RunningTaskInfo taskInfo, boolean allowEnterPip, ActivityManager.RunningTaskInfo taskInfo, boolean allowEnterPip,
@WindowManager.LayoutParams.WindowType int windowType) { @WindowManager.LayoutParams.WindowType int windowType) {
this.mode = mode; this.mode = mode;
@@ -275,10 +283,13 @@ public class RemoteAnimationTarget implements Parcelable {
this.windowConfiguration = windowConfig; this.windowConfiguration = windowConfig;
this.isNotInRecents = isNotInRecents; this.isNotInRecents = isNotInRecents;
this.startLeash = startLeash; this.startLeash = startLeash;
this.startBounds = startBounds == null ? null : new Rect(startBounds);
this.taskInfo = taskInfo; this.taskInfo = taskInfo;
this.allowEnterPip = allowEnterPip; this.allowEnterPip = allowEnterPip;
this.windowType = windowType; this.windowType = windowType;
// Same as screenSpaceBounds if the window is not resizing.
this.startBounds = startBounds == null
? new Rect(screenSpaceBounds)
: new Rect(startBounds);
} }
public RemoteAnimationTarget(Parcel in) { public RemoteAnimationTarget(Parcel in) {
@@ -399,9 +410,7 @@ public class RemoteAnimationTarget implements Parcelable {
if (startLeash != null) { if (startLeash != null) {
startLeash.dumpDebug(proto, START_LEASH); startLeash.dumpDebug(proto, START_LEASH);
} }
if (startBounds != null) {
startBounds.dumpDebug(proto, START_BOUNDS); startBounds.dumpDebug(proto, START_BOUNDS);
}
proto.end(token); proto.end(token);
} }

View File

@@ -18,7 +18,9 @@ package androidx.window.extensions.embedding;
import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_X;
import static android.graphics.Matrix.MTRANS_Y; import static android.graphics.Matrix.MTRANS_Y;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.view.Choreographer; import android.view.Choreographer;
import android.view.RemoteAnimationTarget; import android.view.RemoteAnimationTarget;
@@ -49,6 +51,16 @@ class TaskFragmentAnimationAdapter {
/** Area in absolute coordinate that the animation surface shouldn't go beyond. */ /** Area in absolute coordinate that the animation surface shouldn't go beyond. */
@NonNull @NonNull
private final Rect mWholeAnimationBounds = new Rect(); private final Rect mWholeAnimationBounds = new Rect();
/**
* Area in absolute coordinate that should represent all the content to show for this window.
* This should be the end bounds for opening window, and start bounds for closing window in case
* the window is resizing during the open/close transition.
*/
@NonNull
private final Rect mContentBounds = new Rect();
/** Offset relative to the window parent surface for {@link #mContentBounds}. */
@NonNull
private final Point mContentRelOffset = new Point();
@NonNull @NonNull
final Transformation mTransformation = new Transformation(); final Transformation mTransformation = new Transformation();
@@ -78,6 +90,21 @@ class TaskFragmentAnimationAdapter {
mTarget = target; mTarget = target;
mLeash = leash; mLeash = leash;
mWholeAnimationBounds.set(wholeAnimationBounds); mWholeAnimationBounds.set(wholeAnimationBounds);
if (target.mode == MODE_CLOSING) {
// When it is closing, we want to show the content at the start position in case the
// window is resizing as well. For example, when the activities is changing from split
// to stack, the bottom TaskFragment will be resized to fullscreen when hiding.
final Rect startBounds = target.startBounds;
final Rect endBounds = target.screenSpaceBounds;
mContentBounds.set(startBounds);
mContentRelOffset.set(target.localBounds.left, target.localBounds.top);
mContentRelOffset.offset(
startBounds.left - endBounds.left,
startBounds.top - endBounds.top);
} else {
mContentBounds.set(target.screenSpaceBounds);
mContentRelOffset.set(target.localBounds.left, target.localBounds.top);
}
} }
/** /**
@@ -108,8 +135,7 @@ class TaskFragmentAnimationAdapter {
/** To be overridden by subclasses to adjust the animation surface change. */ /** To be overridden by subclasses to adjust the animation surface change. */
void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) { void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
// Update the surface position and alpha. // Update the surface position and alpha.
mTransformation.getMatrix().postTranslate( mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y);
mTarget.localBounds.left, mTarget.localBounds.top);
t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix); t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
t.setAlpha(mLeash, mTransformation.getAlpha()); t.setAlpha(mLeash, mTransformation.getAlpha());
@@ -117,9 +143,8 @@ class TaskFragmentAnimationAdapter {
// positionX/Y are in local coordinate, so minus the local offset to get the slide amount. // positionX/Y are in local coordinate, so minus the local offset to get the slide amount.
final int positionX = Math.round(mMatrix[MTRANS_X]); final int positionX = Math.round(mMatrix[MTRANS_X]);
final int positionY = Math.round(mMatrix[MTRANS_Y]); final int positionY = Math.round(mMatrix[MTRANS_Y]);
final Rect cropRect = new Rect(mTarget.screenSpaceBounds); final Rect cropRect = new Rect(mContentBounds);
final Rect localBounds = mTarget.localBounds; cropRect.offset(positionX - mContentRelOffset.x, positionY - mContentRelOffset.y);
cropRect.offset(positionX - localBounds.left, positionY - localBounds.top);
// Store the current offset of the surface top left from (0,0) in absolute coordinate. // Store the current offset of the surface top left from (0,0) in absolute coordinate.
final int offsetX = cropRect.left; final int offsetX = cropRect.left;

View File

@@ -17,6 +17,7 @@
package androidx.window.extensions.embedding; package androidx.window.extensions.embedding;
import static android.os.Process.THREAD_PRIORITY_DISPLAY; import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_CHANGING;
import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
@@ -254,7 +255,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
@NonNull RemoteAnimationTarget[] targets) { @NonNull RemoteAnimationTarget[] targets) {
final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>(); final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>();
for (RemoteAnimationTarget target : targets) { for (RemoteAnimationTarget target : targets) {
if (target.startBounds != null) { if (target.mode == MODE_CHANGING) {
// This is the target with bounds change. // This is the target with bounds change.
final Animation[] animations = final Animation[] animations =
mAnimationSpec.createChangeBoundsChangeAnimations(target); mAnimationSpec.createChangeBoundsChangeAnimations(target);

View File

@@ -114,8 +114,8 @@ class TaskFragmentAnimationSpec {
@NonNull @NonNull
Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) { Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) {
final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds();
// TODO(b/258126915): we want to keep track of the closing start bounds // Use startBounds if the window is closing in case it may also resize.
final Rect bounds = target.screenSpaceBounds; final Rect bounds = target.startBounds;
final int endTop; final int endTop;
final int endLeft; final int endLeft;
if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) {

View File

@@ -268,6 +268,7 @@ public class AppTransitionController {
handleClosingApps(); handleClosingApps();
handleOpeningApps(); handleOpeningApps();
handleChangingApps(transit); handleChangingApps(transit);
handleClosingChangingContainers();
appTransition.setLastAppTransition(transit, topOpeningApp, appTransition.setLastAppTransition(transit, topOpeningApp,
topClosingApp, topChangingApp); topClosingApp, topChangingApp);
@@ -287,6 +288,7 @@ public class AppTransitionController {
mDisplayContent.mClosingApps.clear(); mDisplayContent.mClosingApps.clear();
mDisplayContent.mChangingContainers.clear(); mDisplayContent.mChangingContainers.clear();
mDisplayContent.mUnknownAppVisibilityController.clear(); mDisplayContent.mUnknownAppVisibilityController.clear();
mDisplayContent.mClosingChangingContainers.clear();
// This has changed the visibility of windows, so perform // This has changed the visibility of windows, so perform
// a new layout to get them all up-to-date. // a new layout to get them all up-to-date.
@@ -1171,6 +1173,24 @@ public class AppTransitionController {
} }
} }
private void handleClosingChangingContainers() {
final ArrayMap<WindowContainer, Rect> containers =
mDisplayContent.mClosingChangingContainers;
while (!containers.isEmpty()) {
final WindowContainer container = containers.keyAt(0);
containers.remove(container);
// For closing changing windows that are part of the transition, they should have been
// removed from mClosingChangingContainers in WindowContainer#getAnimationAdapter()
// If the closing changing TaskFragment is not part of the transition, update its
// surface after removing it from mClosingChangingContainers.
final TaskFragment taskFragment = container.asTaskFragment();
if (taskFragment != null) {
taskFragment.updateOrganizedTaskFragmentSurface();
}
}
}
private void handleChangingApps(@TransitionOldType int transit) { private void handleChangingApps(@TransitionOldType int transit) {
final ArraySet<WindowContainer> apps = mDisplayContent.mChangingContainers; final ArraySet<WindowContainer> apps = mDisplayContent.mChangingContainers;
final int appsCount = apps.size(); final int appsCount = apps.size();

View File

@@ -192,6 +192,7 @@ import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.WorkSource; import android.os.WorkSource;
import android.provider.Settings; import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.DisplayUtils; import android.util.DisplayUtils;
@@ -348,6 +349,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>(); final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>(); final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>();
final UnknownAppVisibilityController mUnknownAppVisibilityController; final UnknownAppVisibilityController mUnknownAppVisibilityController;
/**
* If a container is closing when resizing, keeps track of its starting bounds when it is
* removed from {@link #mChangingContainers}.
*/
final ArrayMap<WindowContainer, Rect> mClosingChangingContainers = new ArrayMap<>();
private MetricsLogger mMetricsLogger; private MetricsLogger mMetricsLogger;

View File

@@ -103,10 +103,29 @@ class RemoteAnimationController implements DeathRecipient {
RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer, RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer,
Point position, Rect localBounds, Rect endBounds, Rect startBounds, Point position, Rect localBounds, Rect endBounds, Rect startBounds,
boolean showBackdrop) { boolean showBackdrop) {
return createRemoteAnimationRecord(windowContainer, position, localBounds, endBounds,
startBounds, showBackdrop, startBounds != null /* shouldCreateSnapshot */);
}
/**
* Creates an animation record for each individual {@link WindowContainer}.
*
* @param windowContainer The windows to animate.
* @param position The position app bounds relative to its parent.
* @param localBounds The bounds of the app relative to its parent.
* @param endBounds The end bounds after the transition, in screen coordinates.
* @param startBounds The start bounds before the transition, in screen coordinates.
* @param showBackdrop To show background behind a window during animation.
* @param shouldCreateSnapshot Whether this target should create a snapshot animation.
* @return The record representing animation(s) to run on the app.
*/
RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer,
Point position, Rect localBounds, Rect endBounds, Rect startBounds,
boolean showBackdrop, boolean shouldCreateSnapshot) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): container=%s", ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): container=%s",
windowContainer); windowContainer);
final RemoteAnimationRecord adapters = new RemoteAnimationRecord(windowContainer, position, final RemoteAnimationRecord adapters = new RemoteAnimationRecord(windowContainer, position,
localBounds, endBounds, startBounds, showBackdrop); localBounds, endBounds, startBounds, showBackdrop, shouldCreateSnapshot);
mPendingAnimations.add(adapters); mPendingAnimations.add(adapters);
return adapters; return adapters;
} }
@@ -438,14 +457,15 @@ class RemoteAnimationController implements DeathRecipient {
private @RemoteAnimationTarget.Mode int mMode = RemoteAnimationTarget.MODE_CHANGING; private @RemoteAnimationTarget.Mode int mMode = RemoteAnimationTarget.MODE_CHANGING;
RemoteAnimationRecord(WindowContainer windowContainer, Point endPos, Rect localBounds, RemoteAnimationRecord(WindowContainer windowContainer, Point endPos, Rect localBounds,
Rect endBounds, Rect startBounds, boolean showBackdrop) { Rect endBounds, @Nullable Rect startBounds, boolean showBackdrop,
boolean shouldCreateSnapshot) {
mWindowContainer = windowContainer; mWindowContainer = windowContainer;
mShowBackdrop = showBackdrop; mShowBackdrop = showBackdrop;
if (startBounds != null) { if (startBounds != null) {
mStartBounds = new Rect(startBounds); mStartBounds = new Rect(startBounds);
mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, localBounds, endBounds, mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, localBounds, endBounds,
mStartBounds, mShowBackdrop); mStartBounds, mShowBackdrop);
if (mRemoteAnimationAdapter.getChangeNeedsSnapshot()) { if (shouldCreateSnapshot && mRemoteAnimationAdapter.getChangeNeedsSnapshot()) {
final Rect thumbnailLocalBounds = new Rect(startBounds); final Rect thumbnailLocalBounds = new Rect(startBounds);
thumbnailLocalBounds.offsetTo(0, 0); thumbnailLocalBounds.offsetTo(0, 0);
// Snapshot is located at (0,0) of the animation leash. It doesn't have size // Snapshot is located at (0,0) of the animation leash. It doesn't have size

View File

@@ -2345,11 +2345,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
@Override @Override
public void onConfigurationChanged(Configuration newParentConfig) { public void onConfigurationChanged(Configuration newParentConfig) {
super.onConfigurationChanged(newParentConfig); super.onConfigurationChanged(newParentConfig);
if (mTaskFragmentOrganizer != null) {
updateOrganizedTaskFragmentSurface(); updateOrganizedTaskFragmentSurface();
}
sendTaskFragmentInfoChanged(); sendTaskFragmentInfoChanged();
} }
@@ -2362,8 +2358,13 @@ class TaskFragment extends WindowContainer<WindowContainer> {
updateOrganizedTaskFragmentSurface(); updateOrganizedTaskFragmentSurface();
} }
private void updateOrganizedTaskFragmentSurface() { /**
if (mDelayOrganizedTaskFragmentSurfaceUpdate) { * TaskFragmentOrganizer doesn't have access to the surface for security reasons, so we need to
* update its surface on the server side if it is not collected for Shell or in pending
* animation.
*/
void updateOrganizedTaskFragmentSurface() {
if (mDelayOrganizedTaskFragmentSurfaceUpdate || mTaskFragmentOrganizer == null) {
return; return;
} }
if (mTransitionController.isShellTransitionsEnabled() if (mTransitionController.isShellTransitionsEnabled()
@@ -2395,7 +2396,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return; return;
} }
final Rect bounds = getBounds(); // If this TaskFragment is closing while resizing, crop to the starting bounds instead.
final Rect bounds = isClosingWhenResizing()
? mDisplayContent.mClosingChangingContainers.get(this)
: getBounds();
final int width = bounds.width(); final int width = bounds.width();
final int height = bounds.height(); final int height = bounds.height();
if (!forceUpdate && width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) { if (!forceUpdate && width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
@@ -2443,6 +2447,15 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|| endBounds.height() != startBounds.height(); || endBounds.height() != startBounds.height();
} }
/** Records the starting bounds of the closing organized TaskFragment. */
void setClosingChangingStartBoundsIfNeeded() {
if (isOrganizedTaskFragment() && mDisplayContent != null
&& mDisplayContent.mChangingContainers.remove(this)) {
mDisplayContent.mClosingChangingContainers.put(
this, new Rect(mSurfaceFreezer.mFreezeBounds));
}
}
@Override @Override
boolean isSyncFinished() { boolean isSyncFinished() {
return super.isSyncFinished() && isReadyToTransit(); return super.isSyncFinished() && isReadyToTransit();

View File

@@ -810,6 +810,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void removeImmediately() { void removeImmediately() {
final DisplayContent dc = getDisplayContent(); final DisplayContent dc = getDisplayContent();
if (dc != null) { if (dc != null) {
dc.mClosingChangingContainers.remove(this);
mSurfaceFreezer.unfreeze(getSyncTransaction()); mSurfaceFreezer.unfreeze(getSyncTransaction());
} }
while (!mChildren.isEmpty()) { while (!mChildren.isEmpty()) {
@@ -1019,10 +1020,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @param dc The display this container is on after changes. * @param dc The display this container is on after changes.
*/ */
void onDisplayChanged(DisplayContent dc) { void onDisplayChanged(DisplayContent dc) {
if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) { if (mDisplayContent != null) {
mDisplayContent.mClosingChangingContainers.remove(this);
if (mDisplayContent.mChangingContainers.remove(this)) {
// Cancel any change transition queued-up for this container on the old display. // Cancel any change transition queued-up for this container on the old display.
mSurfaceFreezer.unfreeze(getSyncTransaction()); mSurfaceFreezer.unfreeze(getSyncTransaction());
} }
}
mDisplayContent = dc; mDisplayContent = dc;
if (dc != null && dc != this) { if (dc != null && dc != this) {
dc.getPendingTransaction().merge(mPendingTransaction); dc.getPendingTransaction().merge(mPendingTransaction);
@@ -1298,6 +1302,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// If we are losing visibility, then a snapshot isn't necessary and we are no-longer // If we are losing visibility, then a snapshot isn't necessary and we are no-longer
// part of a change transition. // part of a change transition.
if (!visible) { if (!visible) {
if (asTaskFragment() != null) {
// If the organized TaskFragment is closing while resizing, we want to keep track of
// its starting bounds to make sure the animation starts at the correct position.
// This should be called before unfreeze() because we record the starting bounds
// in SurfaceFreezer.
asTaskFragment().setClosingChangingStartBoundsIfNeeded();
}
mSurfaceFreezer.unfreeze(getSyncTransaction()); mSurfaceFreezer.unfreeze(getSyncTransaction());
} }
WindowContainer parent = getParent(); WindowContainer parent = getParent();
@@ -1306,6 +1317,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
} }
} }
/** Whether this window is closing while resizing. */
boolean isClosingWhenResizing() {
return mDisplayContent != null
&& mDisplayContent.mClosingChangingContainers.containsKey(this);
}
void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) { void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId); final long token = proto.start(fieldId);
proto.write(HASH_CODE, System.identityHashCode(this)); proto.write(HASH_CODE, System.identityHashCode(this));
@@ -3004,10 +3021,22 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
} }
final Rect localBounds = new Rect(mTmpRect); final Rect localBounds = new Rect(mTmpRect);
localBounds.offsetTo(mTmpPoint.x, mTmpPoint.y); localBounds.offsetTo(mTmpPoint.x, mTmpPoint.y);
final RemoteAnimationController.RemoteAnimationRecord adapters = final RemoteAnimationController.RemoteAnimationRecord adapters;
controller.createRemoteAnimationRecord( if (!isChanging && !enter && isClosingWhenResizing()) {
this, mTmpPoint, localBounds, screenBounds, // Container that is closing while resizing. Pass in the closing start bounds, so
(isChanging ? mSurfaceFreezer.mFreezeBounds : null), showBackdrop); // the animation can start with the correct bounds, there won't be a snapshot.
// Cleanup the mClosingChangingContainers so that when the animation is finished, it
// will reset the surface.
final Rect closingStartBounds = getDisplayContent().mClosingChangingContainers
.remove(this);
adapters = controller.createRemoteAnimationRecord(
this, mTmpPoint, localBounds, screenBounds, closingStartBounds,
showBackdrop, false /* shouldCreateSnapshot */);
} else {
final Rect startBounds = isChanging ? mSurfaceFreezer.mFreezeBounds : null;
adapters = controller.createRemoteAnimationRecord(
this, mTmpPoint, localBounds, screenBounds, startBounds, showBackdrop);
}
if (backdropColor != 0) { if (backdropColor != 0) {
adapters.setBackDropColor(backdropColor); adapters.setBackDropColor(backdropColor);
} }
@@ -3464,7 +3493,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
return; return;
} }
if (isClosingWhenResizing()) {
// This container is closing while resizing, keep its surface at the starting position
// to prevent animation flicker.
getRelativePosition(mDisplayContent.mClosingChangingContainers.get(this), mTmpPos);
} else {
getRelativePosition(mTmpPos); getRelativePosition(mTmpPos);
}
final int deltaRotation = getRelativeDisplayRotation(); final int deltaRotation = getRelativeDisplayRotation();
if (mTmpPos.equals(mLastSurfacePosition) && deltaRotation == mLastDeltaRotation) { if (mTmpPos.equals(mLastSurfacePosition) && deltaRotation == mLastDeltaRotation) {
return; return;
@@ -3529,9 +3564,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
outSurfaceInsets.setEmpty(); outSurfaceInsets.setEmpty();
} }
/** Gets the position of this container in its parent's coordinate. */
void getRelativePosition(Point outPos) { void getRelativePosition(Point outPos) {
final Rect dispBounds = getBounds(); getRelativePosition(getBounds(), outPos);
outPos.set(dispBounds.left, dispBounds.top); }
/** Gets the position of {@code curBounds} in this container's parent's coordinate. */
void getRelativePosition(Rect curBounds, Point outPos) {
outPos.set(curBounds.left, curBounds.top);
final WindowContainer parent = getParent(); final WindowContainer parent = getParent();
if (parent != null) { if (parent != null) {
final Rect parentBounds = parent.getBounds(); final Rect parentBounds = parent.getBounds();