am 901d8666: am 29126cf0: Merge "Ensure we send at least one wakeup/gotosleep transition." into jb-mr1-dev

* commit '901d8666f9421090cd33d3f2add66d39f93bf771':
  Ensure we send at least one wakeup/gotosleep transition.
This commit is contained in:
Jeff Brown
2012-10-04 20:24:14 -07:00
committed by Android Git Automerger
2 changed files with 63 additions and 30 deletions

View File

@@ -39,17 +39,20 @@ import android.view.WindowManagerPolicy.ScreenOnListener;
/**
* Sends broadcasts about important power state changes.
*
* <p>
* This methods of this class may be called by the power manager service while
* its lock is being held. Internally it takes care of sending broadcasts to
* notify other components of the system or applications asynchronously.
*
* </p><p>
* The notifier is designed to collapse unnecessary broadcasts when it is not
* possible for the system to have observed an intermediate state.
*
* For example, if the device wakes up, goes to sleep and wakes up again immediately
* before the go to sleep broadcast has been sent, then no broadcast will be
* sent about the system going to sleep and waking up.
* </p><p>
* For example, if the device wakes up, goes to sleep, wakes up again and goes to
* sleep again before the wake up notification is sent, then the system will
* be told about only one wake up and sleep. However, we always notify the
* fact that at least one transition occurred. It is especially important to
* tell the system when we go to sleep so that it can lock the keyguard if needed.
* </p>
*/
final class Notifier {
private static final String TAG = "PowerManagerNotifier";
@@ -79,6 +82,10 @@ final class Notifier {
private int mActualPowerState;
private int mLastGoToSleepReason;
// True if there is a pending transition that needs to be reported.
private boolean mPendingWakeUpBroadcast;
private boolean mPendingGoToSleepBroadcast;
// The currently broadcasted power state. This reflects what other parts of the
// system have observed.
private int mBroadcastedPowerState;
@@ -219,6 +226,7 @@ final class Notifier {
synchronized (mLock) {
if (mActualPowerState != POWER_STATE_AWAKE) {
mActualPowerState = POWER_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
updatePendingBroadcastLocked();
}
}
@@ -264,6 +272,7 @@ final class Notifier {
synchronized (mLock) {
if (mActualPowerState != POWER_STATE_ASLEEP) {
mActualPowerState = POWER_STATE_ASLEEP;
mPendingGoToSleepBroadcast = true;
if (mUserActivityPending) {
mUserActivityPending = false;
mHandler.removeMessages(MSG_USER_ACTIVITY);
@@ -300,7 +309,8 @@ final class Notifier {
private void updatePendingBroadcastLocked() {
if (!mBroadcastInProgress
&& mActualPowerState != POWER_STATE_UNKNOWN
&& mActualPowerState != mBroadcastedPowerState) {
&& (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mActualPowerState != mBroadcastedPowerState)) {
mBroadcastInProgress = true;
mSuspendBlocker.acquire();
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
@@ -309,6 +319,11 @@ final class Notifier {
}
}
private void finishPendingBroadcastLocked() {
mBroadcastInProgress = false;
mSuspendBlocker.release();
}
private void sendUserActivity() {
synchronized (mLock) {
if (!mUserActivityPending) {
@@ -324,18 +339,35 @@ final class Notifier {
final int powerState;
final int goToSleepReason;
synchronized (mLock) {
if (mActualPowerState == POWER_STATE_UNKNOWN
|| mActualPowerState == mBroadcastedPowerState) {
mBroadcastInProgress = false;
mSuspendBlocker.release();
return;
if (mBroadcastedPowerState == POWER_STATE_UNKNOWN) {
// Broadcasted power state is unknown. Send wake up.
mPendingWakeUpBroadcast = false;
mBroadcastedPowerState = POWER_STATE_AWAKE;
} else if (mBroadcastedPowerState == POWER_STATE_AWAKE) {
// Broadcasted power state is awake. Send asleep if needed.
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mActualPowerState == POWER_STATE_ASLEEP) {
mPendingGoToSleepBroadcast = false;
mBroadcastedPowerState = POWER_STATE_ASLEEP;
} else {
finishPendingBroadcastLocked();
return;
}
} else {
// Broadcasted power state is asleep. Send awake if needed.
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mActualPowerState == POWER_STATE_AWAKE) {
mPendingWakeUpBroadcast = false;
mBroadcastedPowerState = POWER_STATE_AWAKE;
} else {
finishPendingBroadcastLocked();
return;
}
}
powerState = mActualPowerState;
goToSleepReason = mLastGoToSleepReason;
mBroadcastedPowerState = powerState;
mBroadcastStartTime = SystemClock.uptimeMillis();
powerState = mBroadcastedPowerState;
goToSleepReason = mLastGoToSleepReason;
}
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);

View File

@@ -828,9 +828,9 @@ public final class PowerManagerService extends IPowerManager.Stub
switch (mWakefulness) {
case WAKEFULNESS_ASLEEP:
Slog.i(TAG, "Waking up from sleep...");
sendPendingNotificationsLocked();
mNotifier.onWakeUpStarted();
mSendWakeUpFinishedNotificationWhenReady = true;
mSendGoToSleepFinishedNotificationWhenReady = false;
break;
case WAKEFULNESS_DREAMING:
Slog.i(TAG, "Waking up from dream...");
@@ -901,12 +901,13 @@ public final class PowerManagerService extends IPowerManager.Stub
break;
}
sendPendingNotificationsLocked();
mNotifier.onGoToSleepStarted(reason);
mSendGoToSleepFinishedNotificationWhenReady = true;
mLastSleepTime = eventTime;
mDirty |= DIRTY_WAKEFULNESS;
mWakefulness = WAKEFULNESS_ASLEEP;
mNotifier.onGoToSleepStarted(reason);
mSendGoToSleepFinishedNotificationWhenReady = true;
mSendWakeUpFinishedNotificationWhenReady = false;
// Report the number of wake locks that will be cleared by going to sleep.
int numWakeLocksCleared = 0;
@@ -1005,7 +1006,9 @@ public final class PowerManagerService extends IPowerManager.Stub
updateDisplayPowerStateLocked(dirtyPhase2);
// Phase 3: Send notifications, if needed.
sendPendingNotificationsLocked();
if (mDisplayReady) {
sendPendingNotificationsLocked();
}
// Phase 4: Update suspend blocker.
// Because we might release the last suspend blocker here, we need to make sure
@@ -1014,15 +1017,13 @@ public final class PowerManagerService extends IPowerManager.Stub
}
private void sendPendingNotificationsLocked() {
if (mDisplayReady) {
if (mSendWakeUpFinishedNotificationWhenReady) {
mSendWakeUpFinishedNotificationWhenReady = false;
mNotifier.onWakeUpFinished();
}
if (mSendGoToSleepFinishedNotificationWhenReady) {
mSendGoToSleepFinishedNotificationWhenReady = false;
mNotifier.onGoToSleepFinished();
}
if (mSendWakeUpFinishedNotificationWhenReady) {
mSendWakeUpFinishedNotificationWhenReady = false;
mNotifier.onWakeUpFinished();
}
if (mSendGoToSleepFinishedNotificationWhenReady) {
mSendGoToSleepFinishedNotificationWhenReady = false;
mNotifier.onGoToSleepFinished();
}
}