summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Brown <jeffbrown@google.com> 2014-09-19 12:05:31 -0700
committer Jeff Brown <jeffbrown@google.com> 2014-09-19 13:14:29 -0700
commit36c4db8bd3bd7dad4b6cb8abd9cdc1a627fe3bbc (patch)
tree16fc5f533a7c0392303059a4794f73957fb661da
parent4d69e2219390bce567b0d2c986d0bd3a3182eda5 (diff)
Decouple turning screen on from waking up in policy.
This allows us to ensure windows are fully drawn before unblocking screen on while dozing. Bug: 17516245 Change-Id: Ibe63c212b8db855ce26a34a8169f33764b266ee6
-rw-r--r--core/java/android/view/WindowManagerPolicy.java30
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java142
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/power/Notifier.java30
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java5
6 files changed, 147 insertions, 82 deletions
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index fec7550af66d..d458ee4846cf 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -930,7 +930,12 @@ public interface WindowManagerPolicy {
* A new window has been focused.
*/
public int focusChangedLw(WindowState lastFocus, WindowState newFocus);
-
+
+ /**
+ * Called when the device is waking up.
+ */
+ public void wakingUp();
+
/**
* Called when the device is going to sleep.
*
@@ -939,26 +944,25 @@ public interface WindowManagerPolicy {
*/
public void goingToSleep(int why);
- public interface ScreenOnListener {
- void onScreenOn();
- }
-
/**
- * Called when the device is waking up.
+ * Called when the device is about to turn on the screen to show content.
+ * When waking up, this method will be called once after the call to wakingUp().
+ * When dozing, the method will be called sometime after the call to goingToSleep() and
+ * may be called repeatedly in the case where the screen is pulsing on and off.
+ *
* Must call back on the listener to tell it when the higher-level system
* is ready for the screen to go on (i.e. the lock screen is shown).
*/
- public void wakingUp(ScreenOnListener screenOnListener);
+ public void screenTurningOn(ScreenOnListener screenOnListener);
- /**
- * Return whether the screen is about to turn on or is currently on.
- */
- public boolean isScreenOnEarly();
+ public interface ScreenOnListener {
+ void onScreenOn();
+ }
/**
- * Return whether the screen is fully turned on.
+ * Return whether the system is awake.
*/
- public boolean isScreenOnFully();
+ public boolean isAwake();
/**
* Tell the policy that the lid switch has changed state.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index fbaaf74b2fda..aa49d3747f39 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -351,8 +351,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mLidControlsSleep;
int mShortPressOnPowerBehavior = -1;
int mLongPressOnPowerBehavior = -1;
- boolean mScreenOnEarly = false;
- boolean mScreenOnFully = false;
+ boolean mAwakeEarly = false;
+ boolean mAwakeFully = false;
boolean mOrientationSensorEnabled = false;
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
@@ -548,6 +548,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
private static final int MSG_HIDE_BOOT_MESSAGE = 11;
private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
+ private static final int MSG_SCREEN_TURNING_ON = 13;
private class PolicyHandler extends Handler {
@Override
@@ -573,22 +574,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case MSG_KEYGUARD_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
- mKeyguardDrawComplete = true;
- finishScreenTurningOn();
+ finishKeyguardDrawn();
break;
case MSG_KEYGUARD_DRAWN_TIMEOUT:
Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
- mKeyguardDrawComplete = true;
- finishScreenTurningOn();
+ finishKeyguardDrawn();
break;
case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
- mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
- mWindowManagerDrawComplete = true;
- finishScreenTurningOn();
+ finishWindowsDrawn();
break;
case MSG_WAKING_UP:
- handleWakingUp((ScreenOnListener) msg.obj);
+ handleWakingUp();
break;
case MSG_HIDE_BOOT_MESSAGE:
handleHideBootMessage();
@@ -596,6 +593,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
launchVoiceAssistWithWakeLock(msg.arg1 != 0);
break;
+ case MSG_SCREEN_TURNING_ON:
+ handleScreenTurningOn((ScreenOnListener)msg.obj);
+ break;
}
}
}
@@ -766,11 +766,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
//Could have been invoked due to screen turning on or off or
//change of the currently visible window's orientation
- if (localLOGV) Slog.v(TAG, "Screen status="+mScreenOnEarly+
+ if (localLOGV) Slog.v(TAG, "Screen status="+mAwakeEarly+
", current orientation="+mCurrentAppOrientation+
", SensorEnabled="+mOrientationSensorEnabled);
boolean disable = true;
- if (mScreenOnEarly) {
+ if (mAwakeEarly) {
if (needSensorRunningLp()) {
disable = false;
//enable listener if not already enabled
@@ -1332,7 +1332,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private boolean shouldEnableWakeGestureLp() {
- return mWakeGestureEnabledSetting && !mScreenOnEarly
+ return mWakeGestureEnabledSetting && !mAwakeEarly
&& (!mLidControlsSleep || mLidState != LID_CLOSED)
&& mWakeGestureListener.isSupported();
}
@@ -4731,9 +4731,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void goingToSleep(int why) {
EventLog.writeEvent(70000, 0);
+ if (DEBUG_WAKEUP) Slog.i(TAG, "Going to sleep...");
synchronized (mLock) {
- mScreenOnEarly = false;
- mScreenOnFully = false;
+ mAwakeEarly = false;
+ mAwakeFully = false;
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onScreenTurnedOff(why);
@@ -4746,70 +4747,101 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public void wakingUp(final ScreenOnListener screenOnListener) {
+ public void wakingUp() {
EventLog.writeEvent(70000, 1);
- if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...",
- new RuntimeException("here").fillInStackTrace());
- mHandler.obtainMessage(MSG_WAKING_UP, screenOnListener).sendToTarget();
+ if (DEBUG_WAKEUP) Slog.i(TAG, "Waking up...");
+ mHandler.obtainMessage(MSG_WAKING_UP).sendToTarget();
}
// Called on the mHandler thread.
- private void handleWakingUp(final ScreenOnListener screenOnListener) {
- if (screenOnListener != null) {
- mScreenOnListener = screenOnListener;
- }
-
+ private void handleWakingUp() {
synchronized (mLock) {
- mScreenOnEarly = true;
+ mAwakeEarly = true;
updateWakeGestureListenerLp();
updateOrientationListenerLp();
updateLockScreenTimeout();
}
mKeyguardDrawComplete = false;
- mWindowManagerDrawComplete = false;
+ mWindowManagerDrawComplete = false; // wait for later call to screenTurningOn
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
mKeyguardDelegate.onScreenTurnedOn(mKeyguardDelegateCallback);
+ // ... eventually calls finishKeyguardDrawn
} else {
if (DEBUG_WAKEUP) Slog.d(TAG, "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
+ finishKeyguardDrawn();
+ }
+ }
+
+ // Called on the mHandler thread.
+ private void finishKeyguardDrawn() {
+ if (!mKeyguardDrawComplete) {
mKeyguardDrawComplete = true;
+ mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
+ finishScreenTurningOn();
}
+ }
+
+ @Override
+ public void screenTurningOn(final ScreenOnListener screenOnListener) {
+ EventLog.writeEvent(70000, 1);
+ if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
+ mHandler.obtainMessage(MSG_SCREEN_TURNING_ON, screenOnListener).sendToTarget();
+ }
+
+ // Called on the mHandler thread.
+ private void handleScreenTurningOn(ScreenOnListener screenOnListener) {
+ mScreenOnListener = screenOnListener;
+
+ mWindowManagerDrawComplete = false;
mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
WAITING_FOR_DRAWN_TIMEOUT);
+ // ... eventually calls finishWindowsDrawn
+ }
+
+ // Called on the mHandler thread.
+ private void finishWindowsDrawn() {
+ if (!mWindowManagerDrawComplete) {
+ mWindowManagerDrawComplete = true;
+ finishScreenTurningOn();
+ }
}
// Called on the mHandler thread.
private void finishScreenTurningOn() {
if (DEBUG_WAKEUP) Slog.d(TAG,
- "finishScreenTurningOn: mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ "finishScreenTurningOn: mAwakeEarly=" + mAwakeEarly
+ + " mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ " mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
- if (!mKeyguardDrawComplete || !mWindowManagerDrawComplete) {
- return;
- }
-
- ScreenOnListener screenOnListener;
+ boolean awake;
synchronized (mLock) {
- mScreenOnFully = true;
- screenOnListener = mScreenOnListener;
- mScreenOnListener = null;
- }
+ if ((mAwakeEarly && !mKeyguardDrawComplete)
+ || !mWindowManagerDrawComplete) {
+ return;
+ }
- try {
- mWindowManager.setEventDispatching(true);
- } catch (RemoteException unhandled) {
+ if (mAwakeEarly) {
+ mAwakeFully = true;
+ }
+ awake = mAwakeFully;
}
- if (screenOnListener != null) {
- screenOnListener.onScreenOn();
+ if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on...");
+
+ if (mScreenOnListener != null) {
+ mScreenOnListener.onScreenOn();
+ mScreenOnListener = null;
}
- setKeyguardDrawn();
+ if (awake) {
+ setKeyguardDrawnFirstTime();
- if (mBootMessageNeedsHiding) {
- handleHideBootMessage();
- mBootMessageNeedsHiding = false;
+ if (mBootMessageNeedsHiding) {
+ handleHideBootMessage();
+ mBootMessageNeedsHiding = false;
+ }
}
}
@@ -4829,13 +4861,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public boolean isScreenOnEarly() {
- return mScreenOnEarly;
- }
-
- @Override
- public boolean isScreenOnFully() {
- return mScreenOnFully;
+ public boolean isAwake() {
+ return mAwakeFully;
}
/** {@inheritDoc} */
@@ -4909,7 +4936,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- private void setKeyguardDrawn() {
+ private void setKeyguardDrawnFirstTime() {
synchronized (mLock) {
mKeyguardDrawn = true;
}
@@ -5222,7 +5249,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
mSystemBooted = true;
}
- wakingUp(null);
+ wakingUp();
+ screenTurningOn(null);
}
ProgressDialog mBootMsgDialog = null;
@@ -5352,7 +5380,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private void updateLockScreenTimeout() {
synchronized (mScreenLockTimeout) {
- boolean enable = (mAllowLockscreenWhenOn && mScreenOnEarly &&
+ boolean enable = (mAllowLockscreenWhenOn && mAwakeEarly &&
mKeyguardDelegate != null && mKeyguardDelegate.isSecure());
if (mLockScreenTimerActive != enable) {
if (enable) {
@@ -5890,8 +5918,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior);
pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput);
- pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
- pw.print(" mScreenOnFully="); pw.print(mScreenOnFully);
+ pw.print(prefix); pw.print("mAwakeEarly="); pw.print(mAwakeEarly);
+ pw.print(" mAwakeFully="); pw.print(mAwakeFully);
pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
pw.print(prefix); pw.print("mOverscanScreen=("); pw.print(mOverscanScreenLeft);
pw.print(","); pw.print(mOverscanScreenTop);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 190c16c06740..7d96b84e1ec1 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9958,7 +9958,6 @@ public final class ActivityManagerService extends ActivityManagerNative
void goingToSleep() {
synchronized(this) {
mWentToSleep = true;
- updateEventDispatchingLocked();
goToSleepIfNeededLocked();
}
}
@@ -10056,7 +10055,6 @@ public final class ActivityManagerService extends ActivityManagerNative
void wakingUp() {
synchronized(this) {
mWentToSleep = false;
- updateEventDispatchingLocked();
comeOutOfSleepIfNeededLocked();
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 464972428409..c720668de693 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -256,16 +256,11 @@ final class Notifier {
if (mActualPowerState != POWER_STATE_AWAKE) {
mActualPowerState = POWER_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
- if (mPendingScreenOnUnblocker == null) {
- mScreenOnBlocker.acquire();
- }
- final ScreenOnUnblocker unblocker = new ScreenOnUnblocker();
- mPendingScreenOnUnblocker = unblocker;
mHandler.post(new Runnable() {
@Override
public void run() {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
- mPolicy.wakingUp(unblocker);
+ mPolicy.wakingUp();
mActivityManagerInternal.wakingUp();
}
});
@@ -338,6 +333,21 @@ final class Notifier {
}
/**
+ * Notifies that screen is about to be turned on (any state other than off).
+ */
+ public void onScreenTurningOn() {
+ synchronized (mLock) {
+ final ScreenOnUnblocker unblocker = blockScreenOnLocked();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mPolicy.screenTurningOn(unblocker);
+ }
+ });
+ }
+ }
+
+ /**
* Called when there has been user activity.
*/
public void onUserActivity(int event, int uid) {
@@ -460,6 +470,14 @@ final class Notifier {
}
}
+ private ScreenOnUnblocker blockScreenOnLocked() {
+ if (mPendingScreenOnUnblocker == null) {
+ mScreenOnBlocker.acquire();
+ }
+ mPendingScreenOnUnblocker = new ScreenOnUnblocker();
+ return mPendingScreenOnUnblocker;
+ }
+
private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
@Override
public void onScreenOn() {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c79a6d64121e..71e059ab3a60 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1767,6 +1767,7 @@ public final class PowerManagerService extends SystemService
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
| DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
+ boolean wasBlockerNeeded = isScreenOnBlockerNeededLocked(mDisplayPowerRequest);
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
int screenBrightness = mScreenBrightnessSettingDefault;
@@ -1803,8 +1804,6 @@ public final class PowerManagerService extends SystemService
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
-
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
@@ -1816,6 +1815,12 @@ public final class PowerManagerService extends SystemService
mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
}
+ if (!wasBlockerNeeded && isScreenOnBlockerNeededLocked(mDisplayPowerRequest)
+ && !mScreenOnBlocker.isHeld()) {
+ mNotifier.onScreenTurningOn();
+ }
+ mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
+
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
@@ -1832,6 +1837,17 @@ public final class PowerManagerService extends SystemService
return mDisplayReady && !oldDisplayReady;
}
+ private static boolean isScreenOnBlockerNeededLocked(DisplayPowerRequest req) {
+ switch (req.policy) {
+ case DisplayPowerRequest.POLICY_OFF:
+ return false;
+ case DisplayPowerRequest.POLICY_DOZE:
+ return req.dozeScreenState != Display.STATE_OFF;
+ default:
+ return true;
+ }
+ }
+
private static boolean isValidBrightness(int value) {
return value >= 0 && value <= 255;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fdf2fc8b00e0..b3341ede7d57 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3474,7 +3474,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
boolean okToDisplay() {
- return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
+ return !mDisplayFrozen && mDisplayEnabled && mPolicy.isAwake();
}
AppWindowToken findAppWindowToken(IBinder token) {
@@ -10397,7 +10397,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
- if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
+ if (!mDisplayReady || !mPolicy.isAwake()) {
// No need to freeze the screen before the system is ready or if
// the screen is off.
return;
@@ -11556,6 +11556,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ @Override
public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
synchronized (mWindowMap) {
mWaitingForDrawnCallback = callback;