From d3bf08da95037042813a29941de07854f6f82bea Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 1 Aug 2017 17:24:59 -0700 Subject: [PATCH] Only allow one turnScreenOn per app resume. The current behavior will turn the screen on if a relayout is called. This is problematic because if the screen is off but the client is still requesting relayouts, the relayout will trigger a request to turn the screen on. This change ensures that the screen will only get turned on at most once per resume. If the activity is relaunched again, the screen can be turned on again. Fixes: 64139966 Test: go/wm-smoke Test: Added cts test ActivityManagerActivityVisibilityTests#testTurnScreenOnActivity_WithRelayout Test: Set the phone to have always on ambient display. Launched the dialer app and turned the screen off. The screen no longer turns back on automatically. Change-Id: I5f6ac5451683d4488e72e3a6377cb3a6fd6504b2 --- .../com/android/server/wm/AppWindowToken.java | 25 +++++++++++++++++++ .../server/wm/WindowStateAnimator.java | 7 +++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index be4b43da0742f..2e4de8c586503 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -193,6 +193,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree Task mLastParent; + /** + * See {@link #canTurnScreenOn()} + */ + private boolean mCanTurnScreenOn = true; + AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint, @@ -644,6 +649,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this); mAppStopped = false; + // Allow the window to turn the screen on once the app is resumed again. + setCanTurnScreenOn(true); if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } @@ -1640,6 +1647,24 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mDisablePreviewScreenshots = disable; } + /** + * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()} + */ + void setCanTurnScreenOn(boolean canTurnScreenOn) { + mCanTurnScreenOn = canTurnScreenOn; + } + + /** + * Indicates whether the current launch can turn the screen on. This is to prevent multiple + * relayouts from turning the screen back on. The screen should only turn on at most + * once per activity resume. + * + * @return true if the screen can be turned on. + */ + boolean canTurnScreenOn() { + return mCanTurnScreenOn; + } + /** * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c610ca3818976..0cc505ea9d05f 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1632,9 +1632,14 @@ class WindowStateAnimator { // hidden while the screen is turning off. // TODO(b/63773439): These cases should be eliminated, though we probably still // want to process mTurnOnScreen in this way for clarity. - if (mWin.mTurnOnScreen) { + if (mWin.mTurnOnScreen && mWin.mAppToken.canTurnScreenOn()) { if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin); mWin.mTurnOnScreen = false; + + // The window should only turn the screen on once per resume, but + // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to + // false so the window doesn't turn the screen on again during this resume. + mWin.mAppToken.setCanTurnScreenOn(false); mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN; } }