Merge "Tell PhoneWindowManager when we start/finish interactive changes." into mnc-dev
This commit is contained in:
@@ -945,17 +945,30 @@ public interface WindowManagerPolicy {
|
||||
public int focusChangedLw(WindowState lastFocus, WindowState newFocus);
|
||||
|
||||
/**
|
||||
* Called when the device is waking up.
|
||||
* Called when the device has started waking up.
|
||||
*/
|
||||
public void wakingUp();
|
||||
public void startedWakingUp();
|
||||
|
||||
/**
|
||||
* Called when the device is going to sleep.
|
||||
*
|
||||
* @param why {@link #OFF_BECAUSE_OF_USER} or
|
||||
* {@link #OFF_BECAUSE_OF_TIMEOUT}.
|
||||
* Called when the device has finished waking up.
|
||||
*/
|
||||
public void goingToSleep(int why);
|
||||
public void finishedWakingUp();
|
||||
|
||||
/**
|
||||
* Called when the device has started going to sleep.
|
||||
*
|
||||
* @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
|
||||
* or {@link #OFF_BECAUSE_OF_TIMEOUT}.
|
||||
*/
|
||||
public void startedGoingToSleep(int why);
|
||||
|
||||
/**
|
||||
* Called when the device has finished going to sleep.
|
||||
*
|
||||
* @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
|
||||
* or {@link #OFF_BECAUSE_OF_TIMEOUT}.
|
||||
*/
|
||||
public void finishedGoingToSleep(int why);
|
||||
|
||||
/**
|
||||
* Called when the device is about to turn on the screen to show content.
|
||||
|
||||
@@ -1455,7 +1455,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
|
||||
// Match current screen state.
|
||||
if (!mPowerManager.isInteractive()) {
|
||||
goingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
|
||||
startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
|
||||
finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
|
||||
}
|
||||
|
||||
mWindowManagerInternal.registerAppTransitionListener(
|
||||
@@ -5233,9 +5234,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
|
||||
// Called on the PowerManager's Notifier thread.
|
||||
@Override
|
||||
public void goingToSleep(int why) {
|
||||
public void startedGoingToSleep(int why) {
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
|
||||
}
|
||||
|
||||
// Called on the PowerManager's Notifier thread.
|
||||
@Override
|
||||
public void finishedGoingToSleep(int why) {
|
||||
EventLog.writeEvent(70000, 0);
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Going to sleep...");
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
|
||||
|
||||
// We must get this work done here because the power manager will drop
|
||||
// the wake lock and let the system suspend once this function returns.
|
||||
@@ -5252,24 +5259,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
private void wakeUpFromPowerKey(long eventTime) {
|
||||
wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey);
|
||||
}
|
||||
|
||||
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) {
|
||||
if (!wakeInTheaterMode && isTheaterModeEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mPowerManager.wakeUp(wakeTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called on the PowerManager's Notifier thread.
|
||||
@Override
|
||||
public void wakingUp() {
|
||||
public void startedWakingUp() {
|
||||
EventLog.writeEvent(70000, 1);
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Waking up...");
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
|
||||
|
||||
// Since goToSleep performs these functions synchronously, we must
|
||||
// do the same here. We cannot post this work to a handler because
|
||||
@@ -5297,6 +5291,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
// Called on the PowerManager's Notifier thread.
|
||||
@Override
|
||||
public void finishedWakingUp() {
|
||||
if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
|
||||
}
|
||||
|
||||
private void wakeUpFromPowerKey(long eventTime) {
|
||||
wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey);
|
||||
}
|
||||
|
||||
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) {
|
||||
if (!wakeInTheaterMode && isTheaterModeEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mPowerManager.wakeUp(wakeTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void finishKeyguardDrawn() {
|
||||
synchronized (mLock) {
|
||||
if (!mAwake || mKeyguardDrawComplete) {
|
||||
@@ -5789,7 +5802,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
synchronized (mLock) {
|
||||
mSystemBooted = true;
|
||||
}
|
||||
wakingUp();
|
||||
startedWakingUp();
|
||||
screenTurningOn(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,11 +95,19 @@ final class Notifier {
|
||||
private final Intent mScreenOffIntent;
|
||||
private final Intent mScreenBrightnessBoostIntent;
|
||||
|
||||
// The current interactive state.
|
||||
private int mActualInteractiveState;
|
||||
private int mLastReason;
|
||||
// The current interactive state. This is set as soon as an interactive state
|
||||
// transition begins so as to capture the reason that it happened. At some point
|
||||
// this state will propagate to the pending state then eventually to the
|
||||
// broadcasted state over the course of reporting the transition asynchronously.
|
||||
private boolean mInteractive = true;
|
||||
private int mInteractiveChangeReason;
|
||||
private boolean mInteractiveChanging;
|
||||
|
||||
// True if there is a pending transition that needs to be reported.
|
||||
// The pending interactive state that we will eventually want to broadcast.
|
||||
// This is designed so that we can collapse redundant sequences of awake/sleep
|
||||
// transition pairs while still guaranteeing that at least one transition is observed
|
||||
// whenever this happens.
|
||||
private int mPendingInteractiveState;
|
||||
private boolean mPendingWakeUpBroadcast;
|
||||
private boolean mPendingGoToSleepBroadcast;
|
||||
|
||||
@@ -244,45 +252,17 @@ final class Notifier {
|
||||
|
||||
/**
|
||||
* Notifies that the device is changing wakefulness.
|
||||
* This function may be called even if the previous change hasn't finished in
|
||||
* which case it will assume that the state did not fully converge before the
|
||||
* next transition began and will recover accordingly.
|
||||
*/
|
||||
public void onWakefulnessChangeStarted(int wakefulness, int reason) {
|
||||
public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
|
||||
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
|
||||
+ ", reason=" + reason);
|
||||
+ ", reason=" + reason + ", interactive=" + interactive);
|
||||
}
|
||||
|
||||
// We handle interactive state changes once they start so that the system can
|
||||
// set everything up or the user to begin interacting with applications.
|
||||
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
|
||||
if (interactive) {
|
||||
handleWakefulnessChange(wakefulness, interactive, reason);
|
||||
} else {
|
||||
mLastReason = reason;
|
||||
}
|
||||
|
||||
// Start input as soon as we start waking up or going to sleep.
|
||||
mInputManagerInternal.setInteractive(interactive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the device has finished changing wakefulness.
|
||||
*/
|
||||
public void onWakefulnessChangeFinished(int wakefulness) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakefulnessChangeFinished: wakefulness=" + wakefulness);
|
||||
}
|
||||
|
||||
// Handle interactive state changes once they are finished so that the system can
|
||||
// finish pending transitions (such as turning the screen off) before causing
|
||||
// applications to change state visibly.
|
||||
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
|
||||
if (!interactive) {
|
||||
handleWakefulnessChange(wakefulness, interactive, mLastReason);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWakefulnessChange(final int wakefulness, boolean interactive,
|
||||
final int reason) {
|
||||
// Tell the activity manager about changes in wakefulness, not just interactivity.
|
||||
// It needs more granularity than other components.
|
||||
mHandler.post(new Runnable() {
|
||||
@@ -292,65 +272,132 @@ final class Notifier {
|
||||
}
|
||||
});
|
||||
|
||||
// Handle changes in the overall interactive state.
|
||||
boolean interactiveChanged = false;
|
||||
synchronized (mLock) {
|
||||
// Broadcast interactive state changes.
|
||||
if (interactive) {
|
||||
// Waking up...
|
||||
interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_AWAKE);
|
||||
if (interactiveChanged) {
|
||||
mActualInteractiveState = INTERACTIVE_STATE_AWAKE;
|
||||
mPendingWakeUpBroadcast = true;
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
|
||||
mPolicy.wakingUp();
|
||||
}
|
||||
});
|
||||
updatePendingBroadcastLocked();
|
||||
}
|
||||
} else {
|
||||
// Going to sleep...
|
||||
// This is a good time to make transitions that we don't want the user to see,
|
||||
// such as bringing the key guard to focus. There's no guarantee for this,
|
||||
// however because the user could turn the device on again at any time.
|
||||
// Some things may need to be protected by other mechanisms that defer screen on.
|
||||
interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_ASLEEP);
|
||||
if (interactiveChanged) {
|
||||
mActualInteractiveState = INTERACTIVE_STATE_ASLEEP;
|
||||
mPendingGoToSleepBroadcast = true;
|
||||
if (mUserActivityPending) {
|
||||
mUserActivityPending = false;
|
||||
mHandler.removeMessages(MSG_USER_ACTIVITY);
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;
|
||||
switch (reason) {
|
||||
case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
|
||||
why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
|
||||
break;
|
||||
case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
|
||||
why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
|
||||
mPolicy.goingToSleep(why);
|
||||
}
|
||||
});
|
||||
updatePendingBroadcastLocked();
|
||||
}
|
||||
// Handle any early interactive state changes.
|
||||
// Finish pending incomplete ones from a previous cycle.
|
||||
if (mInteractive != interactive) {
|
||||
// Finish up late behaviors if needed.
|
||||
if (mInteractiveChanging) {
|
||||
handleLateInteractiveChange();
|
||||
}
|
||||
}
|
||||
|
||||
// Notify battery stats.
|
||||
if (interactiveChanged) {
|
||||
// Start input as soon as we start waking up or going to sleep.
|
||||
mInputManagerInternal.setInteractive(interactive);
|
||||
|
||||
// Notify battery stats.
|
||||
try {
|
||||
mBatteryStats.noteInteractive(interactive);
|
||||
} catch (RemoteException ex) { }
|
||||
|
||||
// Handle early behaviors.
|
||||
mInteractive = interactive;
|
||||
mInteractiveChangeReason = reason;
|
||||
mInteractiveChanging = true;
|
||||
handleEarlyInteractiveChange();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the device has finished changing wakefulness.
|
||||
*/
|
||||
public void onWakefulnessChangeFinished() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onWakefulnessChangeFinished");
|
||||
}
|
||||
|
||||
if (mInteractiveChanging) {
|
||||
mInteractiveChanging = false;
|
||||
handleLateInteractiveChange();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle early interactive state changes such as getting applications or the lock
|
||||
* screen running and ready for the user to see (such as when turning on the screen).
|
||||
*/
|
||||
private void handleEarlyInteractiveChange() {
|
||||
synchronized (mLock) {
|
||||
if (mInteractive) {
|
||||
// Waking up...
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
|
||||
mPolicy.startedWakingUp();
|
||||
}
|
||||
});
|
||||
|
||||
// Send interactive broadcast.
|
||||
mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
|
||||
mPendingWakeUpBroadcast = true;
|
||||
updatePendingBroadcastLocked();
|
||||
} else {
|
||||
// Going to sleep...
|
||||
// Tell the policy that we started going to sleep.
|
||||
final int why = translateOffReason(mInteractiveChangeReason);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPolicy.startedGoingToSleep(why);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle late interactive state changes once they are finished so that the system can
|
||||
* finish pending transitions (such as turning the screen off) before causing
|
||||
* applications to change state visibly.
|
||||
*/
|
||||
private void handleLateInteractiveChange() {
|
||||
synchronized (mLock) {
|
||||
if (mInteractive) {
|
||||
// Finished waking up...
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPolicy.finishedWakingUp();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Finished going to sleep...
|
||||
// This is a good time to make transitions that we don't want the user to see,
|
||||
// such as bringing the key guard to focus. There's no guarantee for this
|
||||
// however because the user could turn the device on again at any time.
|
||||
// Some things may need to be protected by other mechanisms that defer screen on.
|
||||
|
||||
// Cancel pending user activity.
|
||||
if (mUserActivityPending) {
|
||||
mUserActivityPending = false;
|
||||
mHandler.removeMessages(MSG_USER_ACTIVITY);
|
||||
}
|
||||
|
||||
// Tell the policy we finished going to sleep.
|
||||
final int why = translateOffReason(mInteractiveChangeReason);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
|
||||
mPolicy.finishedGoingToSleep(why);
|
||||
}
|
||||
});
|
||||
|
||||
// Send non-interactive broadcast.
|
||||
mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
|
||||
mPendingGoToSleepBroadcast = true;
|
||||
updatePendingBroadcastLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int translateOffReason(int reason) {
|
||||
switch (reason) {
|
||||
case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
|
||||
return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
|
||||
case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
|
||||
return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
|
||||
default:
|
||||
return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +414,7 @@ final class Notifier {
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there has been user activity.
|
||||
*/
|
||||
@@ -407,9 +455,9 @@ final class Notifier {
|
||||
|
||||
private void updatePendingBroadcastLocked() {
|
||||
if (!mBroadcastInProgress
|
||||
&& mActualInteractiveState != INTERACTIVE_STATE_UNKNOWN
|
||||
&& mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
|
||||
&& (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|
||||
|| mActualInteractiveState != mBroadcastedInteractiveState)) {
|
||||
|| mPendingInteractiveState != mBroadcastedInteractiveState)) {
|
||||
mBroadcastInProgress = true;
|
||||
mSuspendBlocker.acquire();
|
||||
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
|
||||
@@ -444,7 +492,7 @@ final class Notifier {
|
||||
} else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
|
||||
// Broadcasted power state is awake. Send asleep if needed.
|
||||
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|
||||
|| mActualInteractiveState == INTERACTIVE_STATE_ASLEEP) {
|
||||
|| mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
|
||||
mPendingGoToSleepBroadcast = false;
|
||||
mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
|
||||
} else {
|
||||
@@ -454,7 +502,7 @@ final class Notifier {
|
||||
} else {
|
||||
// Broadcasted power state is asleep. Send awake if needed.
|
||||
if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|
||||
|| mActualInteractiveState == INTERACTIVE_STATE_AWAKE) {
|
||||
|| mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
|
||||
mPendingWakeUpBroadcast = false;
|
||||
mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
|
||||
} else {
|
||||
|
||||
@@ -1217,8 +1217,6 @@ public final class PowerManagerService extends SystemService
|
||||
|
||||
private void setWakefulnessLocked(int wakefulness, int reason) {
|
||||
if (mWakefulness != wakefulness) {
|
||||
finishWakefulnessChangeLocked();
|
||||
|
||||
mWakefulness = wakefulness;
|
||||
mWakefulnessChanging = true;
|
||||
mDirty |= DIRTY_WAKEFULNESS;
|
||||
@@ -1226,10 +1224,14 @@ public final class PowerManagerService extends SystemService
|
||||
}
|
||||
}
|
||||
|
||||
private void finishWakefulnessChangeLocked() {
|
||||
if (mWakefulnessChanging) {
|
||||
mNotifier.onWakefulnessChangeFinished(mWakefulness);
|
||||
private void finishWakefulnessChangeIfNeededLocked() {
|
||||
if (mWakefulnessChanging && mDisplayReady) {
|
||||
if (mWakefulness == WAKEFULNESS_DOZING
|
||||
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
|
||||
return; // wait until dream has enabled dozing
|
||||
}
|
||||
mWakefulnessChanging = false;
|
||||
mNotifier.onWakefulnessChangeFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,9 +1282,7 @@ public final class PowerManagerService extends SystemService
|
||||
updateDreamLocked(dirtyPhase2, displayBecameReady);
|
||||
|
||||
// Phase 4: Send notifications, if needed.
|
||||
if (mDisplayReady) {
|
||||
finishWakefulnessChangeLocked();
|
||||
}
|
||||
finishWakefulnessChangeIfNeededLocked();
|
||||
|
||||
// Phase 5: Update suspend blocker.
|
||||
// Because we might release the last suspend blocker here, we need to make sure
|
||||
|
||||
Reference in New Issue
Block a user