PhoneWindowManager响应电源键

首先按下power键后调用frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java的interceptKeyBeforeQueueing方法:

    // TODO(b/117479243): handle it in InputPolicy/** {@inheritDoc} */@Overridepublic 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 shortcutcancelPendingAccessibilityShortcutAction();result &= ~ACTION_PASS_TO_USER;isWakeKey = false; // wake-up will be handled separatelyif (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 callpublic 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:

    @VisibleForTestingvoid 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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.@Overridepublic 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方法:

    @Overridepublic 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 interfacepublic 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方法:

        @Overridepublic 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方法中处理:

        @Overridepublic 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.@Overridepublic 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 connectionSlog.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方法:

    @Overridepublic 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 interfacepublic 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() {@Overridepublic 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 {@Overridepublic 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方法:

        @Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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.@Overridepublic 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方法:

    @Overridepublic 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 interfacepublic 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() {@Overridepublic 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.@Overridepublic 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方法:

    @Overridepublic 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 interfacepublic 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}

亮屏流程 - 安卓R相关推荐

  1. 灭屏流程 - 安卓R

    PhoneWindowManager响应电源键 首先按下power键后调用frameworks/base/services/core/java/com/android/server/policy/Ph ...

  2. 截屏流程 - 安卓R

    截屏类型有三种,分别是全屏截屏.区域截屏和使用提供的图片作为截屏,定义在frameworks/base/core/java/android/view/WindowManager.java中: /*** ...

  3. 录屏流程 - 安卓R

    根据安卓实现录屏app可知,安卓录屏时要创建一个VirtualDisplay.本文介绍安卓录屏的底层原理. 从frameworks/base/media/java/android/media/proj ...

  4. 安卓手机来电亮屏流程分析

    来电亮屏流程分析 本文档是针对手机来电时候自主点亮屏幕这一流程的分析,很自然的就将其分为2个阶段,第一个是来电,第二个是点亮屏幕. 来电的流程: 来电消息是从RIL层接收到的,然后才开始传递上来. A ...

  5. Android插拔usb亮屏流程

    遇到一个问题,插拔usb,手机不亮屏.先来分析下,插拔usb亮屏流程. 关键流程 updatePowerStateLocked--->updateIsPoweredLockedprivate v ...

  6. (原创)Android6.0亮屏流程分析

    1.概述 Android的亮屏流程从android系统结构层次来分可以分为三个流程,App应用唤醒源:Framework层Power结合Display,Light服务做亮屏绘制准备工作:底层驱动点亮背 ...

  7. Android 亮屏流程分析

    https://blog.csdn.net/FightFightFight/article/details/79808100 相关文章: [Android Framework] 8.1 PowerMa ...

  8. Android 8.1 PowerManagerService分析(四)——亮屏流程分析

    欢迎大家关注我的掘金帐号 我会在那里定期更新最新版本的Android Framework源码分析! 相关文章: [Android Framework] 8.1 PowerManagerService分 ...

  9. Android手机亮屏流程分析

    极力推荐Android 开发大总结文章:欢迎收藏程序员Android 力荐 ,Android 开发者需要的必备技能 注:文章转于网络,点击查看原文 PowerManagerService 之前系列文章 ...

最新文章

  1. OpenCV的支持向量机SVM的程序
  2. Inno Setup使用教程大全
  3. springmvc拦截器配置
  4. 淘宝获取收货地址列表的 API
  5. 如何下载小程序图片?
  6. 单片机的多路温度采集系统
  7. 计算机好多个页面,哪些电脑分屏软件好用?好用电脑分屏软件推荐
  8. 减法公式运算法则_加减法运算法则
  9. 年少成名的我并没有放弃自己,谁敢说她\他文章比我写的好?!,不服来战!
  10. 使用 Wowza IDE 开发第一个 Wowza 服务器扩展应用 -- 监控直播频道
  11. 2021-05-18
  12. MongoDB系列六(聚合).
  13. 【问题解决】springboot启动后一小会就自动停止,提示Process finished with exit code 0
  14. java获取百度实时天气(无限制)
  15. C++ 语法 const限定符
  16. 穷人如何使用测试驱动开发进行重构
  17. [求助] 不显示删除回复显示所有回复显示星级回复显示得分回复 操作系统Swap分区2G,Weblogic却还偶尔报swap分区不够的异常,导致生产偶尔宕机...
  18. Mac 移动硬盘无法装载
  19. Unet——pytorch
  20. 为什么事件的最早发生时间是源点到顶点的最长路径长度?(关键路径详解)

热门文章

  1. 国内虚拟主机与香港云主机的优劣势
  2. Line推出新语音群聊功能 最多支持200人
  3. 淘宝/天猫平台API 接口及API文档
  4. OpenCV开发笔记(六十七):红胖子8分钟带你深入了解特征点暴力匹配(图文并茂+浅显易懂+程序源码)
  5. P9:最大池化的使用
  6. 全球100位人工智能名人和2500名资深AI人士,将聚首深圳
  7. SVN拉取、提交文件
  8. 【征集反馈】工作中让你印象最深刻、最想吐槽的一件事是什么?
  9. HashMap源码探究
  10. 深入分析ConcurrentHashMap的源码设计(中)-hash冲突