diff options
10 files changed, 292 insertions, 111 deletions
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 @@ interface IWindowManager /** * 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 @@ public interface WindowManagerPolicy { * 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { } }; - /** {@inheritDoc} */ + @Override public void screenTurnedOff(int why) { EventLog.writeEvent(70000, 0); synchronized (mLock) { @@ -3596,7 +3596,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - /** {@inheritDoc} */ + @Override public void screenTurningOn(final ScreenOnListener screenOnListener) { EventLog.writeEvent(70000, 1); if (false) { @@ -3604,64 +3604,83 @@ public class PhoneWindowManager implements WindowManagerPolicy { here.fillInStackTrace(); Slog.i(TAG, "Screen turning on...", here); } - if (screenOnListener != null) { - if (mKeyguardMediator != null) { - try { - mWindowManager.setEventDispatching(true); - } catch (RemoteException unhandled) { - } + + synchronized (mLock) { + mScreenOnEarly = true; + updateOrientationListenerLp(); + updateLockScreenTimeout(); + } + + try { + mWindowManager.setEventDispatching(true); + } catch (RemoteException unhandled) { + } + + waitForKeyguard(screenOnListener); + } + + private void waitForKeyguard(final ScreenOnListener screenOnListener) { + if (mKeyguardMediator != null) { + if (screenOnListener != null) { 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; - } - } + @Override + public void onShown(IBinder windowToken) { + waitForKeyguardWindowDrawn(windowToken, screenOnListener); } }); - } - } else { - if (mKeyguardMediator != null) { - // Must set mScreenOn = true. + return; + } else { mKeyguardMediator.onScreenTurnedOn(null); } - synchronized (mLock) { - mScreenOnFully = true; + } 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) { - mScreenOnEarly = true; - updateOrientationListenerLp(); - updateLockScreenTimeout(); + mScreenOnFully = true; + } + + if (screenOnListener != null) { + screenOnListener.onScreenOn(); } } - /** {@inheritDoc} */ + @Override public boolean isScreenOnEarly() { return mScreenOnEarly; } - - /** {@inheritDoc} */ + + @Override public boolean isScreenOnFully() { return mScreenOnFully; } - + /** {@inheritDoc} */ public void enableKeyguard(boolean enabled) { if (mKeyguardMediator != null) { @@ -4236,22 +4255,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { } return true; } - - public void screenOnStartedLw() { - } - public void screenOnStoppedLw() { - if (mPowerManager.isScreenOn()) { - if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) { - long curTime = SystemClock.uptimeMillis(); - mPowerManager.userActivity(curTime, false); - } - } + @Override + public void keepScreenOnStartedLw() { } - public boolean allowKeyRepeat() { - // disable key repeat when screen is off - return mScreenOnEarly; + @Override + public void keepScreenOnStoppedLw() { + if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) { + long curTime = SystemClock.uptimeMillis(); + mPowerManager.userActivity(curTime, false); + } } private int updateSystemUiVisibilityLw() { 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 class DisplayPowerController { final boolean mustNotify; boolean mustInitialize = false; boolean updateAutoBrightness = mTwilightChanged; + boolean screenOnWasBlocked = false; mTwilightChanged = false; synchronized (mLock) { @@ -588,7 +589,6 @@ final class DisplayPowerController { if (mScreenOffBecauseOfProximity && mProximity != PROXIMITY_POSITIVE) { mScreenOffBecauseOfProximity = false; - setScreenOn(true); sendOnProximityNegative(); } } else { @@ -639,20 +639,43 @@ final class DisplayPowerController { // 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 @@ final class DisplayPowerController { // 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 @@ final class DisplayPowerRequest { // 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 @@ final class DisplayPowerRequest { screenBrightness = other.screenBrightness; screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment; useAutoBrightness = other.useAutoBrightness; + blockScreenOn = other.blockScreenOn; } @Override @@ -84,7 +93,8 @@ final class DisplayPowerRequest { && useProximitySensor == other.useProximitySensor && screenBrightness == other.screenBrightness && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment - && useAutoBrightness == other.useAutoBrightness; + && useAutoBrightness == other.useAutoBrightness + && blockScreenOn == other.blockScreenOn; } @Override @@ -98,6 +108,7 @@ final class DisplayPowerRequest { + ", 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.os.WorkSource; 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 @@ final class Notifier { 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 @@ final class Notifier { // 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 @@ final class Notifier { if (mActualPowerState != POWER_STATE_AWAKE) { mActualPowerState = POWER_STATE_AWAKE; mPendingWakeUpBroadcast = true; + if (!mScreenOnBlockerAcquired) { + mScreenOnBlockerAcquired = true; + mScreenOnBlocker.acquire(); + } updatePendingBroadcastLocked(); } } @@ -387,6 +393,7 @@ final class Notifier { EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0); mPolicy.screenTurningOn(mScreenOnListener); + try { ActivityManagerNative.getDefault().wakingUp(); } catch (RemoteException e) { @@ -402,6 +409,19 @@ final class Notifier { } } + 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 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub // 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 @@ public final class PowerManagerService extends IPowerManager.Stub synchronized (mLock) { mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService"); mWakeLockSuspendBlocker.acquire(); + mScreenOnBlocker = new ScreenOnBlockerImpl(); mHoldingWakeLockSuspendBlocker = true; mWakefulness = WAKEFULNESS_AWAKE; } @@ -368,9 +377,14 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub } } + 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 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub 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 @@ public final class PowerManagerService extends IPowerManager.Stub pw.println(" " + sb); } + pw.println(); + pw.println("Screen On Blocker: " + mScreenOnBlocker); + dpc = mDisplayPowerController; } @@ -2152,13 +2178,6 @@ public final class PowerManagerService extends IPowerManager.Stub } } - 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 @@ public final class PowerManagerService extends IPowerManager.Stub case MSG_SANDMAN: handleSandman(); break; + case MSG_SCREEN_ON_BLOCKER_RELEASED: + handleScreenOnBlockerReleased(); + break; } } } @@ -2321,4 +2343,49 @@ public final class PowerManagerService extends IPowerManager.Stub } } } + + 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 class WindowManagerService extends IWindowManager.Stub } } - 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class BridgeWindowManager implements IWindowManager { } @Override - public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) { - // TODO Auto-generated method stub + public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) { + return false; } @Override |
