上一篇介绍了Android 电源键事件流程分析,其中分析了,在按电源键,长按的时候,弹出系统菜单,以及点击其中的关机按键,都执行了哪些操作。这一篇,作为上一篇的补充,主要分析一下,Android按键亮屏、息屏流程。
唤醒
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false;
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
if (!mPowerKeyWakeLock.isHeld()) {
mPowerKeyWakeLock.acquire();
}
if (mPowerKeyPressCounter != 0) {
mHandler.removeMessages(MSG_POWER_DELAYED_PRESS);
}
mWindowManagerFuncs.onPowerKeyDown(interactive);
if (interactive && !mScreenshotChordPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mScreenshotChordPowerKeyTriggered = true;
mScreenshotChordPowerKeyTime = event.getDownTime();
interceptScreenshotChord();
interceptRingerToggleChord();
}
TelecomManager telecomManager = getTelecommService();
boolean hungUp = false;
if (telecomManager != null) {
if (telecomManager.isRinging()) {
telecomManager.silenceRinger();
} else if ((mIncallPowerBehavior
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
&& telecomManager.isInCall() && interactive) {
hungUp = telecomManager.endCall();
}
}
GestureLauncherService gestureService = LocalServices.getService(
GestureLauncherService.class);
boolean gesturedServiceIntercepted = false;
if (gestureService != null) {
gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive,
mTmpBoolean);
if (mTmpBoolean.value && mRequestedOrGoingToSleep) {
mCameraGestureTriggeredDuringGoingToSleep = true;
}
}
sendSystemKeyToStatusBarAsync(event.getKeyCode());
schedulePossibleVeryLongPressReboot();
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
|| mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
if (!mPowerKeyHandled) {
if (interactive) {
} else {
wakeUpFromPowerKey(event.getDownTime());
}
}
}
可以看到,在按下电源键的时候,如果判断,当前是息屏状态,则执行wakeUpFromPowerKey()方法,
private void wakeUpFromPowerKey(long eventTime) {
wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER");
}
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
String details) {
final boolean theaterModeEnabled = isTheaterModeEnabled();
if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
}
if (theaterModeEnabled) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0);
}
mPowerManager.wakeUp(wakeTime, reason, details);
final HdmiControl hdmiControl = getHdmiControl();
if (hdmiControl != null) {
hdmiControl.turnOnTv();
}
return true;
}
往下继续追
public void wakeUp(long time, @WakeReason int reason, String details) {
try {
mService.wakeUp(time, reason, details, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
通过跨进程通信,我们知道真正的操作是在PowerManagerService类里的wakeUp()方法
@Override
public void wakeUp(long eventTime, @WakeReason int reason, String details,
String opPackageName) {
if (eventTime > mClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
wakeUpInternal(eventTime, reason, details, uid, opPackageName, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
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();
}
}
}
我们首先分析wakeUpNoUpdateLocked()方法,如果它返回true,则执行updatePowerStateLocked方法
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);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
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;
}
先来看看setWakefulnessLocked方法
void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
if (getWakefulnessLocked() != wakefulness) {
mInjector.invalidateIsInteractiveCaches();
mWakefulnessRaw = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING);
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
}
mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
}
}
继续往下追,查看Notifier类里的onWakefulnessChangeStarted方法
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);
}
mHandler.post(new Runnable() {
@Override
public void run() {
mActivityManagerInternal.onWakefulnessChanged(wakefulness);
}
});
if (mInteractive != interactive) {
if (mInteractiveChanging) {
handleLateInteractiveChange();
}
mInputManagerInternal.setInteractive(interactive);
mInputMethodManagerInternal.setInteractive(interactive);
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);
mInteractive = interactive;
mInteractiveChangeReason = reason;
mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
}
private void handleEarlyInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
mHandler.post(new Runnable() {
@Override
public void run() {
final int why = translateOnReason(mInteractiveChangeReason);
mPolicy.startedWakingUp(why);
}
});
mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
updatePendingBroadcastLocked();
} else {
final int why = translateOffReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.startedGoingToSleep(why);
}
});
}
}
}
private void updatePendingBroadcastLocked() {
if (!mBroadcastInProgress
&& mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
&& (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mPendingInteractiveState != mBroadcastedInteractiveState)) {
mBroadcastInProgress = true;
mSuspendBlocker.acquire();
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BROADCAST:
sendNextBroadcast();
break;
}
}
private void sendWakeUpBroadcast() {
if (DEBUG) {
Slog.d(TAG, "Sending wake up broadcast.");
}
if (mActivityManagerInternal.isSystemReady()) {
mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
mWakeUpBroadcastDone, mHandler, 0, null, null);
} else {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
sendNextBroadcast();
}
}
再来分析updatePowerStateLocked方法,此方法目的是更新PackageManagerService全局状态
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 {
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty);
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;
}
}
updateProfilesLocked(now);
final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
updateDreamLocked(dirtyPhase2, displayBecameReady);
finishWakefulnessChangeIfNeededLocked();
updateSuspendBlockerLocked();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
再来分析 finishWakefulnessChangeIfNeededLocked() 方法,看看亮屏收尾工作都做了那些
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (getWakefulnessLocked() == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return;
} else {
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();
}
}
Notifier类里的onWakefulnessChangeFinished
public void onWakefulnessChangeFinished() {
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeFinished");
}
if (mInteractiveChanging) {
mInteractiveChanging = false;
handleLateInteractiveChange();
}
}
private void handleLateInteractiveChange() {
synchronized (mLock) {
final int interactiveChangeLatency =
(int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
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 {
}
}
}
息屏
同唤醒操作类似,按键首先会走执行
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false;
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
final boolean handled = canceled || mPowerKeyHandled;
mScreenshotChordPowerKeyTriggered = false;
cancelPendingScreenshotChordAction();
cancelPendingPowerKeyAction();
if (!handled) {
if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) == 0) {
mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);
}
mPowerKeyPressCounter += 1;
final int maxCount = getMaxMultiPressPowerCount();
final long eventTime = event.getDownTime();
if (mPowerKeyPressCounter < maxCount) {
Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
return;
}
powerPress(eventTime, interactive, mPowerKeyPressCounter);
}
finishPowerKeyPress();
}
继续往下追
private void powerPress(long eventTime, boolean interactive, int count) {
if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
}
Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
+ " count=" + count + " beganFromNonInteractive=" + mBeganFromNonInteractive +
" mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
if (count == 2) {
powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
} else if (count == 3) {
powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
} else if (interactive && !mBeganFromNonInteractive) {
switch (mShortPressOnPowerBehavior) {
case SHORT_PRESS_POWER_NOTHING:
break;
case SHORT_PRESS_POWER_GO_TO_SLEEP:
goToSleepFromPowerButton(eventTime, 0);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
goToSleepFromPowerButton(eventTime, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
break;
}
}
}
}
查看mShortPressOnPowerBehavior赋值
mShortPressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shortPressOnPowerBehavior);
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
2 - Really go to sleep (don't doze)
3 - Really go to sleep and go home (don't doze)
4 - Go to home
5 - Dismiss IME if shown. Otherwise go to home
-->
<integer name="config_shortPressOnPowerBehavior">1</integer>
执行case SHORT_PRESS_POWER_GO_TO_SLEEP,即goToSleepFromPowerButton()方法
private boolean goToSleepFromPowerButton(long eventTime, int flags) {
final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup();
if (lastWakeUp != null && lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE) {
final int gestureDelayMillis = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE,
POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS);
final long now = SystemClock.uptimeMillis();
if (mPowerButtonSuppressionDelayMillis > 0
&& (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) {
Slog.i(TAG, "Sleep from power button suppressed. Time since gesture: "
+ (now - lastWakeUp.wakeTime) + "ms");
return false;
}
}
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
return true;
}
private void goToSleep(long eventTime, int reason, int flags) {
mRequestedOrGoingToSleep = true;
mPowerManager.goToSleep(eventTime, reason, flags);
}
继续往下追PowerManagerService 的goToSleep()
@Override
public void goToSleep(long eventTime, int reason, int flags) {
if (eventTime > mClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
goToSleepInternal(eventTime, reason, flags, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
synchronized (mLock) {
if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
updatePowerStateLocked();
}
}
}
@SuppressWarnings("deprecation")
private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
try {
reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
+ " (uid " + uid + ")...");
mLastSleepTime = eventTime;
mLastSleepReason = reason;
mSandmanSummoned = true;
mDozeStartInProgress = true;
setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
int numWakeLocksCleared = 0;
final int numWakeLocks = mWakeLocks.size();
for (int i = 0; i < numWakeLocks; i++) {
final WakeLock wakeLock = mWakeLocks.get(i);
switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
case PowerManager.FULL_WAKE_LOCK:
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
case PowerManager.SCREEN_DIM_WAKE_LOCK:
numWakeLocksCleared += 1;
break;
}
}
EventLogTags.writePowerSleepRequested(numWakeLocksCleared);
if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
reallyGoToSleepNoUpdateLocked(eventTime, uid);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
同wakeup一样,会走到Notifer类的onWakefulnessChangeStarted()方法
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);
}
mHandler.post(new Runnable() {
@Override
public void run() {
mActivityManagerInternal.onWakefulnessChanged(wakefulness);
}
});
if (mInteractive != interactive) {
if (mInteractiveChanging) {
handleLateInteractiveChange();
}
mInputManagerInternal.setInteractive(interactive);
mInputMethodManagerInternal.setInteractive(interactive);
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);
mInteractive = interactive;
mInteractiveChangeReason = reason;
mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
}
继续看handleErarlyInteractiveChange()方法
private void handleEarlyInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
mHandler.post(new Runnable() {
@Override
public void run() {
final int why = translateOnReason(mInteractiveChangeReason);
mPolicy.startedWakingUp(why);
}
});
mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
updatePendingBroadcastLocked();
} else {
final int why = translateOffReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.startedGoingToSleep(why);
}
});
}
}
}
我们现在在返回去看updatePowerStateLocked方法,对,没错,唤醒的时候,也会走到这里
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 {
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty);
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;
}
}
updateProfilesLocked(now);
final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
updateDreamLocked(dirtyPhase2, displayBecameReady);
finishWakefulnessChangeIfNeededLocked();
updateSuspendBlockerLocked();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
当息屏执行结束,我们分析finishWakefulnessChangeIfNeededLocked方法
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (getWakefulnessLocked() == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return;
} else {
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();
}
}
我们继续来分析Notifier类的onWakefulnessChangeFinished方法
public void onWakefulnessChangeFinished() {
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeFinished");
}
if (mInteractiveChanging) {
mInteractiveChanging = false;
handleLateInteractiveChange();
}
}
private void handleLateInteractiveChange() {
synchronized (mLock) {
final int interactiveChangeLatency =
(int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
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 {
if (mUserActivityPending) {
mUserActivityPending = false;
mHandler.removeMessages(MSG_USER_ACTIVITY);
}
final int why = translateOffReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_CLOSE);
log.setSubtype(why);
log.setLatency(interactiveChangeLatency);
log.addTaggedData(
MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason);
MetricsLogger.action(log);
EventLogTags.writePowerScreenState(0, why, 0, 0, interactiveChangeLatency);
mPolicy.finishedGoingToSleep(why);
}
});
mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
mPendingGoToSleepBroadcast = true;
updatePendingBroadcastLocked();
}
}
}
好了,从我们分析源码得知 唤醒的时候,唤醒广播是在handleEarlyInteractiveChange方法,就是在通知PhoneWindowManager 去执行startedWakingUp方法,紧跟着就执行updatePendingBroadcastLocked方法,去发送唤醒广播 而在息屏的时候,在handleEarlyInteractiveChange里,我们只是通知PhoneWindowManager去执行startedGoingToSleep方法,最后在updatePowerStateLocked==>finishWakefulnessChangeIfNeededLocked==>Notifier==>onWakefulnessChangeFinished==》handleLateInteractiveChange方法里,在通知PhoneWindowManager执行finishedGoingToSleep()之后,才执行updatePendingBroadcastLocked()方法去发送息屏广播(Intent.ACTION_SCREEN_OFF),这个时机需要特别注意一下。
|