Merge "Exit dream within keyguard-going-away transition" into main
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index f87cb85..a42eaff 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -29,6 +29,16 @@
 }
 
 flag {
+    name: "dismiss_dream_on_keyguard_dismiss"
+    namespace: "systemui"
+    description: "Dismisses the dream in the keyguard-going-away transition, preventing it from being visible"
+    bug: "333829441"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
   name: "dream_tracks_focus"
   namespace: "communal"
   description: "This flag enables the ability for dreams to track whether or not they have focus"
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 6834e6d..17121c8 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
@@ -702,10 +702,12 @@
             ShellInit shellInit,
             ShellController shellController,
             Transitions transitions,
+            TaskStackListenerImpl taskStackListener,
             @ShellMainThread Handler mainHandler,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new KeyguardTransitionHandler(
-                    shellInit, shellController, transitions, mainHandler, mainExecutor);
+                shellInit, shellController, transitions, taskStackListener, mainHandler,
+                mainExecutor);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 863a51a..9eaf7e4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.service.dreams.Flags.dismissDreamOnKeyguardDismiss;
 import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
@@ -44,10 +45,13 @@
 import android.window.IRemoteTransitionFinishedCallback;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.TaskStackListenerCallback;
+import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.annotations.ExternalThread;
 import com.android.wm.shell.sysui.KeyguardChangeListener;
@@ -62,7 +66,8 @@
  * <p>This takes the highest priority.
  */
 public class KeyguardTransitionHandler
-        implements Transitions.TransitionHandler, KeyguardChangeListener {
+        implements Transitions.TransitionHandler, KeyguardChangeListener,
+        TaskStackListenerCallback {
     private static final String TAG = "KeyguardTransition";
 
     private final Transitions mTransitions;
@@ -71,6 +76,7 @@
     private final ShellExecutor mMainExecutor;
 
     private final ArrayMap<IBinder, StartedTransition> mStartedTransitions = new ArrayMap<>();
+    private final TaskStackListenerImpl mTaskStackListener;
 
     /**
      * Local IRemoteTransition implementations registered by the keyguard service.
@@ -87,6 +93,8 @@
 
     // Last value reported by {@link KeyguardChangeListener}.
     private boolean mKeyguardShowing = true;
+    @Nullable
+    private WindowContainerToken mDreamToken;
 
     private final class StartedTransition {
         final TransitionInfo mInfo;
@@ -105,18 +113,23 @@
             @NonNull ShellInit shellInit,
             @NonNull ShellController shellController,
             @NonNull Transitions transitions,
+            @NonNull TaskStackListenerImpl taskStackListener,
             @NonNull Handler mainHandler,
             @NonNull ShellExecutor mainExecutor) {
         mTransitions = transitions;
         mShellController = shellController;
         mMainHandler = mainHandler;
         mMainExecutor = mainExecutor;
+        mTaskStackListener = taskStackListener;
         shellInit.addInitCallback(this::onInit, this);
     }
 
     private void onInit() {
         mTransitions.addHandler(this);
         mShellController.addKeyguardChangeListener(this);
+        if (dismissDreamOnKeyguardDismiss()) {
+            mTaskStackListener.addListener(this);
+        }
     }
 
     /**
@@ -142,6 +155,11 @@
     }
 
     @Override
+    public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+        mDreamToken = taskInfo.getActivityType() == ACTIVITY_TYPE_DREAM ? taskInfo.token : null;
+    }
+
+    @Override
     public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
@@ -271,6 +289,13 @@
     @Override
     public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
             @NonNull TransitionRequestInfo request) {
+        if (dismissDreamOnKeyguardDismiss()
+                && (request.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0
+                && mDreamToken != null) {
+            // Dismiss the dream in the same transaction, so that it isn't visible once the device
+            // is unlocked.
+            return new WindowContainerTransaction().removeTask(mDreamToken);
+        }
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index ae163ea..674c128 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.service.dreams.Flags.dismissDreamOnKeyguardDismiss;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
@@ -89,14 +90,14 @@
 import com.android.wm.shell.shared.TransitionUtil;
 import com.android.wm.shell.transition.Transitions;
 
-import kotlinx.coroutines.CoroutineScope;
-
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.WeakHashMap;
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.CoroutineScope;
+
 public class KeyguardService extends Service {
     static final String TAG = "KeyguardService";
     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
@@ -223,6 +224,20 @@
                 initAlphaForAnimationTargets(t, apps);
                 initAlphaForAnimationTargets(t, wallpapers);
 
+                // If the keyguard is going away, hide the dream if one exists.
+                if (dismissDreamOnKeyguardDismiss()
+                        && (info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
+                    for (RemoteAnimationTarget app : apps) {
+                        final boolean isDream = app.taskInfo != null
+                                && app.taskInfo.getActivityType()
+                                == WindowConfiguration.ACTIVITY_TYPE_DREAM;
+                        if (isDream && app.mode == RemoteAnimationTarget.MODE_CLOSING) {
+                            t.hide(app.leash);
+                            break;
+                        }
+                    }
+                }
+
                 t.apply();
 
                 runner.onAnimationStart(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 46aec25..5d31d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -21,6 +21,7 @@
 import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
 import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED;
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import static android.service.dreams.Flags.dismissDreamOnKeyguardDismiss;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
@@ -3092,13 +3093,22 @@
                         createInteractionJankMonitorConf(
                                 CUJ_LOCKSCREEN_UNLOCK_ANIMATION, "DismissPanel"));
 
+                // Filter out any closing apps, such as the dream.
+                RemoteAnimationTarget[] openingApps = apps;
+                if (dismissDreamOnKeyguardDismiss()) {
+                    openingApps = Arrays.stream(apps)
+                            .filter(a -> a.mode == RemoteAnimationTarget.MODE_OPENING)
+                            .toArray(RemoteAnimationTarget[]::new);
+                }
+
                 // Pass the surface and metadata to the unlock animation controller.
                 RemoteAnimationTarget[] openingWallpapers = Arrays.stream(wallpapers).filter(
                         w -> w.mode == RemoteAnimationTarget.MODE_OPENING).toArray(
                         RemoteAnimationTarget[]::new);
+
                 mKeyguardUnlockAnimationControllerLazy.get()
                         .notifyStartSurfaceBehindRemoteAnimation(
-                                apps, openingWallpapers, startTime,
+                                openingApps, openingWallpapers, startTime,
                                 mSurfaceBehindRemoteAnimationRequested);
             } else {
                 mInteractionJankMonitor.begin(