summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-02-09 19:08:29 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-02-09 19:08:29 +0000
commit0db836413c85435e7da7e4f23b76cd4e12853e26 (patch)
tree0e917e8d3e1c827aac799a0e4ff91ea27564a894
parent3882a5bba3cecebbeac320d0ddcdad60dc5fdea8 (diff)
parent4023466229f9f5b32d0194ab34284061db083966 (diff)
Merge "Fixed bug with turnScreenOn window flag."
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java76
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java6
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);