diff options
| author | 2021-09-27 15:36:15 +0000 | |
|---|---|---|
| committer | 2021-09-27 15:36:15 +0000 | |
| commit | 04600048604dc6c5838116dbf2eeb0d48c995b80 (patch) | |
| tree | 380e2401bf0777aab2635dcbb681eabaf94796b7 | |
| parent | 6b25c357090c51d1623cd0b93c4b9694f58549c4 (diff) | |
| parent | bc720a77e8c6657ecc5cfb8bc416633b93039f87 (diff) | |
Merge "Merge changes I037517d9,Ic603b271,I47fe530f into sc-qpr1-dev am: 44e5c9a0f5" into sc-v2-dev
3 files changed, 141 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 3c6c23b08091..c7bf8ecfe949 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -59,11 +59,30 @@ class SurfaceAnimator { @VisibleForTesting final Animatable mAnimatable; private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback; + + /** + * Static callback to run on all animations started through this SurfaceAnimator + * when an animation on a Surface is finished or cancelled without restart. + */ @VisibleForTesting @Nullable final OnAnimationFinishedCallback mStaticAnimationFinishedCallback; + + /** + * Callback unique to each animation (i.e. AnimationAdapter). To be run when an animation on a + * Surface is finished or cancelled without restart. + */ + @Nullable + private OnAnimationFinishedCallback mSurfaceAnimationFinishedCallback; + + /** + * The callback is triggered after the SurfaceAnimator sends a cancel call to the underlying + * AnimationAdapter. + * NOTE: Must be called wherever we call onAnimationCancelled on mAnimation. + */ @Nullable - private OnAnimationFinishedCallback mAnimationFinishedCallback; + private Runnable mAnimationCancelledCallback; + private boolean mAnimationStartDelayed; /** @@ -100,7 +119,7 @@ class SurfaceAnimator { return; } final OnAnimationFinishedCallback animationFinishCallback = - mAnimationFinishedCallback; + mSurfaceAnimationFinishedCallback; reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */); if (staticAnimationFinishedCallback != null) { staticAnimationFinishedCallback.onAnimationFinished(type, anim); @@ -130,15 +149,19 @@ class SurfaceAnimator { * This is important as it will start with the leash hidden or visible before * handing it to the component that is responsible to run the animation. * @param animationFinishedCallback The callback being triggered when the animation finishes. + * @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a + * cancel call to the underlying AnimationAdapter. */ void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, @Nullable OnAnimationFinishedCallback animationFinishedCallback, + @Nullable Runnable animationCancelledCallback, @Nullable SurfaceFreezer freezer) { cancelAnimation(t, true /* restarting */, true /* forwardCancel */); mAnimation = anim; mAnimationType = type; - mAnimationFinishedCallback = animationFinishedCallback; + mSurfaceAnimationFinishedCallback = animationFinishedCallback; + mAnimationCancelledCallback = animationCancelledCallback; final SurfaceControl surface = mAnimatable.getSurfaceControl(); if (surface == null) { Slog.w(TAG, "Unable to start animation, surface is null or no children."); @@ -161,14 +184,9 @@ class SurfaceAnimator { } void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, - @AnimationType int type, - @Nullable OnAnimationFinishedCallback animationFinishedCallback) { - startAnimation(t, anim, hidden, type, animationFinishedCallback, null /* freezer */); - } - - void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type) { - startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */); + startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */, + null /* animationCancelledCallback */, null /* freezer */); } /** @@ -278,7 +296,8 @@ class SurfaceAnimator { mLeash = from.mLeash; mAnimation = from.mAnimation; mAnimationType = from.mAnimationType; - mAnimationFinishedCallback = from.mAnimationFinishedCallback; + mSurfaceAnimationFinishedCallback = from.mSurfaceAnimationFinishedCallback; + mAnimationCancelledCallback = from.mAnimationCancelledCallback; // Cancel source animation, but don't let animation runner cancel the animation. from.cancelAnimation(t, false /* restarting */, false /* forwardCancel */); @@ -306,11 +325,16 @@ class SurfaceAnimator { final SurfaceControl leash = mLeash; final AnimationAdapter animation = mAnimation; final @AnimationType int animationType = mAnimationType; - final OnAnimationFinishedCallback animationFinishedCallback = mAnimationFinishedCallback; + final OnAnimationFinishedCallback animationFinishedCallback = + mSurfaceAnimationFinishedCallback; + final Runnable animationCancelledCallback = mAnimationCancelledCallback; reset(t, false); if (animation != null) { if (!mAnimationStartDelayed && forwardCancel) { animation.onAnimationCancelled(leash); + if (animationCancelledCallback != null) { + animationCancelledCallback.run(); + } } if (!restarting) { if (mStaticAnimationFinishedCallback != null) { @@ -335,7 +359,7 @@ class SurfaceAnimator { private void reset(Transaction t, boolean destroyLeash) { mService.mAnimationTransferMap.remove(mAnimation); mAnimation = null; - mAnimationFinishedCallback = null; + mSurfaceAnimationFinishedCallback = null; mAnimationType = ANIMATION_TYPE_NONE; if (mLeash == null) { return; diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 4a1a922c8a02..a257e902dc46 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -42,6 +42,9 @@ import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBL import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static java.lang.Integer.MIN_VALUE; + +import android.annotation.ColorInt; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; @@ -80,6 +83,22 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { DisplayContent mDisplayContent; /** + * A color layer that serves as a solid color background to certain animations. + */ + private SurfaceControl mColorBackgroundLayer; + + /** + * This counter is used to make sure we don't prematurely clear the background color in the + * case that background color animations are interleaved. + * NOTE: The last set color will remain until the counter is reset to 0, which means that an + * animation background color may sometime remain after the animation has finished through an + * animation with a different background color if an animation starts after and ends before + * another where both set different background colors. However, this is not a concern as + * currently all task animation backgrounds are the same color. + */ + private int mColorLayerCounter = 0; + + /** * A control placed at the appropriate level for transitions to occur. */ private SurfaceControl mAppAnimationLayer; @@ -959,6 +978,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) { if (getParent() != null) { super.onParentChanged(newParent, oldParent, () -> { + mColorBackgroundLayer = makeChildSurface(null) + .setColorLayer() + .setName("colorBackgroundLayer") + .setCallsite("TaskDisplayArea.onParentChanged") + .build(); mAppAnimationLayer = makeChildSurface(null) .setName("animationLayer") .setCallsite("TaskDisplayArea.onParentChanged") @@ -975,6 +999,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { .setName("splitScreenDividerAnchor") .setCallsite("TaskDisplayArea.onParentChanged") .build(); + getSyncTransaction() .show(mAppAnimationLayer) .show(mBoostedAppAnimationLayer) @@ -984,11 +1009,13 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } else { super.onParentChanged(newParent, oldParent); mWmService.mTransactionFactory.get() + .remove(mColorBackgroundLayer) .remove(mAppAnimationLayer) .remove(mBoostedAppAnimationLayer) .remove(mHomeAppAnimationLayer) .remove(mSplitScreenDividerAnchor) .apply(); + mColorBackgroundLayer = null; mAppAnimationLayer = null; mBoostedAppAnimationLayer = null; mHomeAppAnimationLayer = null; @@ -996,6 +1023,39 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } } + void setBackgroundColor(@ColorInt int color) { + if (mColorBackgroundLayer == null) { + return; + } + + float r = ((color >> 16) & 0xff) / 255.0f; + float g = ((color >> 8) & 0xff) / 255.0f; + float b = ((color >> 0) & 0xff) / 255.0f; + float a = ((color >> 24) & 0xff) / 255.0f; + + mColorLayerCounter++; + + getPendingTransaction().setLayer(mColorBackgroundLayer, MIN_VALUE) + .setColor(mColorBackgroundLayer, new float[]{r, g, b}) + .setAlpha(mColorBackgroundLayer, a) + .setWindowCrop(mColorBackgroundLayer, getSurfaceWidth(), getSurfaceHeight()) + .setPosition(mColorBackgroundLayer, 0, 0) + .show(mColorBackgroundLayer); + + scheduleAnimation(); + } + + void clearBackgroundColor() { + mColorLayerCounter--; + + // Only clear the color layer if we have received the same amounts of clear as set + // requests. + if (mColorLayerCounter == 0) { + getPendingTransaction().hide(mColorBackgroundLayer); + scheduleAnimation(); + } + } + @Override void migrateToNewSurfaceControl(SurfaceControl.Transaction t) { super.migrateToNewSurfaceControl(t); @@ -1004,6 +1064,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } // As TaskDisplayArea is getting a new surface, reparent and reorder the child surfaces. + t.reparent(mColorBackgroundLayer, mSurfaceControl); t.reparent(mAppAnimationLayer, mSurfaceControl); t.reparent(mBoostedAppAnimationLayer, mSurfaceControl); t.reparent(mHomeAppAnimationLayer, mSurfaceControl); @@ -2159,6 +2220,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } @Override + TaskDisplayArea getTaskDisplayArea() { + return this; + } + + @Override boolean isTaskDisplayArea() { return true; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 26fe2fc59604..861605dd5744 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -856,6 +856,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return parent != null ? parent.getRootDisplayArea() : null; } + @Nullable + TaskDisplayArea getTaskDisplayArea() { + WindowContainer parent = getParent(); + return parent != null ? parent.getTaskDisplayArea() : null; + } + boolean isAttached() { WindowContainer parent = getParent(); return parent != null && parent.isAttached(); @@ -2551,10 +2557,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * some point but the meaning is too weird to work for all containers. * @param type The type of animation defined as {@link AnimationType}. * @param animationFinishedCallback The callback being triggered when the animation finishes. + * @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a + * cancel call to the underlying AnimationAdapter. */ void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, - @Nullable OnAnimationFinishedCallback animationFinishedCallback) { + @Nullable OnAnimationFinishedCallback animationFinishedCallback, + @Nullable Runnable animationCancelledCallback) { if (DEBUG_ANIM) { Slog.v(TAG, "Starting animation on " + this + ": type=" + type + ", anim=" + anim); } @@ -2562,7 +2571,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // TODO: This should use isVisible() but because isVisible has a really weird meaning at // the moment this doesn't work for all animatable window containers. mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback, - mSurfaceFreezer); + animationCancelledCallback, mSurfaceFreezer); + } + + void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, + @AnimationType int type, + @Nullable OnAnimationFinishedCallback animationFinishedCallback) { + startAnimation(t, anim, hidden, type, animationFinishedCallback, + null /* adapterAnimationCancelledCallback */); } void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @@ -2796,8 +2812,27 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (sources != null) { mSurfaceAnimationSources.addAll(sources); } + + TaskDisplayArea taskDisplayArea = getTaskDisplayArea(); + int backgroundColor = adapter.getBackgroundColor(); + + boolean shouldSetBackgroundColor = taskDisplayArea != null && backgroundColor != 0; + + if (shouldSetBackgroundColor) { + taskDisplayArea.setBackgroundColor(backgroundColor); + } + + Runnable clearColorBackground = () -> { + if (shouldSetBackgroundColor) { + taskDisplayArea.clearBackgroundColor(); + } + }; + startAnimation(getPendingTransaction(), adapter, !isVisible(), - ANIMATION_TYPE_APP_TRANSITION); + ANIMATION_TYPE_APP_TRANSITION, + (type, anim) -> clearColorBackground.run(), + clearColorBackground); + if (adapter.getShowWallpaper()) { getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } |