summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt126
2 files changed, 169 insertions, 0 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index a5f071af6973..09ba4d3b75e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -36,6 +36,7 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -72,6 +73,9 @@ public class TransitionAnimationHelper {
final int changeFlags = change.getFlags();
final boolean enter = TransitionUtil.isOpeningType(changeMode);
final boolean isTask = change.getTaskInfo() != null;
+ final boolean isFreeform = isTask && change.getTaskInfo().isFreeform();
+ final boolean isCoveredByOpaqueFullscreenChange =
+ isCoveredByOpaqueFullscreenChange(info, change);
final TransitionInfo.AnimationOptions options;
if (Flags.moveAnimationOptionsToChange()) {
options = change.getAnimationOptions();
@@ -107,6 +111,24 @@ public class TransitionAnimationHelper {
animAttr = enter
? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
: R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
+ } else if (!isCoveredByOpaqueFullscreenChange
+ && isFreeform
+ && TransitionUtil.isOpeningMode(type)
+ && change.getMode() == TRANSIT_TO_BACK) {
+ // Set translucent here so TransitionAnimation loads the appropriate animations for
+ // translucent activities and tasks later
+ translucent = (changeFlags & FLAG_TRANSLUCENT) != 0;
+ // The main Task is launching or being brought to front, this Task is being minimized
+ animAttr = R.styleable.WindowAnimation_activityCloseExitAnimation;
+ } else if (!isCoveredByOpaqueFullscreenChange
+ && isFreeform
+ && type == TRANSIT_TO_FRONT
+ && change.getMode() == TRANSIT_TO_FRONT) {
+ // Set translucent here so TransitionAnimation loads the appropriate animations for
+ // translucent activities and tasks later
+ translucent = (changeFlags & FLAG_TRANSLUCENT) != 0;
+ // Bring the minimized Task back to front
+ animAttr = R.styleable.WindowAnimation_activityOpenEnterAnimation;
} else if (type == TRANSIT_OPEN) {
// We will translucent open animation for translucent activities and tasks. Choose
// WindowAnimation_activityOpenEnterAnimation and set translucent here, then
@@ -417,4 +439,25 @@ public class TransitionAnimationHelper {
return edgeExtensionLayer;
}
+
+ /**
+ * Returns whether there is an opaque fullscreen Change positioned in front of the given Change
+ * in the given TransitionInfo.
+ */
+ private static boolean isCoveredByOpaqueFullscreenChange(
+ TransitionInfo info, TransitionInfo.Change change) {
+ // TransitionInfo#getChanges() are ordered from front to back
+ for (TransitionInfo.Change coveringChange : info.getChanges()) {
+ if (coveringChange == change) {
+ return false;
+ }
+ if ((coveringChange.getFlags() & FLAG_TRANSLUCENT) == 0
+ && coveringChange.getTaskInfo() != null
+ && coveringChange.getTaskInfo().getWindowingMode()
+ == WindowConfiguration.WINDOWING_MODE_FULLSCREEN) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt
new file mode 100644
index 000000000000..bad14bbdb141
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/TransitionAnimationHelperTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.transition
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration
+import android.view.WindowManager
+import android.window.TransitionInfo
+import android.window.TransitionInfo.FLAG_TRANSLUCENT
+import com.android.internal.R
+import com.android.internal.policy.TransitionAnimation
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import org.junit.Test
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+
+class TransitionAnimationHelperTest : ShellTestCase() {
+
+ @Mock
+ lateinit var transitionAnimation: TransitionAnimation
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskOpen_taskToBackChange_returnsMinimizeAnim() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val toBackChange = ChangeBuilder(WindowManager.TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, toBackChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityCloseExitAnimation), anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskToFront_taskToFrontChange_returnsUnminimizeAnim() {
+ val toFrontChange = ChangeBuilder(WindowManager.TRANSIT_TO_FRONT)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_TO_FRONT)
+ .addChange(toFrontChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_TO_FRONT, info, toFrontChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityOpenEnterAnimation),
+ /* translucent= */ anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_fullscreen_taskOpen_returnsTaskOpenEnterAnim() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FULLSCREEN))
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN).addChange(openChange).build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, openChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_taskOpenEnterAnimation),
+ /* translucent= */ anyBoolean())
+ }
+
+ @Test
+ fun loadAttributeAnimation_freeform_taskOpen_taskToBackChange_passesTranslucent() {
+ val openChange = ChangeBuilder(WindowManager.TRANSIT_OPEN)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .build()
+ val toBackChange = ChangeBuilder(WindowManager.TRANSIT_TO_BACK)
+ .setTask(createTaskInfo(WindowConfiguration.WINDOWING_MODE_FREEFORM))
+ .setFlags(FLAG_TRANSLUCENT)
+ .build()
+ val info = TransitionInfoBuilder(WindowManager.TRANSIT_OPEN)
+ .addChange(openChange)
+ .addChange(toBackChange)
+ .build()
+
+ loadAttributeAnimation(WindowManager.TRANSIT_OPEN, info, toBackChange)
+
+ verify(transitionAnimation).loadDefaultAnimationAttr(
+ eq(R.styleable.WindowAnimation_activityCloseExitAnimation),
+ /* translucent= */ eq(true))
+ }
+
+ private fun loadAttributeAnimation(
+ @WindowManager.TransitionType type: Int,
+ info: TransitionInfo,
+ change: TransitionInfo.Change,
+ wallpaperTransit: Int = TransitionAnimation.WALLPAPER_TRANSITION_NONE,
+ isDreamTransition: Boolean = false,
+ ) {
+ TransitionAnimationHelper.loadAttributeAnimation(
+ type, info, change, wallpaperTransit, transitionAnimation, isDreamTransition)
+ }
+
+ private fun createTaskInfo(windowingMode: Int): RunningTaskInfo {
+ val taskInfo = TestRunningTaskInfoBuilder()
+ .setWindowingMode(windowingMode)
+ .build()
+ return taskInfo
+ }
+} \ No newline at end of file