diff options
| author | 2018-02-09 19:08:29 +0000 | |
|---|---|---|
| committer | 2018-02-09 19:08:29 +0000 | |
| commit | 0db836413c85435e7da7e4f23b76cd4e12853e26 (patch) | |
| tree | 0e917e8d3e1c827aac799a0e4ff91ea27564a894 | |
| parent | 3882a5bba3cecebbeac320d0ddcdad60dc5fdea8 (diff) | |
| parent | 4023466229f9f5b32d0194ab34284061db083966 (diff) | |
Merge "Fixed bug with turnScreenOn window flag."
6 files changed, 76 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 83bd9114c48f..f5760e593f37 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -724,19 +724,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { (mSustainedPerformanceModeEnabled ? 1 : 0)); } - if (mService.mTurnOnScreen) { - if (mService.mAllowTheaterModeWakeFromLayout - || Settings.Global.getInt(mService.mContext.getContentResolver(), - Settings.Global.THEATER_MODE_ON, 0) == 0) { - if (DEBUG_VISIBILITY || DEBUG_POWER) { - Slog.v(TAG, "Turning screen on after layout!"); - } - mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(), - "android.server.wm:TURN_ON"); - } - mService.mTurnOnScreen = false; - } - if (mUpdateRotation) { if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); // TODO(multi-display): Update rotation for different displays separately. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1e069a93055e..c2ed2ae30227 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -745,8 +745,6 @@ public class WindowManagerService extends IWindowManager.Stub private Session mHoldingScreenOn; private PowerManager.WakeLock mHoldingScreenWakeLock; - boolean mTurnOnScreen; - // Whether or not a layout can cause a wake up when theater mode is enabled. boolean mAllowTheaterModeWakeFromLayout; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index b6712c097e23..21b436112fda 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.os.PowerManager.DRAW_WAKE_LOCK; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.SurfaceControl.Transaction; @@ -167,6 +168,7 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.WorkSource; +import android.provider.Settings; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.MergedConfiguration; @@ -285,7 +287,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP int mLayer; boolean mHaveFrame; boolean mObscured; - boolean mTurnOnScreen; int mLayoutSeq = -1; @@ -635,6 +636,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private TapExcludeRegionHolder mTapExcludeRegionHolder; /** + * Used for testing because the real PowerManager is final. + */ + private PowerManagerWrapper mPowerManagerWrapper; + + /** * Compares two window sub-layers and returns -1 if the first is lesser than the second in terms * of z-order and 1 otherwise. */ @@ -663,9 +669,34 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f; + interface PowerManagerWrapper { + void wakeUp(long time, String reason); + + boolean isInteractive(); + + } + + WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, + WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, + int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) { + this(service, s, c, token, parentWindow, appOp, seq, a, viewVisibility, ownerId, + ownerCanAddInternalSystemWindow, new PowerManagerWrapper() { + @Override + public void wakeUp(long time, String reason) { + service.mPowerManager.wakeUp(time, reason); + } + + @Override + public boolean isInteractive() { + return service.mPowerManager.isInteractive(); + } + }); + } + WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, - WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, - int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) { + WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, + int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow, + PowerManagerWrapper powerManagerWrapper) { super(service); mSession = s; mClient = c; @@ -682,6 +713,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP DeathRecipient deathRecipient = new DeathRecipient(); mSeq = seq; mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; + mPowerManagerWrapper = powerManagerWrapper; if (localLOGV) Slog.v( TAG, "Window " + this + " client=" + c.asBinder() + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); @@ -2275,9 +2307,34 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void prepareWindowToDisplayDuringRelayout(boolean wasVisible) { // We need to turn on screen regardless of visibility. - if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { - if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); - mTurnOnScreen = true; + boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0; + boolean allowTheaterMode = + mService.mAllowTheaterModeWakeFromLayout || Settings.Global.getInt( + mService.mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0) + == 0; + boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn(); + + // The screen will turn on if the following conditions are met + // 1. The window has the flag FLAG_TURN_SCREEN_ON + // 2. The WMS allows theater mode. + // 3. No AWT or the AWT allows the screen to be turned on. This should only be true once + // per resume to prevent the screen getting getting turned on for each relayout. Set + // canTurnScreenOn will be set to false so the window doesn't turn the screen on again + // during this resume. + // 4. When the screen is not interactive. This is because when the screen is already + // interactive, the value may persist until the next animation, which could potentially + // be occurring while turning off the screen. This would lead to the screen incorrectly + // turning back on. + if (hasTurnScreenOnFlag && allowTheaterMode && canTurnScreenOn + && !mPowerManagerWrapper.isInteractive()) { + if (DEBUG_VISIBILITY || DEBUG_POWER) { + Slog.v(TAG, "Relayout window turning screen on: " + this); + } + mPowerManagerWrapper.wakeUp(SystemClock.uptimeMillis(), + "android.server.wm:TURN_ON"); + } + if (mAppToken != null) { + mAppToken.setCanTurnScreenOn(false); } // If we were already visible, skip rest of preparation. @@ -2571,8 +2628,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // in wake lock statistics. So in particular, we don't want to include the // window's hash code as in toString(). final CharSequence tag = getWindowTag(); - mDrawLock = mService.mPowerManager.newWakeLock( - PowerManager.DRAW_WAKE_LOCK, "Window:" + tag); + mDrawLock = mService.mPowerManager.newWakeLock(DRAW_WAKE_LOCK, "Window:" + tag); mDrawLock.setReferenceCounted(false); mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName)); } @@ -3327,15 +3383,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP pw.print(" mDestroying="); pw.print(mDestroying); pw.print(" mRemoved="); pw.println(mRemoved); } - if (getOrientationChanging() || mAppFreezing || mTurnOnScreen - || mReportOrientationChanged) { + if (getOrientationChanging() || mAppFreezing || mReportOrientationChanged) { pw.print(prefix); pw.print("mOrientationChanging="); pw.print(mOrientationChanging); pw.print(" configOrientationChanging="); pw.print(getLastReportedConfiguration().orientation != getConfiguration().orientation); pw.print(" mAppFreezing="); pw.print(mAppFreezing); - pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen); pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged); } if (mLastFreezeDuration != 0) { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index dd23b6f25630..9621ee527cac 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1108,31 +1108,6 @@ class WindowStateAnimator { w.setOrientationChanging(false); } } - // We process mTurnOnScreen even for windows which have already - // been shown, to handle cases where windows are not necessarily - // 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 && - (mWin.mAppToken == null || 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. - if (mWin.mAppToken != null) { - mWin.mAppToken.setCanTurnScreenOn(false); - } - - // We do not add {@code SET_TURN_ON_SCREEN} when the screen is already - // interactive as the value may persist until the next animation, which could - // potentially occurring while turning off the screen. This would lead to the - // screen incorrectly turning back on. - if (!mService.mPowerManager.isInteractive()) { - mService.mTurnOnScreen = true; - } - } } if (hasSurface()) { w.mToken.hasVisible = true; diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index 4d41718e4da0..74c72bf2ae0d 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -41,6 +41,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; /** * Tests for the {@link WindowState} class. @@ -240,11 +244,11 @@ public class WindowStateTests extends WindowTestsBase { } private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) { + reset(mPowerManagerWrapper); final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; - root.mTurnOnScreen = false; root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/); - assertTrue(root.mTurnOnScreen); + verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString()); } } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java index 6e6863d5220e..91d5ea463bbe 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java @@ -29,6 +29,7 @@ import android.view.DisplayInfo; import org.junit.Assert; import org.junit.After; import org.junit.Before; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import android.content.Context; @@ -84,6 +85,9 @@ class WindowTestsBase { WindowState mChildAppWindowBelow; HashSet<WindowState> mCommonWindows; + @Mock + static WindowState.PowerManagerWrapper mPowerManagerWrapper; + @Before public void setUp() throws Exception { if (!sOneTimeSetupDone) { @@ -245,7 +249,7 @@ class WindowTestsBase { attrs.setTitle(name); final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE, - 0, attrs, VISIBLE, ownerId, ownerCanAddInternalSystemWindow); + 0, attrs, VISIBLE, ownerId, ownerCanAddInternalSystemWindow, mPowerManagerWrapper); // TODO: Probably better to make this call in the WindowState ctor to avoid errors with // adding it to the token... token.addWindow(w); |