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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) -> {
|
||||
|
||||
Reference in New Issue
Block a user