diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b142141898331..f14bdca909772 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4547,7 +4547,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { pmWakeReason)) + ")"); } - mActivityTaskManagerInternal.notifyWakingUp(); mDefaultDisplayPolicy.setAwake(true); // Since goToSleep performs these functions synchronously, we must diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 18b8c39e87d57..854eebb1b5393 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -9670,6 +9670,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Override boolean isSyncFinished() { if (!super.isSyncFinished()) return false; + if (mDisplayContent != null && mDisplayContent.mUnknownAppVisibilityController + .isVisibilityUnknown(this)) { + return false; + } if (!isVisibleRequested()) return true; // Wait for attach. That is the earliest time where we know if there will be an associated // display rotation. If we don't wait, the starting-window can finishDrawing first and diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index f75d73b044761..6152676b9be70 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -666,9 +666,6 @@ public abstract class ActivityTaskManagerInternal { public abstract boolean hasSystemAlertWindowPermission(int callingUid, int callingPid, String callingPackage); - /** Called when the device is waking up */ - public abstract void notifyWakingUp(); - /** * Registers a callback which can intercept activity starts. * @throws IllegalArgumentException if duplicate ids are provided diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index ea0db30ee4dba..206cee802f9e1 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -65,7 +65,6 @@ import static android.provider.Settings.System.FONT_SCALE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; -import static android.view.WindowManager.TRANSIT_WAKE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; @@ -6623,15 +6622,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { callingPid, callingPackage); } - @Override - public void notifyWakingUp() { - synchronized (mGlobalLock) { - // Start a transition for waking. This is needed for showWhenLocked activities. - getTransitionController().requestTransitionIfNeeded(TRANSIT_WAKE, 0 /* flags */, - null /* trigger */, mRootWindowContainer.getDefaultDisplay()); - } - } - @Override public void registerActivityStartInterceptor( @ActivityInterceptorCallback.OrderedId int id, diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 62998cb6bc40e..d1ba77d8d6b59 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -61,6 +61,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static android.view.WindowManager.TRANSIT_WAKE; import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED; import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; @@ -776,7 +777,22 @@ public class DisplayPolicy { } public void setAwake(boolean awake) { + if (awake == mAwake) { + return; + } mAwake = awake; + synchronized (mService.mGlobalLock) { + if (!mDisplayContent.isDefaultDisplay) { + return; + } + if (mAwake) { + // Start a transition for waking. This is needed for showWhenLocked activities. + mDisplayContent.mTransitionController.requestTransitionIfNeeded(TRANSIT_WAKE, + 0 /* flags */, null /* trigger */, mDisplayContent); + } + mService.mAtmService.mKeyguardController.updateDeferWakeTransition( + mAwake /* waiting */); + } } public boolean isAwake() { diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index f36dbfa2316e7..03ac7aafb482b 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -72,6 +72,8 @@ class KeyguardController { static final String KEYGUARD_SLEEP_TOKEN_TAG = "keyguard"; + private static final int DEFER_WAKE_TRANSITION_TIMEOUT_MS = 5000; + private final ActivityTaskSupervisor mTaskSupervisor; private WindowManagerService mWindowManager; @@ -79,7 +81,7 @@ class KeyguardController { private final ActivityTaskManagerService mService; private RootWindowContainer mRootWindowContainer; private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; - + private boolean mWaitingForWakeTransition; KeyguardController(ActivityTaskManagerService service, ActivityTaskSupervisor taskSupervisor) { @@ -171,6 +173,9 @@ class KeyguardController { // Do not reset keyguardChanged status if this is aodChanged. final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing) || (state.mKeyguardGoingAway && keyguardShowing && !aodChanged); + if (aodChanged && !aodShowing) { + updateDeferWakeTransition(false /* waiting */); + } if (!keyguardChanged && !aodChanged) { setWakeTransitionReady(); return; @@ -199,10 +204,6 @@ class KeyguardController { state.mKeyguardShowing = keyguardShowing; state.mAodShowing = aodShowing; - if (aodChanged) { - // Ensure the new state takes effect. - mWindowManager.mWindowPlacerLocked.performSurfacePlacement(); - } if (keyguardChanged) { // Irrelevant to AOD. @@ -220,6 +221,10 @@ class KeyguardController { mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */); setWakeTransitionReady(); + if (aodChanged) { + // Ensure the new state takes effect. + mWindowManager.mWindowPlacerLocked.performSurfacePlacement(); + } } private void setWakeTransitionReady() { @@ -526,6 +531,33 @@ class KeyguardController { } } + private final Runnable mResetWaitTransition = () -> { + synchronized (mWindowManager.mGlobalLock) { + updateDeferWakeTransition(false /* waiting */); + } + }; + + void updateDeferWakeTransition(boolean waiting) { + if (waiting == mWaitingForWakeTransition) { + return; + } + if (!mWindowManager.mAtmService.getTransitionController().isShellTransitionsEnabled()) { + return; + } + // if aod is showing, defer the wake transition until aod state changed. + if (waiting && isAodShowing(DEFAULT_DISPLAY)) { + mWaitingForWakeTransition = true; + mWindowManager.mAtmService.getTransitionController().deferTransitionReady(); + mWindowManager.mH.postDelayed(mResetWaitTransition, DEFER_WAKE_TRANSITION_TIMEOUT_MS); + } else if (!waiting) { + // dismiss the deferring if the aod state change or cancel awake. + mWaitingForWakeTransition = false; + mWindowManager.mAtmService.getTransitionController().continueTransitionReady(); + mWindowManager.mH.removeCallbacks(mResetWaitTransition); + } + } + + /** Represents Keyguard state per individual display. */ private static class KeyguardDisplayState { private final int mDisplayId; diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java index 5e963cc5ae8e8..41c1e793dd901 100644 --- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java +++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java @@ -69,6 +69,10 @@ class UnknownAppVisibilityController { return mUnknownApps.isEmpty(); } + boolean isVisibilityUnknown(ActivityRecord r) { + return mUnknownApps.containsKey(r); + } + void clear() { mUnknownApps.clear(); }