Make activities invisible when the display is turned off.

Bug: 127650360
Test: atest ActivityManagerMultiDisplayTests and existing tests pass.
Change-Id: I0943ef1024b32902826de6fd20ab2a8641059bd7
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e2253e7..083eca8 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -87,6 +87,7 @@
 import static android.os.Build.VERSION_CODES.HONEYCOMB;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Process.SYSTEM_UID;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
@@ -1939,14 +1940,20 @@
             return false;
         }
 
+        // Whether the activity is on the sleeping display.
+        // TODO(b/129750406): This should be applied for the default display, too.
+        final boolean isDisplaySleeping = getDisplay().isSleeping()
+                && getDisplayId() != DEFAULT_DISPLAY;
         // Whether this activity is the top activity of this stack.
         final boolean isTop = this == stack.getTopActivity();
         // Exclude the case where this is the top activity in a pinned stack.
         final boolean isTopNotPinnedStack = stack.isAttached()
                 && stack.getDisplay().isTopNotPinnedStack(stack);
-        // Now check whether it's really visible depending on Keyguard state.
-        return stack.checkKeyguardVisibility(this,
+        // Now check whether it's really visible depending on Keyguard state, and update
+        // {@link ActivityStack} internal states.
+        final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
                 visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
+        return visibleIgnoringDisplayStatus && !isDisplaySleeping;
     }
 
     boolean shouldBeVisible() {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 432d75e..363db54 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -294,7 +294,16 @@
     /**
      * Called when occluded state changed.
      */
-    private void handleOccludedChanged() {
+    private void handleOccludedChanged(int displayId) {
+        // TODO(b/113840485): Handle app transition for individual display, and apply occluded
+        // state change to secondary displays.
+        // For now, only default display fully supports occluded change. Other displays only
+        // updates keygaurd sleep token on that display.
+        if (displayId != DEFAULT_DISPLAY) {
+            updateKeyguardSleepToken(displayId);
+            return;
+        }
+
         mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY));
         if (isKeyguardLocked()) {
             mWindowManager.deferSurfaceLayout();
@@ -303,7 +312,7 @@
                         .prepareAppTransition(resolveOccludeTransit(),
                                 false /* alwaysKeepCurrent */, 0 /* flags */,
                                 true /* forceOverride */);
-                updateKeyguardSleepToken();
+                updateKeyguardSleepToken(DEFAULT_DISPLAY);
                 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
                 mWindowManager.executeAppTransition();
             } finally {
@@ -395,13 +404,16 @@
         for (int displayNdx = mRootActivityContainer.getChildCount() - 1;
              displayNdx >= 0; displayNdx--) {
             final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx);
-            final int displayId = display.mDisplayId;
-            final KeyguardDisplayState state = getDisplay(displayId);
-            if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
-                state.acquiredSleepToken();
-            } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
-                state.releaseSleepToken();
-            }
+            updateKeyguardSleepToken(display.mDisplayId);
+        }
+    }
+
+    private void updateKeyguardSleepToken(int displayId) {
+        final KeyguardDisplayState state = getDisplay(displayId);
+        if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
+            state.acquiredSleepToken();
+        } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
+            state.releaseSleepToken();
         }
     }
 
@@ -483,11 +495,8 @@
                 mOccluded |= controller.mWindowManager.isShowingDream();
             }
 
-            // TODO(b/113840485): Handle app transition for individual display, and apply occluded
-            // state change to secondary displays.
-            // For now, only default display can change occluded.
-            if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
-                controller.handleOccludedChanged();
+            if (lastOccluded != mOccluded) {
+                controller.handleOccludedChanged(mDisplayId);
             }
             if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
                     && mDismissingKeyguardActivity != null