PhoneWindowManager响应电源键
首先按下power键后调用frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的interceptKeyBeforeQueueing方法:
// TODO(b/117479243): handle it in InputPolicy
/** {@inheritDoc} */
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
......
// Handle special keys.
switch (keyCode) {
......
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
......
}
......
}
调用了PhoneWindowManager的interceptPowerKeyDown方法:
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
// Hold a wake lock until the power key is released.
if (!mPowerKeyWakeLock.isHeld()) {
mPowerKeyWakeLock.acquire();
}
......
// If the power key has still not yet been handled, then detect short
// press, long press, or multi press and decide what to do.
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
|| mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted
|| handledByPowerManager;
if (!mPowerKeyHandled) {
if (interactive) {
// When interactive, we're already awake.
// Wait for a long press or for the button to be released to decide what to do.
......
} else {
wakeUpFromPowerKey(event.getDownTime());
......
}
}
}
调用了PhoneWindowManager的wakeUpFromPowerKey方法:
private void wakeUpFromPowerKey(long eventTime) {
wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER");
}
调用了PhoneWindowManager的wakeUp方法:
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
String details) {
......
mPowerManager.wakeUp(wakeTime, reason, details);
......
}
PowerMangerService处理亮屏
调用了frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java的静态内部类BinderService的wakeUp方法:
@Override // Binder call
public void wakeUp(long eventTime, @WakeReason int reason, String details,
String opPackageName) {
......
try {
wakeUpInternal(eventTime, reason, details, uid, opPackageName, uid);
}
......
}
调用了PowerManagerService的wakeUpInternal方法:
private void wakeUpInternal(long eventTime, @WakeReason int reason, String details, int uid,
String opPackageName, int opUid) {
synchronized (mLock) {
if (wakeUpNoUpdateLocked(eventTime, reason, details, uid, opPackageName, opUid)) {
updatePowerStateLocked();
}
}
}
这里首先调用了PowerManagerService的wakeUpNoUpdateLocked方法:
private boolean wakeUpNoUpdateLocked(long eventTime, @WakeReason int reason, String details,
int reasonUid, String opPackageName, int opUid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
}
if (eventTime < mLastSleepTime || getWakefulnessLocked() == WAKEFULNESS_AWAKE
|| mForceSuspendActive || !mSystemReady) {
return false;
}
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0); // private static final String TRACE_SCREEN_ON = "Screen turning on"
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
Slog.i(TAG, "Waking up from "
+ PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ " (uid=" + reasonUid
+ ", reason=" + PowerManager.wakeReasonToString(reason)
+ ", details=" + details
+ ")...");
mLastWakeTime = eventTime;
mLastWakeReason = reason;
setWakefulnessLocked(WAKEFULNESS_AWAKE, reason, eventTime);
mNotifier.onWakeUp(reason, details, reasonUid, opPackageName, opUid);
userActivityNoUpdateLocked(
eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
if (sQuiescent) {
mDirty |= DIRTY_QUIESCENT;
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
这里通过Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0)开始打trace,也就是我们能在systrace中看到的Screen turning on的开始(默认此trace是关的)。
然后调用了PowerManagerService的setWakefulnessLocked方法,传入了WAKEFULNESS_AWAKE:
@VisibleForTesting
void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
if (getWakefulnessLocked() != wakefulness) {
// Under lock, invalidate before set ensures caches won't return stale values.
mInjector.invalidateIsInteractiveCaches();
mWakefulnessRaw = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
// This is only valid while we are in wakefulness dozing. Set to false otherwise.
mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING);
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
}
mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
}
}
调用了frameworks/base/services/core/java/com/android/server/power/Notifier.java的onWakefulnessChangeStarted方法:
/**
* 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(final int wakefulness, int reason, long eventTime) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
+ ", reason=" + reason + ", interactive=" + interactive);
}
// Tell the activity manager about changes in wakefulness, not just interactivity.
// It needs more granularity than other components.
mHandler.post(new Runnable() {
@Override
public void run() {
mActivityManagerInternal.onWakefulnessChanged(wakefulness);
}
});
// 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();
}
// Start input as soon as we start waking up or going to sleep.
mInputManagerInternal.setInteractive(interactive);
mInputMethodManagerInternal.setInteractive(interactive);
// Notify battery stats.
try {
mBatteryStats.noteInteractive(interactive);
} catch (RemoteException ex) { }
FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED,
interactive ? FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON :
FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
// Handle early behaviors.
mInteractive = interactive;
mInteractiveChangeReason = reason;
mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
}
这个方法首先通知AMS状态变为WAKEFULNESS_AWAKE,然后通知InputManager为可交互状态,最后调用了Notifier的handleEarlyInteractiveChange方法:
/**
* 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() {
final int why = translateOnReason(mInteractiveChangeReason);
mPolicy.startedWakingUp(why);
}
});
// 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);
}
});
}
}
}
PhoneWindowManager执行startedWakingUp
调用了frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的startedWakingUp方法:
// Called on the PowerManager's Notifier thread.
@Override
public void startedWakingUp(@OnReason int why) {
EventLogTags.writeScreenToggled(1);
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Started waking up... (why="
+ WindowManagerPolicyConstants.onReasonToString(why) + ")");
}
mDefaultDisplayPolicy.setAwake(true);
// Since goToSleep performs these functions synchronously, we must
// do the same here. We cannot post this work to a handler because
// that might cause it to become reordered with respect to what
// may happen in a future call to goToSleep.
synchronized (mLock) {
updateWakeGestureListenerLp();
updateLockScreenTimeout();
}
mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedWakingUp();
}
}
首先会打印event log:screen_toggled: 1
通知keyguard的onStartedWakingUp
然后调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java的onStartedWakingUp方法:
public void onStartedWakingUp() {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
mKeyguardService.onStartedWakingUp();
}
mKeyguardState.interactiveState = INTERACTIVE_STATE_WAKING;
}
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java的onStartedWakingUp方法:
@Override
public void onStartedWakingUp() {
try {
mService.onStartedWakingUp();
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
通过binder调用了systemui进程中frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java的成员变量mBinder的onStartedWakingUp方法:
@Override // Binder interface
public void onStartedWakingUp() {
Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
checkPermission();
mKeyguardViewMediator.onStartedWakingUp();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.STARTED_WAKING_UP);
Trace.endSection();
}
PowerManagerService更新电源状态
回到PowerManagerService的wakeUpInternal方法中,接下来调用了PowerManagerService的updatePowerStateLocked方法:
/**
* Updates the global power state based on dirty bits recorded in mDirty.
*
* This is the main function that performs power state transitions.
* We centralize them here so that we can recompute the power state completely
* each time something important changes, and ensure that we do it the same
* way each time. The point is to gather all of the transition logic here.
*/
private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {
return;
}
if (!Thread.holdsLock(mLock)) {
Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
try {
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty);
// Phase 1: Update wakefulness.
// Loop because the wake lock and user activity computations are influenced
// by changes in wakefulness.
final long now = mClock.uptimeMillis();
int dirtyPhase2 = 0;
for (;;) {
int dirtyPhase1 = mDirty;
dirtyPhase2 |= dirtyPhase1;
mDirty = 0;
updateWakeLockSummaryLocked(dirtyPhase1);
updateUserActivitySummaryLocked(now, dirtyPhase1);
updateAttentiveStateLocked(now, dirtyPhase1);
if (!updateWakefulnessLocked(dirtyPhase1)) {
break;
}
}
// Phase 2: Lock profiles that became inactive/not kept awake.
updateProfilesLocked(now);
// Phase 3: Update display power state.
final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
// Phase 4: Update dream state (depends on display ready signal).
updateDreamLocked(dirtyPhase2, displayBecameReady);
// Phase 5: Send notifications, if needed.
finishWakefulnessChangeIfNeededLocked();
// Phase 6: Update suspend blocker.
// Because we might release the last suspend blocker here, we need to make sure
// we finished everything else first!
updateSuspendBlockerLocked();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
在Phase 3中调用了PowerManagerService的updateDisplayPowerStateLocked方法:
/**
* Updates the display power state asynchronously.
* When the update is finished, mDisplayReady will be set to true. The display
* controller posts a message to tell us when the actual display power state
* has been updated so we come back here to double-check and finish up.
*
* This function recalculates the display power state each time.
*
* @return True if the display became ready.
*/
private boolean updateDisplayPowerStateLocked(int dirty) {
final boolean oldDisplayReady = mDisplayReady;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
| DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
DIRTY_QUIESCENT)) != 0) {
if ((dirty & DIRTY_QUIESCENT) != 0) {
sQuiescent = false;
}
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
// Determine appropriate screen brightness and auto-brightness adjustments.
final boolean autoBrightness;
final float screenBrightnessOverride;
if (!mBootCompleted) {
// Keep the brightness steady during boot. This requires the
// bootloader brightness and the default brightness to be identical.
autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessSettingDefault;
} else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
} else {
autoBrightness = (mScreenBrightnessModeSetting ==
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
// Update display power request.
mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0
&& !mDrawWakeLockOverrideFromSidekick) {
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
}
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;
}
}
mDisplayPowerRequest.dozeScreenBrightness =
mDozeScreenBrightnessOverrideFromDreamManagerFloat;
} else {
mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
mDisplayPowerRequest.dozeScreenBrightness =
PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
+ ", policy=" + mDisplayPowerRequest.policy
+ ", mWakefulness=" + getWakefulnessLocked()
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", mBootCompleted=" + mBootCompleted
+ ", screenBrightnessOverride=" + screenBrightnessOverride
+ ", useAutoBrightness=" + autoBrightness
+ ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress
+ ", mIsVrModeEnabled= " + mIsVrModeEnabled
+ ", sQuiescent=" + sQuiescent);
}
}
return mDisplayReady && !oldDisplayReady;
}
DisplayManagerService更新电源状态
通过mDisplayManagerInternal.requestPowerState调用了frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java的内部类LocalService的requestPowerState方法:
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mSyncRoot) {
return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity);
}
}
DisplayPowerController更新电源状态
调用了frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java的requestPowerState方法:
/**
* Requests a new power state.
* The controller makes a copy of the provided object and then
* begins adjusting the power state to match what was requested.
*
* @param request The requested power state.
* @param waitForNegativeProximity If true, issues a request to wait for
* negative proximity before turning the screen back on, assuming the screen
* was turned off by the proximity sensor.
* @return True if display is ready, false if there are important changes that must
* be made asynchronously (such as turning the screen on), in which case the caller
* should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
* then try the request again later until the state converges.
*/
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
if (DEBUG) {
Slog.d(TAG, "requestPowerState: "
+ request + ", waitForNegativeProximity=" + waitForNegativeProximity);
}
synchronized (mLock) {
boolean changed = false;
if (waitForNegativeProximity
&& !mPendingWaitForNegativeProximityLocked) {
mPendingWaitForNegativeProximityLocked = true;
changed = true;
}
if (mPendingRequestLocked == null) {
mPendingRequestLocked = new DisplayPowerRequest(request);
changed = true;
} else if (!mPendingRequestLocked.equals(request)) {
mPendingRequestLocked.copyFrom(request);
changed = true;
}
if (changed) {
mDisplayReadyLocked = false;
}
if (changed && !mPendingRequestChangedLocked) {
mPendingRequestChangedLocked = true;
sendUpdatePowerStateLocked();
}
return mDisplayReadyLocked;
}
}
调用了DisplayPowerController的sendUpdatePowerStateLocked方法:
private void sendUpdatePowerStateLocked() {
if (!mPendingUpdatePowerStateLocked) {
mPendingUpdatePowerStateLocked = true;
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
mHandler.sendMessage(msg);
}
}
这个消息在DisplayPowerController的内部类DisplayControllerHandler的handleMessage方法中处理:
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_POWER_STATE:
updatePowerState();
break;
......
}
}
调用了DisplayPowerController的updatePowerState方法:
private void updatePowerState() {
......
animateScreenStateChange(state, performScreenOffTransition);
......
// Notify policy about screen turned on.
if (ready && state != Display.STATE_OFF
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
mWindowManagerPolicy.screenTurnedOn();
}
......
}
调用了DisplayPowerController的animateScreenStateChange方法:
private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
......
if (target == Display.STATE_ON) {
// Want screen on. The contents of the screen may not yet
// be visible if the color fade has not been dismissed because
// its last frame of animation is solid black.
if (!setScreenState(Display.STATE_ON)) {
return; // screen on blocked
}
......
}
......
}
调用了DisplayPowerController的setScreenState方法:
private boolean setScreenState(int state) {
return setScreenState(state, false /*reportOnly*/);
}
private boolean setScreenState(int state, boolean reportOnly) {
final boolean isOff = (state == Display.STATE_OFF);
......
if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
if (mPowerState.getColorFadeLevel() == 0.0f) {
blockScreenOn();
} else {
unblockScreenOn();
}
mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
}
// Return true if the screen isn't blocked.
return mPendingScreenOnUnblocker == null;
}
PhoneWindowManager执行screenTurningOn
调用了frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的screenTurningOn方法:
// Called on the DisplayManager's DisplayPowerController thread.
@Override
public void screenTurningOn(final ScreenOnListener screenOnListener) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
updateScreenOffSleepToken(false);
mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
synchronized (mLock) {
if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
getKeyguardDrawnTimeout());
mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
} else {
if (DEBUG_WAKEUP) Slog.d(TAG,
"null mKeyguardDelegate: setting mKeyguardDrawComplete.");
mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
}
}
}
这里通过Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, “screenTurningOn”, 0 /* cookie */)开始打trace,也就是我们能在systrace中看到的screenTurningOn的开始(默认此trace是开的)。
这里还通过updateScreenOffSleepToken(false)释放了灭屏的SleepToken,详见SleepToken机制。
通知keyguard的onScreenTurningOn
然后调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java的onScreenTurningOn方法:
public void onScreenTurningOn(final DrawnListener drawnListener) {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")");
mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener));
} else {
// try again when we establish a connection
Slog.w(TAG, "onScreenTurningOn(): no keyguard service!");
// This shouldn't happen, but if it does, show the scrim immediately and
// invoke the listener's callback after the service actually connects.
mDrawnListenerWhenConnect = drawnListener;
}
mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
}
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java的onScreenTurningOn方法:
@Override
public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
try {
mService.onScreenTurningOn(callback);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
通过binder调用了systemui进程中frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java的成员变量mBinder的onScreenTurningOn方法:
@Override // Binder interface
public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
checkPermission();
mKeyguardViewMediator.onScreenTurningOn(callback);
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
Trace.endSection();
}
PhoneWindowManger得知keyguard绘制完成
如果systemui绘制好了Keyguard会调用callback回调,这个callback是PhoneWindowManager的screenTurningOn方法中传进来的PhoneWindowManager的mKeyguardDrawnCallback成员变量:
final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {
@Override
public void onDrawn() {
if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");
mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
}
};
mHandler是PhoneWindowManager的内部类PolicyHandler,其handleMessage方法:
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case MSG_KEYGUARD_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
finishKeyguardDrawn();
break;
case MSG_KEYGUARD_DRAWN_TIMEOUT:
Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
finishKeyguardDrawn();
break;
......
}
}
}
调用了PhoneWindowManager的finishKeyguardDrawn方法:
private void finishKeyguardDrawn() {
if (!mDefaultDisplayPolicy.finishKeyguardDrawn()) {
return;
}
synchronized (mLock) {
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
}
}
// ... eventually calls finishWindowsDrawn which will finalize our screen turn on
// as well as enabling the orientation change logic/sensor.
mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
WAITING_FOR_DRAWN_TIMEOUT, INVALID_DISPLAY);
}
WindowManagerService等待所有窗口绘制完
调用了frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java的内部类LocalService的waitForAllWindowsDrawn方法:
@Override
public void waitForAllWindowsDrawn(Runnable callback, long timeout, int displayId) {
final WindowContainer container = displayId == INVALID_DISPLAY
? mRoot : mRoot.getDisplayContent(displayId);
if (container == null) {
// The waiting container doesn't exist, no need to wait to run the callback. Run and
// return;
callback.run();
return;
}
boolean allWindowsDrawn = false;
synchronized (mGlobalLock) {
container.waitForAllWindowsDrawn();
mWindowPlacerLocked.requestTraversal();
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
if (container.mWaitingForDrawn.isEmpty()) {
allWindowsDrawn = true;
} else {
mWaitingForDrawnCallbacks.put(container, callback);
mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
checkDrawnWindowsLocked();
}
}
if (allWindowsDrawn) {
callback.run();
}
}
PhoneWindowManager完成亮屏
最终会调用callback的run方法(即使绘制超时),这个callback是在PhoneWindowManager的finishKeyguardDrawn方法中传入的PhoneWindowManager的成员变量mWindowManagerDrawCallback:
final Runnable mWindowManagerDrawCallback = new Runnable() {
@Override
public void run() {
if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
}
};
mHandler是PhoneWindowManager的内部类PolicyHandler,其handleMessage方法:
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
finishWindowsDrawn();
break;
......
}
}
}
调用了PhoneWindowManager的finishWindowsDrawn方法:
private void finishWindowsDrawn() {
if (!mDefaultDisplayPolicy.finishWindowsDrawn()) {
return;
}
finishScreenTurningOn();
}
调用了PhoneWindowManager的finishScreenTurningOn方法:
private void finishScreenTurningOn() {
// We have just finished drawing screen content. Since the orientation listener
// gets only installed when all windows are drawn, we try to install it again.
mDefaultDisplayRotation.updateOrientationListener();
final ScreenOnListener listener = mDefaultDisplayPolicy.getScreenOnListener();
if (!mDefaultDisplayPolicy.finishScreenTurningOn()) {
return; // Spurious or not ready yet.
}
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
final boolean enableScreen;
final boolean awake = mDefaultDisplayPolicy.isAwake();
synchronized (mLock) {
// Remember the first time we draw the keyguard so we know when we're done with
// the main part of booting and can enable the screen and hide boot messages.
if (!mKeyguardDrawnOnce && awake) {
mKeyguardDrawnOnce = true;
enableScreen = true;
if (mBootMessageNeedsHiding) {
mBootMessageNeedsHiding = false;
hideBootMessages();
}
} else {
enableScreen = false;
}
}
if (listener != null) {
listener.onScreenOn();
}
if (enableScreen) {
try {
mWindowManager.enableScreenIfNeeded();
} catch (RemoteException unhandled) {
}
}
}
这里通过Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, “screenTurningOn”, 0 /* cookie */)结束打trace,也就是我们能在systrace中看到的screenTurningOn的结束。
PhoneWindowManager执行screenTurnedOn
DisplayPowerController的updatePowerState方法后面还会调用frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的screenTurnedOn方法:
// Called on the DisplayManager's DisplayPowerController thread.
@Override
public void screenTurnedOn() {
synchronized (mLock) {
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onScreenTurnedOn();
}
}
reportScreenStateToVrManager(true);
}
通知keyguard的onScreenTurnedOn
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java的onScreenTurnedOn方法:
public void onScreenTurnedOn() {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "onScreenTurnedOn()");
mKeyguardService.onScreenTurnedOn();
}
mKeyguardState.screenState = SCREEN_STATE_ON;
}
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java的onScreenTurnedOn方法:
@Override
public void onScreenTurnedOn() {
try {
mService.onScreenTurnedOn();
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
通过binder调用了systemui进程中frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java的成员变量mBinder的onScreenTurnedOn方法:
@Override // Binder interface
public void onScreenTurnedOn() {
Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
checkPermission();
mKeyguardViewMediator.onScreenTurnedOn();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
Trace.endSection();
}
PhoneWindowManager执行finishedWakingUp
回到PowerManagerService的updatePowerStateLocked方法中,在Phase 5调用了PowerManagerService的finishWakefulnessChangeIfNeededLocked方法:
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (getWakefulnessLocked() == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
} else {
// Doze wakelock acquired (doze started) or device is no longer dozing.
mDozeStartInProgress = false;
}
if (getWakefulnessLocked() == WAKEFULNESS_DOZING
|| getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
logSleepTimeoutRecapturedLocked();
}
if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
final int latencyMs = (int) (mClock.uptimeMillis() - mLastWakeTime);
if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
Slog.w(TAG, "Screen on took " + latencyMs + " ms");
}
}
mWakefulnessChanging = false;
mNotifier.onWakefulnessChangeFinished();
}
}
这里通过Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0)结束打trace,也就是我们能在systrace中看到的Screen turning on的结束。
最后还调用了frameworks/base/services/core/java/com/android/server/power/Notifier.java的onWakefulnessChangeFinished方法:
/**
* Notifies that the device has finished changing wakefulness.
*/
public void onWakefulnessChangeFinished() {
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeFinished");
}
if (mInteractiveChanging) {
mInteractiveChanging = false;
handleLateInteractiveChange();
}
}
调用了Notifier的handleLateInteractiveChange方法:
/**
* 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) {
final int interactiveChangeLatency =
(int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
// Finished waking up...
final int why = translateOnReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_OPEN);
log.setSubtype(why);
log.setLatency(interactiveChangeLatency);
log.addTaggedData(
MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason);
MetricsLogger.action(log);
EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
mPolicy.finishedWakingUp(why);
}
});
} else {
// Finished going to sleep...
......
}
}
}
通过mHandler.post方法切换线程后调用了frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的finishedWakingUp方法:
// Called on the PowerManager's Notifier thread.
@Override
public void finishedWakingUp(@OnReason int why) {
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Finished waking up... (why="
+ WindowManagerPolicyConstants.onReasonToString(why) + ")");
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedWakingUp();
}
if (mDisplayFoldController != null) {
mDisplayFoldController.finishedWakingUp();
}
}
通知keyguard的onFinishedWakingUp
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java的onFinishedWakingUp方法:
public void onFinishedWakingUp() {
if (mKeyguardService != null) {
if (DEBUG) Log.v(TAG, "onFinishedWakingUp()");
mKeyguardService.onFinishedWakingUp();
}
mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
}
调用了frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java的onFinishedWakingUp方法:
@Override
public void onFinishedWakingUp() {
try {
mService.onFinishedWakingUp();
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
通过binder调用了systemui进程中frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java的成员变量mBinder的onFinishedWakingUp方法:
@Override // Binder interface
public void onFinishedWakingUp() {
Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
checkPermission();
mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
Trace.endSection();
}
总结
1 可以和灭屏流程对比来学习。
2 PhoneWindowManager会依次调用startedWakingUp、screenTurningOn、screenTurnedOn、finishedWakingUp方法。
3 亮屏时SleepToken会被释放,但是由于一般在灭屏时Keyguard会显示出来,导致还是不会去resume前台Activity。
亮屏时log示例
05-19 19:42:37.042 1000 1653 2275 I PowerManagerService: Waking up from Asleep (uid=1000, reason=WAKE_REASON_POWER_BUTTON, details=android.policy:POWER)...
05-19 19:42:37.123 1000 1653 1898 I DisplayPowerController: Blocking screen on until initial contents have been drawn.
05-19 19:42:37.123 1000 1653 1898 I WindowManager: Screen turning on... // 要keyguard开始绘制
05-19 19:42:37.137 1000 1653 1653 I WindowManager: Started waking up... (why=ON_BECAUSE_OF_USER)
05-19 19:42:37.210 1000 1653 4074 I WindowManager: mKeyguardDelegate.ShowListener.onDrawn. // keyguard绘制完成,耗时87ms
05-19 19:42:37.293 1000 982 982 D SurfaceFlinger: Setting power mode 2 on display 19260217866401409
05-19 19:42:37.588 1000 982 982 D SurfaceFlinger: Finished setting power mode 2 on display 19260217866401409
05-19 19:42:37.645 1000 1653 1788 D WindowManager: Input focus has changed to Window{8be56b9 mode=0 rootTaskId=1 u0 ScreenOnProximitySensorGuide}
05-19 19:42:37.659 1000 1653 1788 W WindowManager: Setting mKeyguardDrawComplete // 要所有window开始绘制
05-19 19:42:38.013 1000 1653 1788 V WindowManager: Orientation start waiting for draw, mDrawState=DRAW_PENDING in Window{8be56b9 mode=0 rootTaskId=1 u0 ScreenOnProximitySensorGuide}, surfaceController Surface(name=ScreenOnProximitySensorGuide)/@0xfc3ebd6
05-19 19:42:38.687 1000 1653 1790 I WindowManager: All windows ready for display! // 所有window绘制完成,耗时1028ms
05-19 19:42:39.950 1000 1653 1788 W WindowManager: Setting mWindowManagerDrawComplete
05-19 19:42:39.950 1000 1653 1898 I DisplayPowerController: Unblocked screen on after 2827 ms
05-19 19:42:40.032 1000 1653 1898 W PowerManagerService: Screen on took 3112 ms
05-19 19:42:40.043 1000 1653 1653 I WindowManager: Finished waking up... (why=ON_BECAUSE_OF_USER)
05-19 19:42:40.071 1000 1653 1788 D WindowManager: Input focus has changed to Window{ed0343b mode=0 rootTaskId=1 u0 NotificationShade}