Don't merge keyguard and unfold transitions

Bug: 305711477
Test: atest UnfoldTransitionHandlerTest
Change-Id: I066217dd13e4222372f26dbed0c2510e8c4815df
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index b26d061..07c5429 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.unfold;
 
+import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
@@ -188,23 +189,27 @@
     public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
             @NonNull TransitionFinishCallback finishCallback) {
-        if (info.getType() == TRANSIT_CHANGE) {
-            // TODO (b/286928742) unfold transition handler should be part of mixed handler to
-            //  handle merges better.
-            for (int i = 0; i < info.getChanges().size(); ++i) {
-                final TransitionInfo.Change change = info.getChanges().get(i);
-                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-                if (taskInfo != null
-                        && taskInfo.configuration.windowConfiguration.isAlwaysOnTop()) {
-                    // Tasks that are always on top (e.g. bubbles), will handle their own transition
-                    // as they are on top of everything else. So skip merging transitions here.
-                    return;
-                }
-            }
-            // Apply changes happening during the unfold animation immediately
-            t.apply();
-            finishCallback.onTransitionFinished(null);
+        if (info.getType() != TRANSIT_CHANGE) {
+            return;
         }
+        if ((info.getFlags() & KEYGUARD_VISIBILITY_TRANSIT_FLAGS) != 0) {
+            return;
+        }
+        // TODO (b/286928742) unfold transition handler should be part of mixed handler to
+        //  handle merges better.
+        for (int i = 0; i < info.getChanges().size(); ++i) {
+            final TransitionInfo.Change change = info.getChanges().get(i);
+            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+            if (taskInfo != null
+                    && taskInfo.configuration.windowConfiguration.isAlwaysOnTop()) {
+                // Tasks that are always on top (e.g. bubbles), will handle their own transition
+                // as they are on top of everything else. So skip merging transitions here.
+                return;
+            }
+        }
+        // Apply changes happening during the unfold animation immediately
+        t.apply();
+        finishCallback.onTransitionFinished(null);
     }
 
     /** Whether `request` contains an unfold action. */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
index 7917ba6..6d73c12 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
@@ -17,6 +17,7 @@
 package com.android.wm.shell.unfold;
 
 import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_NONE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -46,6 +47,7 @@
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.transition.TransitionInfoBuilder;
 import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
 import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
 import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
@@ -265,6 +267,42 @@
         verify(finishCallback).onTransitionFinished(any());
     }
 
+    @Test
+    public void mergeAnimation_eatsDisplayOnlyTransitions() {
+        TransitionRequestInfo requestInfo = createUnfoldTransitionRequestInfo();
+        mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo);
+        TransitionFinishCallback finishCallback = mock(TransitionFinishCallback.class);
+        TransitionFinishCallback mergeCallback = mock(TransitionFinishCallback.class);
+
+        mUnfoldTransitionHandler.startAnimation(
+                mTransition,
+                mock(TransitionInfo.class),
+                mock(SurfaceControl.Transaction.class),
+                mock(SurfaceControl.Transaction.class),
+                finishCallback);
+
+        // Offer a keyguard unlock transition - this should NOT merge
+        mUnfoldTransitionHandler.mergeAnimation(
+                new Binder(),
+                new TransitionInfoBuilder(TRANSIT_CHANGE, TRANSIT_FLAG_KEYGUARD_GOING_AWAY).build(),
+                mock(SurfaceControl.Transaction.class),
+                mTransition,
+                mergeCallback);
+        verify(finishCallback, never()).onTransitionFinished(any());
+
+        // Offer a CHANGE-only transition - this SHOULD merge (b/278064943)
+        mUnfoldTransitionHandler.mergeAnimation(
+                new Binder(),
+                new TransitionInfoBuilder(TRANSIT_CHANGE).build(),
+                mock(SurfaceControl.Transaction.class),
+                mTransition,
+                mergeCallback);
+        verify(mergeCallback).onTransitionFinished(any());
+
+        // We should never have finished the original transition.
+        verify(finishCallback, never()).onTransitionFinished(any());
+    }
+
     private TransitionRequestInfo createUnfoldTransitionRequestInfo() {
         ActivityManager.RunningTaskInfo triggerTaskInfo = new ActivityManager.RunningTaskInfo();
         TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
@@ -372,4 +410,4 @@
     private TransitionInfo createNonUnfoldTransitionInfo() {
         return new TransitionInfo(TRANSIT_CHANGE, /* flags= */ 0);
     }
-}
\ No newline at end of file
+}