Merge "Account for task and inset crops in default legacy task animations" into sc-v2-dev am: 0759523698

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

Change-Id: Id50856a3d62955b3627d83b921ea03068a65d93f
This commit is contained in:
Pablo Gamito
2021-11-05 13:49:07 +00:00
committed by Automerger Merge Worker
4 changed files with 128 additions and 0 deletions

View File

@@ -39,6 +39,7 @@ public class TaskTransitionSpec implements Parcelable {
/**
* TEMPORARY FIELD (b/202383002)
* TODO: Remove once we use surfaceflinger rounded corners on tasks rather than taskbar overlays
* or when shell transitions are fully enabled
*
* A set of {@InsetsState.InternalInsetsType}s we want to use as the source to set the bounds
* of the task during the animation. Used to make sure that task animate above the taskbar.

View File

@@ -108,6 +108,16 @@ class InsetsSourceProvider {
private final boolean mControllable;
/**
* Whether to forced the dimensions of the source window to the inset frame and crop out any
* overflow.
* Used to crop the taskbar inset source when a task animation is occurring to hide the taskbar
* rounded corners overlays.
*
* TODO: Remove when we enable shell transitions (b/202383002)
*/
private boolean mCropToProvidingInsets = false;
InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
DisplayContent displayContent) {
mClientVisible = InsetsState.getDefaultVisibility(source.getType());
@@ -303,6 +313,62 @@ class InsetsSourceProvider {
mFakeControlTarget = fakeTarget;
}
/**
* Ensures that the inset source window is cropped so that anything that doesn't fit within the
* inset frame is cropped out until removeCropToProvidingInsetsBounds is called.
*
* The inset source surface will get cropped to the be of the size of the insets it's providing.
*
* For example, for the taskbar window which serves as the ITYPE_EXTRA_NAVIGATION_BAR inset
* source, the window is larger than the insets because of the rounded corners overlay, but
* during task animations we want to make sure that the overlay is cropped out of the window so
* that they don't hide the window animations.
*
* @param t The transaction to use to apply immediate overflow cropping operations.
*
* NOTE: The relies on the inset source window to have a leash (usually this would be a leash
* for the ANIMATION_TYPE_INSETS_CONTROL animation if the inset is controlled by the client)
*
* TODO: Remove when we migrate over to shell transitions (b/202383002)
*/
void setCropToProvidingInsetsBounds(Transaction t) {
mCropToProvidingInsets = true;
if (mWin != null && mWin.mSurfaceAnimator.hasLeash()) {
// apply to existing leash
t.setWindowCrop(mWin.mSurfaceAnimator.mLeash, getProvidingInsetsBoundsCropRect());
}
}
/**
* Removes any overflow cropping and future cropping to the inset source window's leash that may
* have been set with a call to setCropToProvidingInsetsBounds().
* @param t The transaction to use to apply immediate removal of overflow cropping.
*
* TODO: Remove when we migrate over to shell transitions (b/202383002)
*/
void removeCropToProvidingInsetsBounds(Transaction t) {
mCropToProvidingInsets = false;
// apply to existing leash
if (mWin != null && mWin.mSurfaceAnimator.hasLeash()) {
t.setWindowCrop(mWin.mSurfaceAnimator.mLeash, null);
}
}
private Rect getProvidingInsetsBoundsCropRect() {
Rect sourceWindowFrame = mWin.getFrame();
Rect insetFrame = getSource().getFrame();
// The rectangle in buffer space we want to crop to
return new Rect(
insetFrame.left - sourceWindowFrame.left,
insetFrame.top - sourceWindowFrame.top,
insetFrame.right - sourceWindowFrame.left,
insetFrame.bottom - sourceWindowFrame.top
);
}
void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force) {
if (mSeamlessRotating) {
// We are un-rotating the window against the display rotation. We don't want the target
@@ -548,6 +614,11 @@ class InsetsSourceProvider {
mCapturedLeash = animationLeash;
t.setPosition(mCapturedLeash, mSurfacePosition.x, mSurfacePosition.y);
if (mCropToProvidingInsets) {
// Apply crop to hide overflow
t.setWindowCrop(mCapturedLeash, getProvidingInsetsBoundsCropRect());
}
}
@Override

View File

@@ -155,6 +155,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
@@ -178,9 +179,11 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.RemoteAnimationAdapter;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.TaskTransitionSpec;
import android.view.WindowManager;
import android.view.WindowManager.TransitionOldType;
import android.window.ITaskOrganizer;
@@ -2822,6 +2825,30 @@ class Task extends TaskFragment {
return;
}
/**
* Account for specified insets to crop the animation bounds by to avoid the animation
* occurring over "out of bounds" regions
*
* For example this is used to make sure the tasks are cropped to be fully above the
* taskbar when animating.
*
* @param animationBounds The animations bounds to adjust to account for the custom spec insets.
*/
void adjustAnimationBoundsForTransition(Rect animationBounds) {
TaskTransitionSpec spec = mWmService.mTaskTransitionSpec;
if (spec != null) {
for (@InsetsState.InternalInsetsType int insetType : spec.animationBoundInsets) {
InsetsSourceProvider insetProvider = getDisplayContent()
.getInsetsStateController()
.getSourceProvider(insetType);
Insets insets = insetProvider.getSource().calculateVisibleInsets(
animationBounds);
animationBounds.inset(insets);
}
}
}
void setDragResizing(boolean dragResizing, int dragResizeMode) {
if (mDragResizing != dragResizing) {
// No need to check if the mode is allowed if it's leaving dragResize

View File

@@ -108,6 +108,7 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -2731,6 +2732,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// Separate position and size for use in animators.
final Rect screenBounds = getAnimationBounds(appRootTaskClipMode);
mTmpRect.set(screenBounds);
if (this.asTask() != null && isTaskTransitOld(transit)) {
this.asTask().adjustAnimationBoundsForTransition(mTmpRect);
}
getAnimationPosition(mTmpPoint);
mTmpRect.offsetTo(0, 0);
@@ -2826,6 +2830,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
if (isTaskTransitOld(transit)) {
animationRunnerBuilder.setTaskBackgroundColor(getTaskAnimationBackgroundColor());
// TODO: Remove when we migrate to shell (b/202383002)
if (mWmService.mTaskTransitionSpec != null) {
animationRunnerBuilder.hideInsetSourceViewOverflows(
mWmService.mTaskTransitionSpec.animationBoundInsets);
}
}
animationRunnerBuilder.build()
@@ -3570,6 +3579,26 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
}
}
private void hideInsetSourceViewOverflows(Set<Integer> insetTypes) {
final ArrayList<SurfaceControl> surfaceControls =
new ArrayList<>(insetTypes.size());
for (int insetType : insetTypes) {
InsetsSourceProvider insetProvider = getDisplayContent().getInsetsStateController()
.getSourceProvider(insetType);
// Will apply it immediately to current leash and to all future inset animations
// until we disable it.
insetProvider.setCropToProvidingInsetsBounds(getPendingTransaction());
// Only clear the size restriction of the inset once the surface animation is over
// and not if it's canceled to be replace by another animation.
mOnAnimationFinished.add(() -> {
insetProvider.removeCropToProvidingInsetsBounds(getPendingTransaction());
});
}
}
private IAnimationStarter build() {
return (Transaction t, AnimationAdapter adapter, boolean hidden,
@AnimationType int type, @Nullable AnimationAdapter snapshotAnim) -> {