From 42f3fa43059b190397b05d07247e432d2b54d381 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Thu, 1 Jun 2023 05:41:25 +0000 Subject: [PATCH] Draw background color above display area... ...so the background color layer won't occludes any other windows which does involved the transition. Also fix the animation transformation accumulates to next change in DefaultTransitionHandler#applyTransformation Bug: 283050044 Test: follow issue description, when launch a new task on non-top task, the background color of animation won't occludes the lower task. Test: atest ShellTransitionTests StageCoordinatorTests Change-Id: I02cd3a232350a1dc74e755f9445179ccb216507f --- .../wm/shell/dagger/WMShellBaseModule.java | 14 +++--- .../transition/DefaultTransitionHandler.java | 49 ++++++++++++++----- .../wm/shell/transition/Transitions.java | 9 ++-- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java index 5a9c25f7a710f..c491fed5d8963 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java @@ -70,6 +70,8 @@ import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.freeform.FreeformComponents; import com.android.wm.shell.fullscreen.FullscreenTaskListener; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController; +import com.android.wm.shell.keyguard.KeyguardTransitionHandler; +import com.android.wm.shell.keyguard.KeyguardTransitions; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.Pip; @@ -77,8 +79,6 @@ import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipSurfaceTransactionHelper; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PipTouchHandler; -import com.android.wm.shell.keyguard.KeyguardTransitionHandler; -import com.android.wm.shell.keyguard.KeyguardTransitions; import com.android.wm.shell.recents.RecentTasks; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.recents.RecentsTransitionHandler; @@ -102,13 +102,13 @@ import com.android.wm.shell.unfold.UnfoldAnimationController; import com.android.wm.shell.unfold.UnfoldTransitionHandler; import com.android.wm.shell.windowdecor.WindowDecorViewModel; +import java.util.Optional; + import dagger.BindsOptionalOf; import dagger.Lazy; import dagger.Module; import dagger.Provides; -import java.util.Optional; - /** * Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only * accessible from components within the WM subcomponent (can be explicitly exposed to the @@ -548,13 +548,15 @@ public abstract class WMShellBaseModule { @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellAnimationThread ShellExecutor animExecutor, - ShellCommandHandler shellCommandHandler) { + ShellCommandHandler shellCommandHandler, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { if (!context.getResources().getBoolean(R.bool.config_registerShellTransitionsOnInit)) { // TODO(b/238217847): Force override shell init if registration is disabled shellInit = new ShellInit(mainExecutor); } return new Transitions(context, shellInit, shellController, organizer, pool, - displayController, mainExecutor, mainHandler, animExecutor, shellCommandHandler); + displayController, mainExecutor, mainHandler, animExecutor, shellCommandHandler, + rootTaskDisplayAreaOrganizer); } @WMSingleton 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 4c678a2bf29be..39fbd973dc6c2 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 @@ -58,7 +58,6 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN; import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE; import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN; -import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition; import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow; import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; @@ -76,6 +75,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Color; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; @@ -103,6 +103,7 @@ import com.android.internal.policy.AttributeCache; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.TransitionAnimation; import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; @@ -137,6 +138,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private final Rect mInsets = new Rect(0, 0, 0, 0); private float mTransitionAnimationScaleSetting = 1.0f; + private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer; private final int mCurrentUserId; private Drawable mEnterpriseThumbnailDrawable; @@ -157,7 +159,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { @NonNull DisplayController displayController, @NonNull TransactionPool transactionPool, @NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler, - @NonNull ShellExecutor animExecutor) { + @NonNull ShellExecutor animExecutor, + @NonNull RootTaskDisplayAreaOrganizer rootTDAOrganizer) { mDisplayController = displayController; mTransactionPool = transactionPool; mContext = context; @@ -168,6 +171,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { mCurrentUserId = UserHandle.myUserId(); mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class); shellInit.addInitCallback(this::onInit, this); + mRootTDAOrganizer = rootTDAOrganizer; } private void onInit() { @@ -510,10 +514,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } if (backgroundColorForTransition != 0) { - for (int i = 0; i < info.getRootCount(); ++i) { - addBackgroundToTransition(info.getRoot(i).getLeash(), backgroundColorForTransition, - startTransaction, finishTransaction); - } + addBackgroundColorOnTDA(info, backgroundColorForTransition, startTransaction, + finishTransaction); } if (postStartTransactionCallbacks.size() > 0) { @@ -543,6 +545,28 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { return true; } + private void addBackgroundColorOnTDA(@NonNull TransitionInfo info, + @ColorInt int color, @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction) { + final Color bgColor = Color.valueOf(color); + final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() }; + + for (int i = 0; i < info.getRootCount(); ++i) { + final int displayId = info.getRoot(i).getDisplayId(); + final SurfaceControl.Builder colorLayerBuilder = new SurfaceControl.Builder() + .setName("animation-background") + .setCallsite("DefaultTransitionHandler") + .setColorLayer(); + + mRootTDAOrganizer.attachToDisplayArea(displayId, colorLayerBuilder); + final SurfaceControl backgroundSurface = colorLayerBuilder.build(); + startTransaction.setColor(backgroundSurface, colorArray) + .setLayer(backgroundSurface, -1) + .show(backgroundSurface); + finishTransaction.remove(backgroundSurface); + } + } + private static boolean isDreamTransition(@NonNull TransitionInfo info) { for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); @@ -874,17 +898,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } private static void applyTransformation(long time, SurfaceControl.Transaction t, - SurfaceControl leash, Animation anim, Transformation transformation, float[] matrix, + SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix, Point position, float cornerRadius, @Nullable Rect immutableClipRect) { - anim.getTransformation(time, transformation); + tmpTransformation.clear(); + anim.getTransformation(time, tmpTransformation); if (position != null) { - transformation.getMatrix().postTranslate(position.x, position.y); + tmpTransformation.getMatrix().postTranslate(position.x, position.y); } - t.setMatrix(leash, transformation.getMatrix(), matrix); - t.setAlpha(leash, transformation.getAlpha()); + t.setMatrix(leash, tmpTransformation.getMatrix(), matrix); + t.setAlpha(leash, tmpTransformation.getAlpha()); final Rect clipRect = immutableClipRect == null ? null : new Rect(immutableClipRect); - Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE); + Insets extensionInsets = Insets.min(tmpTransformation.getInsets(), Insets.NONE); if (!extensionInsets.equals(Insets.NONE) && clipRect != null && !clipRect.isEmpty()) { // Clip out any overflowing edge extension clipRect.inset(extensionInsets); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index ce8d792ef302f..06423109ed33c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -68,6 +68,7 @@ import androidx.annotation.BinderThread; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; @@ -264,7 +265,8 @@ public class Transitions implements RemoteCallable, @NonNull Handler mainHandler, @NonNull ShellExecutor animExecutor) { this(context, shellInit, shellController, organizer, pool, displayController, mainExecutor, - mainHandler, animExecutor, null); + mainHandler, animExecutor, null, + new RootTaskDisplayAreaOrganizer(mainExecutor, context)); } public Transitions(@NonNull Context context, @@ -276,7 +278,8 @@ public class Transitions implements RemoteCallable, @NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler, @NonNull ShellExecutor animExecutor, - @Nullable ShellCommandHandler shellCommandHandler) { + @Nullable ShellCommandHandler shellCommandHandler, + @NonNull RootTaskDisplayAreaOrganizer rootTDAOrganizer) { mOrganizer = organizer; mContext = context; mMainExecutor = mainExecutor; @@ -284,7 +287,7 @@ public class Transitions implements RemoteCallable, mDisplayController = displayController; mPlayerImpl = new TransitionPlayerImpl(); mDefaultTransitionHandler = new DefaultTransitionHandler(context, shellInit, - displayController, pool, mainExecutor, mainHandler, animExecutor); + displayController, pool, mainExecutor, mainHandler, animExecutor, rootTDAOrganizer); mRemoteTransitionHandler = new RemoteTransitionHandler(mMainExecutor); mShellController = shellController; // The very last handler (0 in the list) should be the default one.