From 8eadecca2206d7bd90dbd6404d4e139828b05fe8 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 27 Mar 2023 22:13:39 +0800 Subject: [PATCH] Request transition for corner case of keyguard state If an app requests to occlude keyguard after its first resumed and relayout is done (outside scope of UnknownAppVisibilityController), the transition may not collect any visibility change. Then when setShowWhenLocked takes effect to notify keyguard, there won't be transition when calling setKeyguardShown. And the screen may be either blank because the launching activity's parent was hidden or keyguard is still showing because there is no transition to tell keyguard to hide by TRANSIT_FLAG_KEYGUARD_LOCKED. Also - Reduce noise log when making device sleep - Recover the surface visibility of parents if the activity is changing to visible outside a transition. Bug: 274123143 Test: Turn off display or on lockscreen. Cold/warm/hot launch an activity which calls setShowWhenLocked and setTurnScreenOn with a delay. The visibility error log should not appear and the activity is visible without lockscreen. Change-Id: I1fe16af079564a99cd61b0e3accf8699bc72e1e6 --- .../com/android/server/wm/ActivityRecord.java | 12 ++++++++++- .../server/wm/RootWindowContainer.java | 21 ++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9069ac50badfa..5c5b3b8de303e 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5265,10 +5265,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mTransitionController.collect(this); } else { inFinishingTransition = mTransitionController.inFinishingTransition(this); - if (!inFinishingTransition) { + if (!inFinishingTransition && !mDisplayContent.isSleeping()) { Slog.e(TAG, "setVisibility=" + visible + " while transition is not collecting or finishing " + this + " caller=" + Debug.getCallers(8)); + // Force showing the parents because they may be hidden by previous transition. + if (visible) { + final Transaction t = getSyncTransaction(); + for (WindowContainer p = getParent(); p != null && p != mDisplayContent; + p = p.getParent()) { + if (p.mSurfaceControl != null) { + t.show(p.mSurfaceControl); + } + } + } } } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 2f5634362e68a..07daa4b22ac9d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2349,12 +2349,23 @@ class RootWindowContainer extends WindowContainer } // Prepare transition before resume top activity, so it can be collected. - if (!displayShouldSleep && display.isDefaultDisplay - && !display.getDisplayPolicy().isAwake() - && display.mTransitionController.isShellTransitionsEnabled() + if (!displayShouldSleep && display.mTransitionController.isShellTransitionsEnabled() && !display.mTransitionController.isCollecting()) { - display.mTransitionController.requestTransitionIfNeeded(TRANSIT_WAKE, - 0 /* flags */, null /* trigger */, display); + int transit = TRANSIT_NONE; + if (!display.getDisplayPolicy().isAwake()) { + // Note that currently this only happens on default display because non-default + // display is always awake. + transit = TRANSIT_WAKE; + } else if (display.isKeyguardOccluded()) { + // The display was awake so this is resuming activity for occluding keyguard. + transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE; + } + if (transit != TRANSIT_NONE) { + display.mTransitionController.requestStartTransition( + display.mTransitionController.createTransition(transit), + null /* startTask */, null /* remoteTransition */, + null /* displayChange */); + } } // Set the sleeping state of the root tasks on the display. display.forAllRootTasks(rootTask -> {