OSDN Git Service

Decouple turning screen on from waking up in policy.
authorJeff Brown <jeffbrown@google.com>
Fri, 19 Sep 2014 19:05:31 +0000 (12:05 -0700)
committerJeff Brown <jeffbrown@google.com>
Fri, 19 Sep 2014 20:14:29 +0000 (13:14 -0700)
This allows us to ensure windows are fully drawn before unblocking
screen on while dozing.

Bug: 17516245
Change-Id: Ibe63c212b8db855ce26a34a8169f33764b266ee6

core/java/android/view/WindowManagerPolicy.java
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/power/Notifier.java
services/core/java/com/android/server/power/PowerManagerService.java
services/core/java/com/android/server/wm/WindowManagerService.java

index fec7550..d458ee4 100644 (file)
@@ -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.
index fbaaf74..aa49d37 100644 (file)
@@ -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);
index 190c16c..7d96b84 100755 (executable)
@@ -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();
         }
     }
index 4649724..c720668 100644 (file)
@@ -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() {
index c79a6d6..71e059a 100644 (file)
@@ -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;
     }
index fdf2fc8..b3341ed 100644 (file)
@@ -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;