Loading core/java/android/view/TaskTransitionSpec.java +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading services/core/java/com/android/server/wm/InsetsSourceProvider.java +71 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 Loading Loading @@ -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 Loading services/core/java/com/android/server/wm/Task.java +27 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -2819,6 +2822,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 Loading services/core/java/com/android/server/wm/WindowContainer.java +29 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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() Loading Loading @@ -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) -> { Loading Loading
core/java/android/view/TaskTransitionSpec.java +1 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
services/core/java/com/android/server/wm/InsetsSourceProvider.java +71 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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 Loading Loading @@ -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 Loading
services/core/java/com/android/server/wm/Task.java +27 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -2819,6 +2822,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 Loading
services/core/java/com/android/server/wm/WindowContainer.java +29 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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() Loading Loading @@ -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) -> { Loading