亮屏流程 - 安卓R

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}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSSxCCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值