diff --git a/core/api/current.txt b/core/api/current.txt index e0572e46b5359..4d27dde716288 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1314,6 +1314,7 @@ package android { field public static final int shouldDisableView = 16843246; // 0x10101ee field public static final int shouldUseDefaultUnfoldTransition = 16844364; // 0x101064c field public static final int showAsAction = 16843481; // 0x10102d9 + field public static final int showBackground; field public static final int showClockAndComplications; field public static final int showDefault = 16843258; // 0x10101fa field public static final int showDividers = 16843561; // 0x1010329 @@ -52508,6 +52509,7 @@ package android.view.animation { method public int getRepeatCount(); method public int getRepeatMode(); method protected float getScaleFactor(); + method public boolean getShowBackground(); method public long getStartOffset(); method public long getStartTime(); method public boolean getTransformation(long, android.view.animation.Transformation); @@ -52533,6 +52535,7 @@ package android.view.animation { method public void setInterpolator(android.view.animation.Interpolator); method public void setRepeatCount(int); method public void setRepeatMode(int); + method public void setShowBackground(boolean); method public void setStartOffset(long); method public void setStartTime(long); method public void setZAdjustment(int); diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index b1d618eff40a6..ab749ee284a86 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -209,6 +209,13 @@ public abstract class Animation implements Cloneable { private boolean mShowWallpaper; private boolean mHasRoundedCorners; + /** + * Whether to show a background behind the windows during the animation. + * @see #getShowBackground() + * @see #setShowBackground(boolean) + */ + private boolean mShowBackground; + private boolean mMore = true; private boolean mOneMoreTime = true; @@ -266,6 +273,8 @@ public abstract class Animation implements Cloneable { a.getBoolean(com.android.internal.R.styleable.Animation_showWallpaper, false)); setHasRoundedCorners( a.getBoolean(com.android.internal.R.styleable.Animation_hasRoundedCorners, false)); + setShowBackground( + a.getBoolean(com.android.internal.R.styleable.Animation_showBackground, false)); final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0); @@ -697,6 +706,24 @@ public abstract class Animation implements Cloneable { mHasRoundedCorners = hasRoundedCorners; } + /** + * If showBackground is {@code true} and this animation is applied on a window, then the windows + * in the animation will animate with the background associated with this window behind them. + * + * The background comes from the {@link android.R.styleable#Theme_colorBackground} that is + * applied to this window through its theme. + * + * If multiple animating windows have showBackground set to {@code true} during an animation, + * the top most window with showBackground set to {@code true} and a valid background color + * takes precedence. + * + * @param showBackground Whether to show a background behind the windows during the animation. + * @attr ref android.R.styleable#Animation_showBackground + */ + public void setShowBackground(boolean showBackground) { + mShowBackground = showBackground; + } + /** * Gets the acceleration curve type for this animation. * @@ -837,6 +864,24 @@ public abstract class Animation implements Cloneable { return mHasRoundedCorners; } + /** + * If showBackground is {@code true} and this animation is applied on a window, then the windows + * in the animation will animate with the background associated with this window behind them. + * + * The background comes from the {@link android.R.styleable#Theme_colorBackground} that is + * applied to this window through its theme. + * + * If multiple animating windows have showBackground set to {@code true} during an animation, + * the top most window with showBackground set to {@code true} and a valid background color + * takes precedence. + * + * @return if the background of this window should be shown behind the animating windows. + * @attr ref android.R.styleable#Animation_showBackground + */ + public boolean getShowBackground() { + return mShowBackground; + } + /** *

Indicates whether or not this animation will affect the transformation * matrix. For instance, a fade animation will not affect the matrix whereas diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 915c8fb9a6dd1..fd1e848221938 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -36,6 +36,7 @@ import static android.view.WindowManager.TransitionFlags; import static android.view.WindowManager.TransitionType; import static android.view.WindowManager.transitTypeToString; +import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -366,6 +367,7 @@ public final class TransitionInfo implements Parcelable { private int mStartRotation = ROTATION_UNDEFINED; private int mEndRotation = ROTATION_UNDEFINED; private int mRotationAnimation = ROTATION_ANIMATION_UNSPECIFIED; + private @ColorInt int mBackgroundColor; public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { mContainer = container; @@ -387,6 +389,7 @@ public final class TransitionInfo implements Parcelable { mStartRotation = in.readInt(); mEndRotation = in.readInt(); mRotationAnimation = in.readInt(); + mBackgroundColor = in.readInt(); } /** Sets the parent of this change's container. The parent must be a participant or null. */ @@ -446,6 +449,11 @@ public final class TransitionInfo implements Parcelable { mRotationAnimation = anim; } + /** Sets the background color of this change's container. */ + public void setBackgroundColor(@ColorInt int backgroundColor) { + mBackgroundColor = backgroundColor; + } + /** @return the container that is changing. May be null if non-remotable (eg. activity) */ @Nullable public WindowContainerToken getContainer() { @@ -526,6 +534,12 @@ public final class TransitionInfo implements Parcelable { return mRotationAnimation; } + /** @return get the background color of this change's container. */ + @ColorInt + public int getBackgroundColor() { + return mBackgroundColor; + } + /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { @@ -542,6 +556,7 @@ public final class TransitionInfo implements Parcelable { dest.writeInt(mStartRotation); dest.writeInt(mEndRotation); dest.writeInt(mRotationAnimation); + dest.writeInt(mBackgroundColor); } @NonNull diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index d2dc6005f3f3a..a08bca3b3fe94 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -6884,6 +6884,9 @@ + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index dfeeccf80423c..e801ac0ba71a6 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3254,6 +3254,7 @@ + diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 11b23875437f9..5054e60d09f88 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -291,8 +291,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); }; - boolean requireBackgroundForTransition = false; - + @ColorInt int backgroundColorForTransition = 0; final int wallpaperTransit = getWallpaperTransitType(info); for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); @@ -352,8 +351,19 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { Animation a = loadAnimation(info, change, wallpaperTransit); if (a != null) { - if (changeRequiresBackground(info, change)) { - requireBackgroundForTransition = true; + if (isTask) { + final @TransitionType int type = info.getType(); + final boolean isOpenOrCloseTransition = type == TRANSIT_OPEN + || type == TRANSIT_CLOSE + || type == TRANSIT_TO_FRONT + || type == TRANSIT_TO_BACK; + if (isOpenOrCloseTransition) { + // Use the overview background as the background for the animation + final Context uiContext = ActivityThread.currentActivityThread() + .getSystemUiContext(); + backgroundColorForTransition = + uiContext.getColor(R.color.overview_background); + } } float cornerRadius = 0; @@ -365,6 +375,15 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { ScreenDecorationsUtils.getWindowCornerRadius(displayContext); } + if (a.getShowBackground()) { + // use the window's background color if provided as the background color for the + // animation - the top most window with a valid background color and + // showBackground set takes precedence. + if (change.getBackgroundColor() != 0) { + backgroundColorForTransition = change.getBackgroundColor(); + } + } + startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish, mTransactionPool, mMainExecutor, mAnimExecutor, null /* position */, cornerRadius, change.getEndAbsBounds()); @@ -376,8 +395,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } } - if (requireBackgroundForTransition) { - addBackgroundToTransition(info.getRootLeash(), startTransaction, finishTransaction); + if (backgroundColorForTransition != 0) { + addBackgroundToTransition(info.getRootLeash(), backgroundColorForTransition, + startTransaction, finishTransaction); } startTransaction.apply(); @@ -388,24 +408,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { return true; } - private boolean changeRequiresBackground(TransitionInfo info, - TransitionInfo.Change change) { - final boolean isTask = change.getTaskInfo() != null; - final @TransitionType int type = info.getType(); - final boolean isOpenOrCloseTransition = type == TRANSIT_OPEN || type == TRANSIT_CLOSE - || type == TRANSIT_TO_FRONT || type == TRANSIT_TO_BACK; - return isTask && isOpenOrCloseTransition; - } - private void addBackgroundToTransition( @NonNull SurfaceControl rootLeash, + @ColorInt int color, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction ) { - final Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext(); - final @ColorInt int overviewBackgroundColor = - uiContext.getColor(R.color.overview_background); - final Color bgColor = Color.valueOf(overviewBackgroundColor); + final Color bgColor = Color.valueOf(color); final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() }; final SurfaceControl animationBackgroundSurface = new SurfaceControl.Builder() diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index a4771082b3e93..b13c9a9e3e14e 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -79,6 +79,7 @@ import android.window.RemoteTransition; import android.window.TransitionInfo; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.graphics.ColorUtils; import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.function.pooled.PooledLambda; @@ -1271,6 +1272,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe change.setAllowEnterPip(topMostActivity != null && topMostActivity.checkEnterPictureInPictureAppOpsState()); } + final ActivityRecord activityRecord = target.asActivityRecord(); + if (activityRecord != null) { + final Task arTask = activityRecord.getTask(); + final int backgroundColor = ColorUtils.setAlphaComponent( + arTask.getTaskDescription().getBackgroundColor(), 255); + change.setBackgroundColor(backgroundColor); + } + out.addChange(change); }