Coordinate screen on with the window manager.
Bug: 7267457
Change-Id: Ic2c322253639e1f0b2e4e72a7b145025d0240f93
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index f7ba38c..e3250f9 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -201,8 +201,9 @@
/**
* Block until the given window has been drawn to the screen.
+ * Returns true if really waiting, false if the window does not exist.
*/
- void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
+ boolean waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
/**
* Device has a software navigation bar (separate from the status bar).
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 04b5e11..d25f4cd 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1058,18 +1058,13 @@
* Called when we have started keeping the screen on because a window
* requesting this has become visible.
*/
- public void screenOnStartedLw();
+ public void keepScreenOnStartedLw();
/**
* Called when we have stopped keeping the screen on because the last window
* requesting this is no longer visible.
*/
- public void screenOnStoppedLw();
-
- /**
- * Return false to disable key repeat events from being generated.
- */
- public boolean allowKeyRepeat();
+ public void keepScreenOnStoppedLw();
/**
* Inform the policy that the user has chosen a preferred orientation ("rotation lock").
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ed9c6a3..60c6d06 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3580,7 +3580,7 @@
}
};
- /** {@inheritDoc} */
+ @Override
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
synchronized (mLock) {
@@ -3596,7 +3596,7 @@
}
}
- /** {@inheritDoc} */
+ @Override
public void screenTurningOn(final ScreenOnListener screenOnListener) {
EventLog.writeEvent(70000, 1);
if (false) {
@@ -3604,64 +3604,83 @@
here.fillInStackTrace();
Slog.i(TAG, "Screen turning on...", here);
}
- if (screenOnListener != null) {
- if (mKeyguardMediator != null) {
- try {
- mWindowManager.setEventDispatching(true);
- } catch (RemoteException unhandled) {
- }
- mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
- @Override public void onShown(IBinder windowToken) {
- if (windowToken != null) {
- try {
- mWindowManager.waitForWindowDrawn(windowToken,
- new IRemoteCallback.Stub() {
- @Override public void sendResult(Bundle data) {
- Slog.i(TAG, "Lock screen displayed!");
- screenOnListener.onScreenOn();
- synchronized (mLock) {
- mScreenOnFully = true;
- }
- }
- });
- } catch (RemoteException e) {
- }
- } else {
- Slog.i(TAG, "No lock screen!");
- screenOnListener.onScreenOn();
- synchronized (mLock) {
- mScreenOnFully = true;
- }
- }
- }
- });
- }
- } else {
- if (mKeyguardMediator != null) {
- // Must set mScreenOn = true.
- mKeyguardMediator.onScreenTurnedOn(null);
- }
- synchronized (mLock) {
- mScreenOnFully = true;
- }
- }
+
synchronized (mLock) {
mScreenOnEarly = true;
updateOrientationListenerLp();
updateLockScreenTimeout();
}
+
+ try {
+ mWindowManager.setEventDispatching(true);
+ } catch (RemoteException unhandled) {
+ }
+
+ waitForKeyguard(screenOnListener);
}
- /** {@inheritDoc} */
+ private void waitForKeyguard(final ScreenOnListener screenOnListener) {
+ if (mKeyguardMediator != null) {
+ if (screenOnListener != null) {
+ mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
+ @Override
+ public void onShown(IBinder windowToken) {
+ waitForKeyguardWindowDrawn(windowToken, screenOnListener);
+ }
+ });
+ return;
+ } else {
+ mKeyguardMediator.onScreenTurnedOn(null);
+ }
+ } else {
+ Slog.i(TAG, "No keyguard mediator!");
+ }
+ finishScreenTurningOn(screenOnListener);
+ }
+
+ private void waitForKeyguardWindowDrawn(IBinder windowToken,
+ final ScreenOnListener screenOnListener) {
+ if (windowToken != null) {
+ try {
+ if (mWindowManager.waitForWindowDrawn(
+ windowToken, new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle data) {
+ Slog.i(TAG, "Lock screen displayed!");
+ finishScreenTurningOn(screenOnListener);
+ }
+ })) {
+ return;
+ }
+ } catch (RemoteException ex) {
+ // Can't happen in system process.
+ }
+ }
+
+ Slog.i(TAG, "No lock screen!");
+ finishScreenTurningOn(screenOnListener);
+ }
+
+ private void finishScreenTurningOn(ScreenOnListener screenOnListener) {
+ synchronized (mLock) {
+ mScreenOnFully = true;
+ }
+
+ if (screenOnListener != null) {
+ screenOnListener.onScreenOn();
+ }
+ }
+
+ @Override
public boolean isScreenOnEarly() {
return mScreenOnEarly;
}
-
- /** {@inheritDoc} */
+
+ @Override
public boolean isScreenOnFully() {
return mScreenOnFully;
}
-
+
/** {@inheritDoc} */
public void enableKeyguard(boolean enabled) {
if (mKeyguardMediator != null) {
@@ -4236,24 +4255,19 @@
}
return true;
}
-
- public void screenOnStartedLw() {
+
+ @Override
+ public void keepScreenOnStartedLw() {
}
- public void screenOnStoppedLw() {
- if (mPowerManager.isScreenOn()) {
- if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
- long curTime = SystemClock.uptimeMillis();
- mPowerManager.userActivity(curTime, false);
- }
+ @Override
+ public void keepScreenOnStoppedLw() {
+ if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
+ long curTime = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(curTime, false);
}
}
- public boolean allowKeyRepeat() {
- // disable key repeat when screen is off
- return mScreenOnEarly;
- }
-
private int updateSystemUiVisibilityLw() {
// If there is no window focused, there will be nobody to handle the events
// anyway, so just hang on in whatever state we're in until things settle down.
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index b9f9df7..23df701 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -531,6 +531,7 @@
final boolean mustNotify;
boolean mustInitialize = false;
boolean updateAutoBrightness = mTwilightChanged;
+ boolean screenOnWasBlocked = false;
mTwilightChanged = false;
synchronized (mLock) {
@@ -588,7 +589,6 @@
if (mScreenOffBecauseOfProximity
&& mProximity != PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = false;
- setScreenOn(true);
sendOnProximityNegative();
}
} else {
@@ -639,20 +639,43 @@
// It is relatively short but if we cancel it and switch to the
// on animation immediately then the results are pretty ugly.
if (!mElectronBeamOffAnimator.isStarted()) {
- setScreenOn(true);
- if (USE_ELECTRON_BEAM_ON_ANIMATION) {
- if (!mElectronBeamOnAnimator.isStarted()) {
- if (mPowerState.getElectronBeamLevel() == 1.0f) {
- mPowerState.dismissElectronBeam();
- } else if (mPowerState.prepareElectronBeam(true)) {
- mElectronBeamOnAnimator.start();
- } else {
- mElectronBeamOnAnimator.end();
- }
+ if (mPowerRequest.blockScreenOn && !mPowerState.isScreenOn()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Blocked screen on while screen currently off.");
}
+ screenOnWasBlocked = true;
} else {
- mPowerState.setElectronBeamLevel(1.0f);
- mPowerState.dismissElectronBeam();
+ setScreenOn(true);
+ if (USE_ELECTRON_BEAM_ON_ANIMATION) {
+ if (!mElectronBeamOnAnimator.isStarted()) {
+ if (mPowerState.getElectronBeamLevel() == 1.0f) {
+ mPowerState.dismissElectronBeam();
+ } else if (mPowerState.prepareElectronBeam(true)) {
+ mElectronBeamOnAnimator.start();
+ } else {
+ mElectronBeamOnAnimator.end();
+ }
+ }
+ } else {
+ mPowerState.setElectronBeamLevel(1.0f);
+ mPowerState.dismissElectronBeam();
+ }
+ }
+ } else {
+ // FIXME: If the electron beam off animation is playing then we have a bit
+ // of a problem. The window manager policy would only have requested
+ // to block screen on if it was about to start preparing the keyguard.
+ // It's already too late to do anything about that. Ideally we would
+ // let the animation play out first but that would require making
+ // some pretty deep changes to the power manager and we don't have
+ // time just now. For now, short-circuit the animation and get ready.
+ if (mPowerRequest.blockScreenOn) {
+ if (DEBUG) {
+ Slog.d(TAG, "Blocked screen on while screen off animation running.");
+ }
+ screenOnWasBlocked = true;
+ setScreenOn(false);
+ mElectronBeamOffAnimator.end();
}
}
} else {
@@ -677,12 +700,17 @@
// We mostly care about the screen state here, ignoring brightness changes
// which will be handled asynchronously.
if (mustNotify
+ && !screenOnWasBlocked
&& !mElectronBeamOnAnimator.isStarted()
&& !mElectronBeamOffAnimator.isStarted()
&& mPowerState.waitUntilClean(mCleanListener)) {
synchronized (mLock) {
if (!mPendingRequestChangedLocked) {
mDisplayReadyLocked = true;
+
+ if (DEBUG) {
+ Slog.d(TAG, "Display ready!");
+ }
}
}
sendOnStateChanged();
diff --git a/services/java/com/android/server/power/DisplayPowerRequest.java b/services/java/com/android/server/power/DisplayPowerRequest.java
index 2d74292..5f94414 100644
--- a/services/java/com/android/server/power/DisplayPowerRequest.java
+++ b/services/java/com/android/server/power/DisplayPowerRequest.java
@@ -52,12 +52,20 @@
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
+ // If true, prevents the screen from turning on if it is currently off.
+ // The display does not enter a "ready" state if this flag is true and the screen
+ // is off and is being prevented from turning on. The window manager policy blocks
+ // screen on while it prepares the keyguard to prevent the user from seeing
+ // intermediate updates.
+ public boolean blockScreenOn;
+
public DisplayPowerRequest() {
screenState = SCREEN_STATE_BRIGHT;
useProximitySensor = false;
screenBrightness = PowerManager.BRIGHTNESS_ON;
screenAutoBrightnessAdjustment = 0.0f;
useAutoBrightness = false;
+ blockScreenOn = false;
}
public DisplayPowerRequest(DisplayPowerRequest other) {
@@ -70,6 +78,7 @@
screenBrightness = other.screenBrightness;
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
useAutoBrightness = other.useAutoBrightness;
+ blockScreenOn = other.blockScreenOn;
}
@Override
@@ -84,7 +93,8 @@
&& useProximitySensor == other.useProximitySensor
&& screenBrightness == other.screenBrightness
&& screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
- && useAutoBrightness == other.useAutoBrightness;
+ && useAutoBrightness == other.useAutoBrightness
+ && blockScreenOn == other.blockScreenOn;
}
@Override
@@ -98,6 +108,7 @@
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightness=" + screenBrightness
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
- + ", useAutoBrightness=" + useAutoBrightness;
+ + ", useAutoBrightness=" + useAutoBrightness
+ + ", blockScreenOn=" + blockScreenOn;
}
}
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
index 3042124..5e05693 100644
--- a/services/java/com/android/server/power/Notifier.java
+++ b/services/java/com/android/server/power/Notifier.java
@@ -35,7 +35,6 @@
import android.util.EventLog;
import android.util.Slog;
import android.view.WindowManagerPolicy;
-import android.view.WindowManagerPolicy.ScreenOnListener;
/**
* Sends broadcasts about important power state changes.
@@ -71,8 +70,8 @@
private final Context mContext;
private final IBatteryStats mBatteryStats;
private final SuspendBlocker mSuspendBlocker;
+ private final ScreenOnBlocker mScreenOnBlocker;
private final WindowManagerPolicy mPolicy;
- private final ScreenOnListener mScreenOnListener;
private final NotifierHandler mHandler;
private final Intent mScreenOnIntent;
@@ -95,14 +94,17 @@
// True if a user activity message should be sent.
private boolean mUserActivityPending;
+ // True if the screen on blocker has been acquired.
+ private boolean mScreenOnBlockerAcquired;
+
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
- SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- ScreenOnListener screenOnListener) {
+ SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker,
+ WindowManagerPolicy policy) {
mContext = context;
mBatteryStats = batteryStats;
mSuspendBlocker = suspendBlocker;
+ mScreenOnBlocker = screenOnBlocker;
mPolicy = policy;
- mScreenOnListener = screenOnListener;
mHandler = new NotifierHandler(looper);
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -227,6 +229,10 @@
if (mActualPowerState != POWER_STATE_AWAKE) {
mActualPowerState = POWER_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
+ if (!mScreenOnBlockerAcquired) {
+ mScreenOnBlockerAcquired = true;
+ mScreenOnBlocker.acquire();
+ }
updatePendingBroadcastLocked();
}
}
@@ -387,6 +393,7 @@
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
mPolicy.screenTurningOn(mScreenOnListener);
+
try {
ActivityManagerNative.getDefault().wakingUp();
} catch (RemoteException e) {
@@ -402,6 +409,19 @@
}
}
+ private final WindowManagerPolicy.ScreenOnListener mScreenOnListener =
+ new WindowManagerPolicy.ScreenOnListener() {
+ @Override
+ public void onScreenOn() {
+ synchronized (mLock) {
+ if (mScreenOnBlockerAcquired && !mPendingWakeUpBroadcast) {
+ mScreenOnBlockerAcquired = false;
+ mScreenOnBlocker.release();
+ }
+ }
+ }
+ };
+
private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index ae7b2d1..f584302 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -79,6 +79,8 @@
private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
// Message: Sent when the device enters or exits a napping or dreaming state.
private static final int MSG_SANDMAN = 2;
+ // Message: Sent when the screen on blocker is released.
+ private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
// Dirty bit: mWakeLocks changed
private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@@ -100,6 +102,8 @@
private static final int DIRTY_BATTERY_STATE = 1 << 8;
// Dirty bit: proximity state changed
private static final int DIRTY_PROXIMITY_POSITIVE = 1 << 9;
+ // Dirty bit: screen on blocker state became held or unheld
+ private static final int DIRTY_SCREEN_ON_BLOCKER_RELEASED = 1 << 10;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
@@ -222,6 +226,10 @@
// The suspend blocker used to keep the CPU alive when wake locks have been acquired.
private final SuspendBlocker mWakeLockSuspendBlocker;
+ // The screen on blocker used to keep the screen from turning on while the lock
+ // screen is coming up.
+ private final ScreenOnBlockerImpl mScreenOnBlocker;
+
// True if systemReady() has been called.
private boolean mSystemReady;
@@ -318,6 +326,7 @@
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService");
mWakeLockSuspendBlocker.acquire();
+ mScreenOnBlocker = new ScreenOnBlockerImpl();
mHoldingWakeLockSuspendBlocker = true;
mWakefulness = WAKEFULNESS_AWAKE;
}
@@ -368,9 +377,14 @@
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
- mNotifier = new Notifier(mHandler.getLooper(), mContext, mBatteryStats,
+ // The notifier runs on the system server's main looper so as not to interfere
+ // with the animations and other critical functions of the power manager.
+ mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
- mPolicy, mScreenOnListener);
+ mScreenOnBlocker, mPolicy);
+
+ // The display power controller runs on the power manager service's
+ // own handler thread.
mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
mContext, mNotifier, mLightsService, twilight,
createSuspendBlockerLocked("PowerManagerService.Display"),
@@ -1433,6 +1447,13 @@
}
}
+ private void handleScreenOnBlockerReleased() {
+ synchronized (mLock) {
+ mDirty |= DIRTY_SCREEN_ON_BLOCKER_RELEASED;
+ updatePowerStateLocked();
+ }
+ }
+
/**
* Updates the display power state asynchronously.
* When the update is finished, mDisplayReady will be set to true. The display
@@ -1444,8 +1465,8 @@
private void updateDisplayPowerStateLocked(int dirty) {
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS)) != 0) {
- int newScreenState = getDesiredScreenPowerState();
+ | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {
+ int newScreenState = getDesiredScreenPowerStateLocked();
if (newScreenState != mDisplayPowerRequest.screenState) {
if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF
&& mDisplayPowerRequest.screenState
@@ -1493,12 +1514,14 @@
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
+ mDisplayPowerRequest.blockScreenOn = mScreenOnBlocker.isHeld();
+
mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
- Slog.d(TAG, "updateScreenStateLocked: displayReady=" + mDisplayReady
+ Slog.d(TAG, "updateScreenStateLocked: mDisplayReady=" + mDisplayReady
+ ", newScreenState=" + newScreenState
+ ", mWakefulness=" + mWakefulness
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
@@ -1517,7 +1540,7 @@
return value >= -1.0f && value <= 1.0f;
}
- private int getDesiredScreenPowerState() {
+ private int getDesiredScreenPowerStateLocked() {
if (mWakefulness == WAKEFULNESS_ASLEEP) {
return DisplayPowerRequest.SCREEN_STATE_OFF;
}
@@ -2070,6 +2093,9 @@
pw.println(" " + sb);
}
+ pw.println();
+ pw.println("Screen On Blocker: " + mScreenOnBlocker);
+
dpc = mDisplayPowerController;
}
@@ -2152,13 +2178,6 @@
}
}
- private final WindowManagerPolicy.ScreenOnListener mScreenOnListener =
- new WindowManagerPolicy.ScreenOnListener() {
- @Override
- public void onScreenOn() {
- }
- };
-
/**
* Handler for asynchronous operations performed by the power manager.
*/
@@ -2176,6 +2195,9 @@
case MSG_SANDMAN:
handleSandman();
break;
+ case MSG_SCREEN_ON_BLOCKER_RELEASED:
+ handleScreenOnBlockerReleased();
+ break;
}
}
}
@@ -2321,4 +2343,49 @@
}
}
}
+
+ private final class ScreenOnBlockerImpl implements ScreenOnBlocker {
+ private int mNestCount;
+
+ public boolean isHeld() {
+ synchronized (this) {
+ return mNestCount != 0;
+ }
+ }
+
+ @Override
+ public void acquire() {
+ synchronized (this) {
+ mNestCount += 1;
+ if (DEBUG) {
+ Slog.d(TAG, "Screen on blocked: mNestCount=" + mNestCount);
+ }
+ }
+ }
+
+ @Override
+ public void release() {
+ synchronized (this) {
+ mNestCount -= 1;
+ if (mNestCount < 0) {
+ Log.wtf(TAG, "Screen on blocker was released without being acquired!",
+ new Throwable());
+ mNestCount = 0;
+ }
+ if (mNestCount == 0) {
+ mHandler.sendEmptyMessage(MSG_SCREEN_ON_BLOCKER_RELEASED);
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Screen on unblocked: mNestCount=" + mNestCount);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ synchronized (this) {
+ return "held=" + (mNestCount != 0) + ", mNestCount=" + mNestCount;
+ }
+ }
+ };
}
diff --git a/services/java/com/android/server/power/ScreenOnBlocker.java b/services/java/com/android/server/power/ScreenOnBlocker.java
new file mode 100644
index 0000000..2bf0bcf
--- /dev/null
+++ b/services/java/com/android/server/power/ScreenOnBlocker.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+/**
+ * Low-level screen on blocker mechanism which is used to keep the screen off
+ * until the window manager is ready to show new content.
+ */
+interface ScreenOnBlocker {
+ /**
+ * Acquires the screen on blocker.
+ * Prevents the screen from turning on.
+ *
+ * Calls to acquire() nest and must be matched by the same number
+ * of calls to release().
+ */
+ void acquire();
+
+ /**
+ * Releases the screen on blocker.
+ * Allows the screen to turn on.
+ *
+ * It is an error to call release() if the screen on blocker has not been acquired.
+ * The system may crash.
+ */
+ void release();
+}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 8cc3d61..8f5103c 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9450,18 +9450,22 @@
}
}
- public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
- synchronized (mWindowMap) {
- WindowState win = windowForClientLocked(null, token, true);
- if (win != null) {
- Pair<WindowState, IRemoteCallback> pair =
- new Pair<WindowState, IRemoteCallback>(win, callback);
- Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
- mH.sendMessageDelayed(m, 2000);
- mWaitingForDrawn.add(pair);
- checkDrawnWindowsLocked();
+ public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
+ if (token != null && callback != null) {
+ synchronized (mWindowMap) {
+ WindowState win = windowForClientLocked(null, token, true);
+ if (win != null) {
+ Pair<WindowState, IRemoteCallback> pair =
+ new Pair<WindowState, IRemoteCallback>(win, callback);
+ Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+ mH.sendMessageDelayed(m, 2000);
+ mWaitingForDrawn.add(pair);
+ checkDrawnWindowsLocked();
+ return true;
+ }
}
}
+ return false;
}
void setHoldScreenLocked(final Session newHoldScreen) {
@@ -9475,10 +9479,10 @@
final boolean state = mHoldingScreenWakeLock.isHeld();
if (hold != state) {
if (hold) {
- mPolicy.screenOnStartedLw();
mHoldingScreenWakeLock.acquire();
+ mPolicy.keepScreenOnStartedLw();
} else {
- mPolicy.screenOnStoppedLw();
+ mPolicy.keepScreenOnStoppedLw();
mHoldingScreenWakeLock.release();
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index dbd52a0..9ddaf63 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -414,8 +414,8 @@
}
@Override
- public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
- // TODO Auto-generated method stub
+ public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
+ return false;
}
@Override