android 亮屏流程分析--随记

目录

一. 源码分析:

二. 简单整理流程:

三.  DisplayPowerController处理

四. 阻塞亮屏

五. 从按下power键到亮屏的流程小结: 

六.log 验证:


一. 源码分析:

1.按键上报流程.

 (1).从native 层上报事件:

 frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

//打开log 调试开关
#define LOG_NDEBUG 0
static struct {
...
 jmethodID interceptKeyBeforeQueueing;
...
}
int register_android_server_InputManager(JNIEnv* env) {
....
    //动态JNI注册
    GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
            "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
....
}
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
        uint32_t& policyFlags) {
    ATRACE_CALL();
    // Policy:
    // - Ignore untrusted events and pass them along.
    // - Ask the window manager what to do with normal events and trusted injected events.
    // - For normal events wake and brighten the screen if currently off or dim.
    bool interactive = mInteractive.load();
    if (interactive) {
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
        nsecs_t when = keyEvent->getEventTime();
        JNIEnv* env = jniEnv();
        jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
        jint wmActions;
        if (keyEventObj) {
            //通过反射的方法调用java层
            wmActions = env->CallIntMethod(mServiceObj,
                    gServiceClassInfo.interceptKeyBeforeQueueing,
                    keyEventObj, policyFlags);
            if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                wmActions = 0;
            }
            android_view_KeyEvent_recycle(env, keyEventObj);
            env->DeleteLocalRef(keyEventObj);
        } else {
            ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
            wmActions = 0;
        }

        handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
    } else {
        if (interactive) {
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        }
    }
}

(2). 通过JNI 调用的java 层InputManagerService.java,对应的路径:

android/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

    // Native callback.
    //C++ 层调用对应的java 层函数.
    private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
        return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);
    }

 3. mWindowManagerCallbacks对象的java类是:InputManagerCallback.java,对应的路径:

android/frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java

    /**
     * Provides an opportunity for the window manager policy to intercept early key
     * processing as soon as the key has been read from the device.
     */
    @Override
    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
        return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
    }

4. mService.mPolicy 对应的java类是PhoneWindowManager.java, 对应的路径:

android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java


    // TODO(b/117479243): handle it in InputPolicy
    /** {@inheritDoc} */
    @Override
    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
        //获取keycode
        final int keyCode = event.getKeyCode();
        //是否down事件
        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
        //是否是唤醒键
        boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
                || event.isWakeKey();
        
        if (!mSystemBooted) {
            // If we have not yet booted, don't let key events do anything.
            // Exception: Wake and power key events are forwarded to PowerManager to allow it to
            // wake from quiescent mode during boot.
            //未启动完成,直接拦截.顺便处理特殊的按键
            if (down && (keyCode == KeyEvent.KEYCODE_POWER
                    || keyCode == KeyEvent.KEYCODE_TV_POWER)) {
                //若是power键,则唤醒
                wakeUpFromPowerKey(event.getDownTime());
            } else if (down && (isWakeKey || keyCode == KeyEvent.KEYCODE_WAKEUP)
                    && isWakeKeyWhenScreenOff(keyCode)) {
                wakeUpFromWakeKey(event);
            }
            return 0;
        }
        //是否存在FLAG_INTERACTIVE flag
        final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
        //event是否被cancel.
        final boolean canceled = event.isCanceled();
  
        final int displayId = event.getDisplayId();
        //是否存在FLAG_INJECTED flag
        final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
        //是否显示锁屏
        final boolean keyguardActive = (mKeyguardDelegate != null
                && (interactive ? isKeyguardShowingAndNotOccluded() :
                mKeyguardDelegate.isShowing()));

        
         if (DEBUG_INPUT) {
            // If screen is off then we treat the case where the keyguard is open but hidden
            // the same as if it were open and in front.
            // This will prevent any keys other than the power button from waking the screen
            // when the keyguard is hidden by another activity.
            Log.d(TAG, "interceptKeyTq keycode=" + keyCode
                    + " interactive=" + interactive + " keyguardActive=" + keyguardActive
                    + " policyFlags=" + Integer.toHexString(policyFlags));
        }

        // Basic policy based on interactive state.
        int result;
        if (interactive || (isInjected && !isWakeKey)) {
            // When the device is interactive or the key is injected pass the
            // key to the application.
            result = ACTION_PASS_TO_USER;
            isWakeKey = false;

            if (interactive) {
                // If the screen is awake, but the button pressed was the one that woke the device
                // then don't pass it to the application
                if (keyCode == mPendingWakeKey && !down) {
                    result = 0;
                }
                // Reset the pending key
                mPendingWakeKey = PENDING_KEY_NULL;
            }
        } else if (shouldDispatchInputWhenNonInteractive(displayId, keyCode)) {
            // If we're currently dozing with the screen on and the keyguard showing, pass the key
            // to the application but preserve its wake key status to make sure we still move
            // from dozing to fully interactive if we would normally go from off to fully
            // interactive.
            result = ACTION_PASS_TO_USER;
            // Since we're dispatching the input, reset the pending key
            mPendingWakeKey = PENDING_KEY_NULL;
        } else {
            // When the screen is off and the key is not injected, determine whether
            // to wake the device but don't pass the key to the application.
            result = 0;
            if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) {
                isWakeKey = false;
            }
            // Cache the wake key on down event so we can also avoid sending the up event to the app
            if (isWakeKey && down) {
                mPendingWakeKey = keyCode;
            }
        }

        // If the key would be handled globally, just return the result, don't worry about special
        // key processing.
        if (isValidGlobalKey(keyCode)
                && mGlobalKeyManager.shouldHandleGlobalKey(keyCode)) {
            // Dispatch if global key defined dispatchWhenNonInteractive.
            if (!interactive && isWakeKey && down
                    && mGlobalKeyManager.shouldDispatchFromNonInteractive(keyCode)) {
                mGlobalKeyManager.setBeganFromNonInteractive();
                result = ACTION_PASS_TO_USER;
                // Since we're dispatching the input, reset the pending key
                mPendingWakeKey = PENDING_KEY_NULL;
            }

            if (isWakeKey) {
                wakeUpFromWakeKey(event);
            }
            return result;
        }

        // Alternate TV power to power key for Android TV device.
        final HdmiControlManager hdmiControlManager = getHdmiControlManager();
        if (keyCode == KeyEvent.KEYCODE_TV_POWER && mHasFeatureLeanback
                && (hdmiControlManager == null || !hdmiControlManager.shouldHandleTvPowerKey())) {
            event = KeyEvent.obtain(
                    event.getDownTime(), event.getEventTime(),
                    event.getAction(), KeyEvent.KEYCODE_POWER,
                    event.getRepeatCount(), event.getMetaState(),
                    event.getDeviceId(), event.getScanCode(),
                    event.getFlags(), event.getSource(), event.getDisplayId(), null);
            return interceptKeyBeforeQueueing(event, policyFlags);
        }

        // This could prevent some wrong state in multi-displays environment,
        // the default display may turned off but interactive is true.
        final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
        final boolean interactiveAndOn = interactive && isDefaultDisplayOn;

        if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
             //处理手势,譬如:双击power启动camera等等
             handleKeyGesture(event, interactiveAndOn);
        }

        // Enable haptics if down and virtual key without multiple repetitions. If this is a hard
        // virtual key such as a navigation bar button, only vibrate if flag is enabled.
        final boolean isNavBarVirtKey = ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0);
        boolean useHapticFeedback = down
                && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
                && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
                && event.getRepeatCount() == 0;


        /// M: Add more log at WMS
        if (mWindowManagerDebugger.WMS_DEBUG_ENG || mWindowManagerDebugger.WMS_DEBUG_USER_DEBUG) {
            mWindowManagerDebugger.debugInterceptKeyBeforeQueueing(TAG, keyCode, interactive,
                    keyguardActive, policyFlags, down, canceled, isWakeKey,
                    result, useHapticFeedback, isInjected);
        }

        // Handle special keys.
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK: {
                if (down) {
                    mBackKeyHandled = false;
                } else {
                    if (!hasLongPressOnBackBehavior()) {
                        mBackKeyHandled |= backKeyPress();
                    }
                    // Don't pass back press to app if we've already handled it via long press
                    if (mBackKeyHandled) {
                        result &= ~ACTION_PASS_TO_USER;
                    }
                }
                break;
            }

            case KeyEvent.KEYCODE_VOLUME_DOWN:
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
                if (down) {
                    sendSystemKeyToStatusBarAsync(event.getKeyCode());

                    NotificationManager nm = getNotificationService();
                    if (nm != null && !mHandleVolumeKeysInWM) {
                        nm.silenceNotificationSound();
                    }

                    TelecomManager telecomManager = getTelecommService();
                    if (telecomManager != null && !mHandleVolumeKeysInWM) {
                        // When {@link #mHandleVolumeKeysInWM} is set, volume key events
                        // should be dispatched to WM.
                        if (telecomManager.isRinging()) {
                            // If an incoming call is ringing, either VOLUME key means
                            // "silence ringer".  We handle these keys here, rather than
                            // in the InCallScreen, to make sure we'll respond to them
                            // even if the InCallScreen hasn't come to the foreground yet.
                            // Look for the DOWN event here, to agree with the "fallback"
                            // behavior in the InCallScreen.
                            Log.i(TAG, "interceptKeyBeforeQueueing:"
                                  + " VOLUME key-down while ringing: Silence ringer!");

                            // Silence the ringer.  (It's safe to call this
                            // even if the ringer has already been silenced.)
                            telecomManager.silenceRinger();

                            // And *don't* pass this key thru to the current activity
                            // (which is probably the InCallScreen.)
                            result &= ~ACTION_PASS_TO_USER;
                            break;
                        }
                    }
                    int audioMode = AudioManager.MODE_NORMAL;
                    try {
                        audioMode = getAudioService().getMode();
                    } catch (Exception e) {
                        Log.e(TAG, "Error getting AudioService in interceptKeyBeforeQueueing.", e);
                    }
                    boolean isInCall = (telecomManager != null && telecomManager.isInCall()) ||
                            audioMode == AudioManager.MODE_IN_COMMUNICATION;
                    if (isInCall && (result & ACTION_PASS_TO_USER) == 0) {
                        // If we are in call but we decided not to pass the key to
                        // the application, just pass it to the session service.
                        MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
                                event, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
                        break;
                    }
                }
                if (mUseTvRouting || mHandleVolumeKeysInWM) {
                    // Defer special key handlings to
                    // {@link interceptKeyBeforeDispatching()}.
                    result |= ACTION_PASS_TO_USER;
                } else if ((result & ACTION_PASS_TO_USER) == 0) {
                    // If we aren't passing to the user and no one else
                    // handled it send it to the session manager to
                    // figure out.
                    MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
                            event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
                }
                break;
            }

            case KeyEvent.KEYCODE_ENDCALL: {
                result &= ~ACTION_PASS_TO_USER;
                if (down) {
                    TelecomManager telecomManager = getTelecommService();
                    boolean hungUp = false;
                    if (telecomManager != null) {
                        hungUp = telecomManager.endCall();
                    }
                    if (interactive && !hungUp) {
                        mEndCallKeyHandled = false;
                        mHandler.postDelayed(mEndCallLongPress,
                                ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
                    } else {
                        mEndCallKeyHandled = true;
                    }
                } else {
                    if (!mEndCallKeyHandled) {
                        mHandler.removeCallbacks(mEndCallLongPress);
                        if (!canceled) {
                            if ((mEndcallBehavior
                                    & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
                                if (goHome()) {
                                    break;
                                }
                            }
                            if ((mEndcallBehavior
                                    & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
                                sleepDefaultDisplay(event.getEventTime(),
                                        PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                                isWakeKey = false;
                            }
                        }
                    }
                }
                break;
            }

            case KeyEvent.KEYCODE_TV_POWER: {
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false; // wake-up will be handled separately
                if (down && hdmiControlManager != null) {
                    hdmiControlManager.toggleAndFollowTvPower();
                }
                break;
            }

            case KeyEvent.KEYCODE_POWER: {
                //电源键日志记录
                EventLogTags.writeInterceptPower(
                        KeyEvent.actionToString(event.getAction()),
                        mPowerKeyHandled ? 1 : 0,
                        mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
                // Any activity on the power button stops the accessibility shortcut
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false; // wake-up will be handled separately
                if (down) {
                    //拦截power键按下
                    interceptPowerKeyDown(event, interactiveAndOn);
                } else {
                     //拦截power键按下
                    interceptPowerKeyUp(event, canceled);
                }
                break;
            }

            case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
                // fall through
            case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP:
                // fall through
            case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
                // fall through
            case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: {
                result &= ~ACTION_PASS_TO_USER;
                interceptSystemNavigationKey(event);
                break;
            }

            case KeyEvent.KEYCODE_SLEEP: {
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false;
                if (!mPowerManager.isInteractive()) {
                    useHapticFeedback = false; // suppress feedback if already non-interactive
                }
                if (down) {
                    sleepPress();
                } else {
                    sleepRelease(event.getEventTime());
                }
                break;
            }

            case KeyEvent.KEYCODE_SOFT_SLEEP: {
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false;
                if (!down) {
                    mPowerManagerInternal.setUserInactiveOverrideFromWindowManager();
                }
                break;
            }

            case KeyEvent.KEYCODE_WAKEUP: {
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = true;
                break;
            }

            case KeyEvent.KEYCODE_MEDIA_PLAY:
            case KeyEvent.KEYCODE_MEDIA_PAUSE:
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
            case KeyEvent.KEYCODE_HEADSETHOOK:
            case KeyEvent.KEYCODE_MUTE:
            case KeyEvent.KEYCODE_MEDIA_STOP:
            case KeyEvent.KEYCODE_MEDIA_NEXT:
            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
            case KeyEvent.KEYCODE_MEDIA_REWIND:
            case KeyEvent.KEYCODE_MEDIA_RECORD:
            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
                if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) {
                    // If the global session is active pass all media keys to it
                    // instead of the active window.
                    result &= ~ACTION_PASS_TO_USER;
                }
                if ((result & ACTION_PASS_TO_USER) == 0) {
                    // Only do this if we would otherwise not pass it to the user. In that
                    // case, the PhoneWindow class will do the same thing, except it will
                    // only do it if the showing app doesn't process the key on its own.
                    // Note that we need to make a copy of the key event here because the
                    // original key event will be recycled when we return.
                    mBroadcastWakeLock.acquire();
                    Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK,
                            new KeyEvent(event));
                    msg.setAsynchronous(true);
                    msg.sendToTarget();
                }
                break;
            }

            case KeyEvent.KEYCODE_CALL: {
                if (down) {
                    TelecomManager telecomManager = getTelecommService();
                    if (telecomManager != null) {
                        if (telecomManager.isRinging()) {
                            Log.i(TAG, "interceptKeyBeforeQueueing:"
                                  + " CALL key-down while ringing: Answer the call!");
                            telecomManager.acceptRingingCall();

                            // And *don't* pass this key thru to the current activity
                            // (which is presumably the InCallScreen.)
                            result &= ~ACTION_PASS_TO_USER;
                        }
                    }
                }
                break;
            }
            case KeyEvent.KEYCODE_ASSIST: {
                //Tinno:add by qipeng.wang for task:VFJAAE-82 begin
                if (TinnoFeature.FEATURE_HMD_FW_INTERGRATED) {
                    boolean notprovision = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.DEVICE_PROVISIONED,0) == 0;
                    boolean assistGestureDisabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ASSIST_GESTURE_ENABLED, 1) == 0;
                    if (notprovision || assistGestureDisabled){
                        break;
                    }

                    if (down) {
                        cancelPossibleAssistInKeyguard();
                        schedulePossibleAssistInKeyguard(keyguardActive);
                     }else{
                        cancelPossibleAssistInKeyguard();
                    }
                }else{
                    final boolean longPressed = event.getRepeatCount() > 0;
                    if (down && !longPressed) {
                        Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(),
                                0 /* unused */, event.getEventTime() /* eventTime */);
                        msg.setAsynchronous(true);
                        msg.sendToTarget();
                    }
                }
                //Tinno:add by qipeng.wang for task:VFJAAE-82 end
                result &= ~ACTION_PASS_TO_USER;
                break;
            }
            case KeyEvent.KEYCODE_VOICE_ASSIST: {
                if (!down) {
                    mBroadcastWakeLock.acquire();
                    Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK);
                    msg.setAsynchronous(true);
                    msg.sendToTarget();
                }
                result &= ~ACTION_PASS_TO_USER;
                break;
            }
            case KeyEvent.KEYCODE_WINDOW: {
                if (mShortPressOnWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) {
                    if (mPictureInPictureVisible) {
                        // Consumes the key only if picture-in-picture is visible to show
                        // picture-in-picture control menu. This gives a chance to the foreground
                        // activity to customize PIP key behavior.
                        if (!down) {
                            showPictureInPictureMenu(event);
                        }
                        result &= ~ACTION_PASS_TO_USER;
                    }
                }
                break;
            }
        }

        // Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
        if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_Z: {
                    if (down && event.isCtrlPressed() && event.isAltPressed()) {
                        mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
                        result &= ~ACTION_PASS_TO_USER;
                    }
                    break;
                }
            }
        }

        if (useHapticFeedback) {
            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
                    "Virtual Key - Press");
        }

        if (isWakeKey) {
            wakeUpFromWakeKey(event);
        }

        if ((result & ACTION_PASS_TO_USER) != 0) {
            // If the key event is targeted to a specific display, then the user is interacting with
            // that display. Therefore, give focus to the display that the user is interacting with.
            if (!mPerDisplayFocusEnabled
                    && displayId != INVALID_DISPLAY && displayId != mTopFocusedDisplayId) {
                // An event is targeting a non-focused display. Move the display to top so that
                // it can become the focused display to interact with the user.
                // This should be done asynchronously, once the focus logic is fully moved to input
                // from windowmanager. Currently, we need to ensure the setInputWindows completes,
                // which would force the focus event to be queued before the current key event.
                // TODO(b/70668286): post call to 'moveDisplayToTop' to mHandler instead
                Log.i(TAG, "Moving non-focused display " + displayId + " to top "
                        + "because a key is targeting it");
                mWindowManagerFuncs.moveDisplayToTop(displayId);
            }
        }

        return result;
    }

处理手势handleKeyGesture函数:

    private void handleKeyGesture(KeyEvent event, boolean interactive) {
        if (mKeyCombinationManager.interceptKey(event, interactive)) {
            // handled by combo keys manager.
            mSingleKeyGestureDetector.reset();
            return;
        }

        if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
            //若是power key, 并且是按下去的.
            mPowerKeyHandled = handleCameraGesture(event, interactive);
            if (mPowerKeyHandled) {
                // handled by camera gesture.
                mSingleKeyGestureDetector.reset();
                return;
            }
        }

        mSingleKeyGestureDetector.interceptKey(event, interactive);
    }

5. handleCameraGesture 函数: 

android/frameworks/base/services/core/java/com/android/server/GestureLauncherService.java

    /**
     * @return true if camera was launched, false otherwise.
     */
    @VisibleForTesting
    boolean handleCameraGesture(boolean useWakelock, int source) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handleCameraGesture");
        try {
             //判断setup wizard 是否设置完成。
            boolean userSetupComplete = isUserSetupComplete();
            if (!userSetupComplete) {
                if (DBG) {
                    Slog.d(TAG, String.format(
                            "userSetupComplete = %s, ignoring camera gesture.",
                            userSetupComplete));
                }
                return false;
            }
            if (DBG) {
                Slog.d(TAG, String.format(
                        "userSetupComplete = %s, performing camera gesture.",
                        userSetupComplete));
            }
            //保持常亮0.5s
            if (useWakelock) {
                // Make sure we don't sleep too early
                mWakeLock.acquire(500L);
            }
            //和SystemUI 服务可以关联起来。
            StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            //StatusBarManagerInternal 进行调度
            service.onCameraLaunchGestureDetected(source);
            return true;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

6. StatusBarManagerInternal service = LocalServices.getService( StatusBarManagerInternal.class)的对象获取:

android/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

    /**
     * Construct the service
     */
    public StatusBarManagerService(Context context) {

        ...
        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
        ...

    /**
     * Private API used by NotificationManagerService.
     */
    private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {

    ....

        @Override
        public void onCameraLaunchGestureDetected(int source) {
            if (mBar != null) {
                try {
                    mBar.onCameraLaunchGestureDetected(source);
                } catch (RemoteException e) {
                }
            }
        }

....

mBar 是通过registerStatusBar 函数注册得到。

android/frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

    // ================================================================================
    // Callbacks from the status bar service.
    // ================================================================================
    // TODO(b/118592525): refactor it as an IStatusBar API.
    @Override
    public RegisterStatusBarResult registerStatusBar(IStatusBar bar) {
        enforceStatusBarService();
        Slog.i(TAG, "registerStatusBar bar=" + bar);
        mBar = bar;
     
    }

android/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

    @Override
    public void start() {

     ...

        mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
        RegisterStatusBarResult result = null;
        try {
            result = mBarService.registerStatusBar(mCommandQueue);
        } catch (RemoteException ex) {
            ex.rethrowFromSystemServer();
        }

mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE));

mBarService 可以看出来,mBarService就是StatusBarManagerService 对象。

对应的注册:

android/frameworks/base/services/java/com/android/server/SystemServer.java

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
     */
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {

...

            if (!isWatch) {
                t.traceBegin("StartStatusBarManagerService");
                try {
                    statusBar = new StatusBarManagerService(context);
                    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                } catch (Throwable e) {
                    reportWtf("starting StatusBarManagerService", e);
                }
                t.traceEnd();
            }

mBarService.registerStatusBar(mCommandQueue);  就是调用StatusBarManagerService的registerStatusBar 函数. 所以 mBar 就是mCommandQueue。

也就是说启动camera 会调用到,由systemui 处理。

android/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java

    @Override
    public void onCameraLaunchGestureDetected(int source) {
        synchronized (mLock) {
            mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE);
            mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE, source, 0).sendToTarget();
        }
    }
                case MSG_CAMERA_LAUNCH_GESTURE:
                    for (int i = 0; i < mCallbacks.size(); i++) {
                        mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1);
                    }
                    break;

6. 处理camera手势:handleCameraGesture 函数

    // The camera gesture will be detected by GestureLauncherService.
    private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
        // camera gesture.
        if (mGestureLauncherService == null) {
            return false;
        }
        mCameraGestureTriggered = false;
        final MutableBoolean outLaunched = new MutableBoolean(false);
        //使用GestureLauncherService拦截power信息处理.
        final boolean intercept =
                mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
        if (!outLaunched.value) {
            // If GestureLauncherService intercepted the power key, but didn't launch camera app,
            // we should still return the intercept result. This prevents the single key gesture
            // detector from processing the power key later on.
            return intercept;
        }
        mCameraGestureTriggered = true;
        if (mRequestedOrSleepingDefaultDisplay) {
            mCameraGestureTriggeredDuringGoingToSleep = true;
        }
        return true;
    }

 7. 处理 mGestureLauncherService 对应的java类是:

android/frameworks/base/services/core/java/com/android/server/GestureLauncherService.java

    /**
     * Attempts to intercept power key down event by detecting certain gesture patterns
     *
     * @param interactive true if the event's policy contains {@code FLAG_INTERACTIVE}
     * @param outLaunched true if some action is taken as part of the key intercept (eg, app launch)
     * @return true if the key down event is intercepted
     */
    public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
            MutableBoolean outLaunched) {
        if (event.isLongPress()) {
            // Long presses are sent as a second key down. If the long press threshold is set lower
            // than the double tap of sequence interval thresholds, this could cause false double
            // taps or consecutive taps, so we want to ignore the long press event.
            //长按会误导双击行为,所以将此忽略掉。
            return false;
        }
        boolean launchCamera = false;
        boolean launchEmergencyGesture = false;
        boolean intercept = false;
        long powerTapInterval;

        synchronized (this) {
            //计算power键按下的时间间隔
            powerTapInterval = event.getEventTime() - mLastPowerDown;
            mLastPowerDown = event.getEventTime();
            if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
                //时间隔间太长,则重置状态
                // Tap too slow, reset consecutive tap counts.
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonSlowConsecutiveTaps = 1;
            } else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
                // Tap too slow for shortcuts
                //大于camera 启动的最小值,说明点击太慢了。
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonSlowConsecutiveTaps++;
            } else {
                // Fast consecutive tap
                //在此区间,判断为快速点击。
                mPowerButtonConsecutiveTaps++;
                mPowerButtonSlowConsecutiveTaps++;
            }
            // Check if we need to launch camera or emergency gesture flows
            //首先判断Emergency Gesture
            if (mEmergencyGestureEnabled) {
                // Commit to intercepting the powerkey event after the second "quick" tap to avoid
                // lockscreen changes between launching camera and the emergency gesture flow.
                //mPowerButtonConsecutiveTaps 要超过一次。 
                if (mPowerButtonConsecutiveTaps > 1) {
                    intercept = interactive;
                }
                if (mPowerButtonConsecutiveTaps == EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD) {
                    launchEmergencyGesture = true;
                }
            }
             //其次判断是mCameraDoubleTapPowerEnabled 
            if (mCameraDoubleTapPowerEnabled
                    && powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
                    && mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD) {
                launchCamera = true;
                intercept = interactive;
            }
        }
        if (mPowerButtonConsecutiveTaps > 1 || mPowerButtonSlowConsecutiveTaps > 1) {
            Slog.i(TAG, Long.valueOf(mPowerButtonConsecutiveTaps)
                    + " consecutive power button taps detected, "
                    + Long.valueOf(mPowerButtonSlowConsecutiveTaps)
                    + " consecutive slow power button taps detected");
        }
         //优先camera 启动。
        if (launchCamera) {
            Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
                    + powerTapInterval + "ms");
             //启动camera
            launchCamera = handleCameraGesture(false /* useWakelock */,
                    StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
            //若启动成功,则打印对应的日志。
            if (launchCamera) {
                mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
                        (int) powerTapInterval);
                mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
            }
        } else if (launchEmergencyGesture) {
            Slog.i(TAG, "Emergency gesture detected, launching.");
            launchEmergencyGesture = handleEmergencyGesture();
            mUiEventLogger.log(GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
        }
        mMetricsLogger.histogram("power_consecutive_short_tap_count",
                mPowerButtonSlowConsecutiveTaps);
        mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval);

        outLaunched.value = launchCamera || launchEmergencyGesture;
        // Intercept power key event if the press is part of a gesture (camera, eGesture) and the
        // user has completed setup.
        //
        return intercept && isUserSetupComplete();
    }

8. 对应的常量: 

    /**
     * Time in milliseconds in which the power button must be pressed twice so it will be considered
     * as a camera launch.
     */
    @VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
    /**
     * Interval in milliseconds in which the power button must be depressed in succession to be
     * considered part of an extended sequence of taps. Note that this is a looser threshold than
     * the camera launch gesture, because the purpose of this threshold is to measure the
     * frequency of consecutive taps, for evaluation for future gestures.
     */
    @VisibleForTesting static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500;
    /**
     * Number of taps required to launch camera shortcut.
     */
    private static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;

9. 对isUserSetupComplete 函数,进行讲解: 

    @Override
    public boolean isUserSetupComplete() {
          //判断setup wizard是否设置完成。
         boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
         //是否配置FEATURE_LEANBACK
        if (mHasFeatureLeanback) {
            isSetupComplete &= isTvUserSetupComplete();
        } else if (mHasFeatureAuto) {//是否配置 FEATURE_AUTOMOTIVE
            isSetupComplete &= isAutoUserSetupComplete();
        }
        return isSetupComplete;
    }

 10 handleEmergencyGesture 函数讲解:

android/frameworks/base/services/core/java/com/android/server/GestureLauncherService.java

    /**
     * @return true if emergency gesture UI was launched, false otherwise.
     */
    @VisibleForTesting
    boolean handleEmergencyGesture() {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                "GestureLauncher:handleEmergencyGesture");
        try {
            boolean userSetupComplete = isUserSetupComplete();
            if (!userSetupComplete) {
                if (DBG) {
                    Slog.d(TAG, String.format(
                            "userSetupComplete = %s, ignoring emergency gesture.",
                            userSetupComplete));
                }
                return false;
            }
            if (DBG) {
                Slog.d(TAG, String.format(
                        "userSetupComplete = %s, performing emergency gesture.",
                        userSetupComplete));
            }
            StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.onEmergencyActionLaunchGestureDetected();
            return true;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

 上面流程顺便分析了,点击power 启动camera或者Emergency。

   

二. 简单整理流程:

 1. 双击power 键camera的流程:

com_android_server_input_InputManagerService.cpp:: interceptKeyBeforeQueueing() 

-->InputManagerService.java::interceptKeyBeforeQueueing()

-->InputManagerCallback.java::interceptKeyBeforeQueueing()

-->PhoneWindowManager.java::interceptKeyBeforeQueueing()

-->PhoneWindowManager.java::handleKeyGesture()

-->GestureLauncherService.java::handleCameraGesture()

--->StatusBarManagerService.java::onCameraLaunchGestureDetected()

-->CommandQueue.java::onCameraLaunchGestureDetected()

--> vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java::onCameraLaunchGestureDetected(int source)

 2. 双击power 键Emergency的流程:

com_android_server_input_InputManagerService.cpp:: interceptKeyBeforeQueueing()  -->InputManagerService.java::interceptKeyBeforeQueueing() -->InputManagerCallback.java::interceptKeyBeforeQueueing() -->PhoneWindowManager.java::interceptKeyBeforeQueueing() -->PhoneWindowManager.java::handleKeyGesture()-->GestureLauncherService.java::handleEmergencyGesture()--->CommandQueue.java::onEmergencyActionLaunchGestureDetected() --> vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java::onEmergencyActionLaunchGestureDetected()

3. 亮屏流程:

(1).  interceptKeyBeforeQueueing 函数

android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    // TODO(b/117479243): handle it in InputPolicy
    /** {@inheritDoc} */
    @Override
    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
...
            case KeyEvent.KEYCODE_POWER: {
                EventLogTags.writeInterceptPower(
                        KeyEvent.actionToString(event.getAction()),
                        mPowerKeyHandled ? 1 : 0,
                        mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
                // Any activity on the power button stops the accessibility shortcut
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false; // wake-up will be handled separately
                if (down) {
                    interceptPowerKeyDown(event, interactiveAndOn);
                } else {
                    interceptPowerKeyUp(event, canceled);
                }
                break;
            }
...
}

 (2)  interceptPowerKeyDown 函数分析:

android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    //拦截power键down
    private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
        // Hold a wake lock until the power key is released.

        // 获取一个wakelock,防止cpu在此流程期间休眠 
        if (!mPowerKeyWakeLock.isHeld()) {
            mPowerKeyWakeLock.acquire();
        }

        mWindowManagerFuncs.onPowerKeyDown(interactive);

        // Stop ringing or end call if configured to do so when power is pressed.
        //对于来电场景下,按下power键的处理
        TelecomManager telecomManager = getTelecommService();
        boolean hungUp = false;
        if (telecomManager != null) {
            if (telecomManager.isRinging()) {
                // Pressing Power while there's a ringing incoming
                // call should silence the ringer.
               //如果配置为在按下电源时停止响铃或结束通话,则停止响铃或结束通话。
                telecomManager.silenceRinger();
            } else if ((mIncallPowerBehavior
                    & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
                    && telecomManager.isInCall() && interactive) {
                // Otherwise, if "Power button ends call" is enabled,
                // the Power button will hang up any current active call.
                //若正在打电话,则关掉电话。
                hungUp = telecomManager.endCall();
            }
        }

        final boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event);

        // Inform the StatusBar; but do not allow it to consume the event.
        //通知SystemUI处理
        sendSystemKeyToStatusBarAsync(event.getKeyCode());

        // 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 = mPowerKeyHandled || hungUp
                || handledByPowerManager || mKeyCombinationManager.isPowerKeyIntercepted();
        //此时还没有被处理
        if (!mPowerKeyHandled) {
            //若不是交互
            if (!interactive) {
                //使用电源键唤醒。
                wakeUpFromPowerKey(event.getDownTime());
            }
        } else {
            // handled by another power key policy.
            if (!mSingleKeyGestureDetector.isKeyIntercepted(KEYCODE_POWER)) {
                mSingleKeyGestureDetector.reset();
            }
        }
    }

 (3) wakeUpFromPowerKey函数

android/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    private void wakeUpFromPowerKey(long eventTime) {
         //唤醒屏幕
        if (wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
                PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER")) {
            // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout
            //是否发生HOME intent,默认是不发送。
            if (shouldWakeUpWithHomeIntent()) {
                startDockOrHome(DEFAULT_DISPLAY, /*fromHomeKey*/ false, /*wakenFromDreams*/ true,
                        PowerManager.wakeReasonToString(PowerManager.WAKE_REASON_POWER_BUTTON));
            }
        }
    }

 (4)wakeUp 函数

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
            String details) {
        final boolean theaterModeEnabled = isTheaterModeEnabled();
        //唤醒不是TheaterMode,而且此时的theaterMode 是打开的。
        if (!wakeInTheaterMode && theaterModeEnabled) {
            return false;
        }
        //若theaterMode,则将此值设置false
        if (theaterModeEnabled) {
            Settings.Global.putInt(mContext.getContentResolver(),
                    Settings.Global.THEATER_MODE_ON, 0);
        }
        //最终使用PMS的wakeup的函数
        mPowerManager.wakeUp(wakeTime, reason, details);
        return true;
    }

 (5)mPowerManager.wakeUp对应的函数:

android/frameworks/base/core/java/android/os/PowerManager.java

    /**
     * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
     *
     * 

If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen. * *

If the device is an Android TV playback device, it will attempt to turn on the * HDMI-connected TV and become the current active source via the HDMI-CEC One Touch Play * feature. * *

* This is what happens when the power key is pressed to turn on the screen. *

* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. *

* * @param time The time when the request to wake up was issued, in the * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly * order the wake up request with other power management functions. It should be set * to the timestamp of the input event that caused the request to wake up. * * @param reason The reason for the wake up. * * @param details A free form string to explain the specific details behind the wake up for * debugging purposes. * * @see #userActivity * @see #goToSleep * @hide */ public void wakeUp(long time, @WakeReason int reason, String details) { try { mService.wakeUp(time, reason, details, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }

(6)mService.wakeUp 对应的函数:

android/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

        @Override // Binder call
        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 {
                wakeDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, reason, details, uid,
                        opPackageName, uid);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }

(7) 对reason 常量进行解释:

android/frameworks/base/core/java/android/os/PowerManager.java

    /**
     * Wake up reason code: Waking for an unknown reason.
     * @hide
     */
    public static final int WAKE_REASON_UNKNOWN = 0;

    /**
     * Wake up reason code: Waking up due to power button press.
     * @hide
     */
    public static final int WAKE_REASON_POWER_BUTTON = 1;

    /**
     * Wake up reason code: Waking up because an application requested it.
     * @hide
     */
    public static final int WAKE_REASON_APPLICATION = 2;

    /**
     * Wake up reason code: Waking up due to being plugged in or docked on a wireless charger.
     * @hide
     */
    public static final int WAKE_REASON_PLUGGED_IN = 3;

    /**
     * Wake up reason code: Waking up due to a user performed gesture (e.g. douple tapping on the
     * screen).
     * @hide
     */
    public static final int WAKE_REASON_GESTURE = 4;

    /**
     * Wake up reason code: Waking up due to the camera being launched.
     * @hide
     */
    public static final int WAKE_REASON_CAMERA_LAUNCH = 5;

    /**
     * Wake up reason code: Waking up because a wake key other than power was pressed.
     * @hide
     */
    public static final int WAKE_REASON_WAKE_KEY = 6;

    /**
     * Wake up reason code: Waking up because a wake motion was performed.
     *
     * For example, a trackball that was set to wake the device up was spun.
     * @hide
     */
    public static final int WAKE_REASON_WAKE_MOTION = 7;

    /**
     * Wake up reason code: Waking due to HDMI.
     * @hide
     */
    public static final int WAKE_REASON_HDMI = 8;

    /**
     * Wake up reason code: Waking due to the lid being opened.
     * @hide
     */
    public static final int WAKE_REASON_LID = 9;

    /**
     * Wake up reason code: Waking due to display group being added.
     * @hide
     */
    public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10;

    /**
     * Wake up reason code: Waking due to display group being powered on.
     * @hide
     */
    public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11;

(8) wakeDisplayGroup 函数分析:

android/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private void wakeDisplayGroup(int groupId, long eventTime, @WakeReason int reason,
            String details, int uid, String opPackageName, int opUid) {
        synchronized (mLock) {
             
            // 判断是否可以进行亮屏,设置Wakefulness以及相关参数,发送亮屏广播 
            if (wakeDisplayGroupNoUpdateLocked(groupId, eventTime, reason, details, uid,
                    opPackageName, opUid)) {
                // 更新PMS中状态参数,通知DPC处理亮屏操作
                updatePowerStateLocked();
            }
        }
    }

(9) wakeDisplayGroupNoUpdateLocked 函数分析:

android/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private boolean wakeDisplayGroupNoUpdateLocked(int groupId, long eventTime,
            @WakeReason int reason, String details, int uid, String opPackageName, int opUid) {

        if (DEBUG_SPEW) {
            Slog.d(TAG, "wakeDisplayGroupNoUpdateLocked: eventTime=" + eventTime
                    + ", groupId=" + groupId + ", uid=" + uid);
        }
        // 判断触发时间是否正确,系统是否挂起或者是否还在开机状态
        if (eventTime < mLastSleepTime || mForceSuspendActive || !mSystemReady) {
            return false;
        }

        final int currentState = mDisplayGroupPowerStateMapper.getWakefulnessLocked(groupId);
         //设备已经完全唤醒
        if (currentState == WAKEFULNESS_AWAKE) {
              //没有开机完成并且sQuiescent 为true
            if (!mBootCompleted && sQuiescent) {
                mDirty |= DIRTY_QUIESCENT;
                return true;
            }
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay");
        try {
            Slog.i(TAG, "Powering on display group from"
                    + PowerManagerInternal.wakefulnessToString(currentState)
                    + " (groupId=" + groupId
                    + ", uid=" + uid
                    + ", reason=" + PowerManager.wakeReasonToString(reason)
                    + ", details=" + details
                    + ")...");
            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
            //设置Wakefulness,设置为亮屏
            setWakefulnessLocked(groupId, WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
                    opPackageName, details);
            //
            mDisplayGroupPowerStateMapper.setLastPowerOnTimeLocked(groupId, eventTime);
            mDisplayGroupPowerStateMapper.setPoweringOnLocked(groupId, true);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }

        return true;
    }

    /**
     * Wakefulness: The device is fully awake.  It can be put to sleep by a call to goToSleep().
     * When the user activity timeout expires, the device may start dreaming or go to sleep.
     */
    public static final int WAKEFULNESS_AWAKE = 1;
    // True if the lights should stay off until an explicit user action.
    private static boolean sQuiescent;
    // Dirty bit: display group wakefulness has changed
    private static final int DIRTY_DISPLAY_GROUP_WAKEFULNESS = 1 << 16;

(10)

setWakefulnessLocked 函数分析:

    @VisibleForTesting
    void setWakefulnessLocked(int groupId, int wakefulness, long eventTime, int uid, int reason,
            int opUid, String opPackageName, String details) {
          //表示在groupId 设置wakefulness 值是否成功,若设置成功则为true.
        if (mDisplayGroupPowerStateMapper.setWakefulnessLocked(groupId, wakefulness)) {

            //增加flag表示唤醒状态发生了变化。
            mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
           

   // 设置全局参数状态,并对亮屏工作进行准备

setGlobalWakefulnessLocked(

mDisplayGroupPowerStateMapper.getGlobalWakefulnessLocked(),
                    eventTime, reason, uid, opUid, opPackageName, details);

            //

if (wakefulness == WAKEFULNESS_AWAKE) {
                // Kick user activity to prevent newly awake group from timing out instantly.
                userActivityNoUpdateLocked(
                        groupId, eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
            }
        }
    }

此函数中最重要的就是参数mDirty,这个是PMS中一个非常重要的标志位,通过对它的位运算,可以知晓当前power状态是否发生变化,根据变化的位置可以进行对应的业务操作。

(11) setGlobalWakefulnessLocked函数分析:

    private void setGlobalWakefulnessLocked(int wakefulness, long eventTime, int reason, int uid,
            int opUid, String opPackageName, String details) {
         
        if (getWakefulnessLocked() == wakefulness) {
            //若和当前状态是一样的,说明没有变化,则直接返回。
            return;
        }

        // Phase 1: Handle pre-wakefulness change bookkeeping.
        final String traceMethodName;
        switch (wakefulness) {
            case WAKEFULNESS_ASLEEP:
                traceMethodName = "reallyGoToSleep";
                Slog.i(TAG, "Sleeping (uid " + uid + ")...");
                break;

            case WAKEFULNESS_AWAKE:
                traceMethodName = "wakeUp";
                Slog.i(TAG, "Waking up from "
                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                        + " (uid=" + uid
                        + ", reason=" + PowerManager.wakeReasonToString(reason)
                        + ", details=" + details
                        + ")...");
                mLastWakeTime = eventTime;
                mLastWakeReason = reason;
                break;

            case WAKEFULNESS_DREAMING:
                traceMethodName = "nap";
                Slog.i(TAG, "Nap time (uid " + uid + ")...");
                break;

            case WAKEFULNESS_DOZING:
                traceMethodName = "goToSleep";
                Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
                        + " (uid " + uid + ")...");

                mLastSleepTime = eventTime;
                mLastSleepReason = reason;
                mDozeStartInProgress = true;
                break;

            default:
                throw new IllegalArgumentException("Unexpected wakefulness: " + wakefulness);
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName);
        try {
            // Phase 2: Handle wakefulness change and bookkeeping.
            // 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) {
                // 通知系统中其他模块Wakefulness开始变化,发送亮屏广播
                mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
            }
            mAttentionDetector.onWakefulnessChangeStarted(wakefulness);

            // Phase 3: Handle post-wakefulness change bookkeeping.
            switch (wakefulness) {
                case WAKEFULNESS_AWAKE:
                    mNotifier.onWakeUp(reason, details, uid, opPackageName, opUid);
                    if (sQuiescent) {
                        mDirty |= DIRTY_QUIESCENT;
                    }
                    break;

                case WAKEFULNESS_DOZING:
                    // Report the number of wake locks that will be cleared by going to sleep.
                    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);
                    break;
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
        }
    }

(11) onWakefulnessChangeStarted函数分析:

frameworks/base/services/core/java/com/android/server/power/Notifier.java

    /**
     * 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();
        }
    }

(12)handleEarlyInteractiveChange 函数:

frameworks/base/services/core/java/com/android/server/power/Notifier.java

    /**
     * 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...
                // 通知WMS正在亮屏 
                mHandler.post(() -> mPolicy.startedWakingUp(mInteractiveChangeReason));

                // Send interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
                mPendingWakeUpBroadcast = true;
                //发送广播
                updatePendingBroadcastLocked();
            } else {
                // Going to sleep...
                // Tell the policy that we started going to sleep.
                mHandler.post(() -> mPolicy.startedGoingToSleep(mInteractiveChangeReason));
            }
        }
    }
    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);
        }
    }
                case MSG_BROADCAST:
                    sendNextBroadcast();

   (13) sendNextBroadcast 函数分析:

    private void sendNextBroadcast() {
        final int powerState;
        synchronized (mLock) {
            if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
                // Broadcasted power state is unknown.
                // Send wake up or go to sleep.
                switch (mPendingInteractiveState) {
                    case INTERACTIVE_STATE_ASLEEP:
                        mPendingGoToSleepBroadcast = false;
                        mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
                        break;

                    case INTERACTIVE_STATE_AWAKE:
                    default:
                        mPendingWakeUpBroadcast = false;
                        mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
                        break;
                }
            } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
                // Broadcasted power state is awake.  Send asleep if needed.
                if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
                    mPendingGoToSleepBroadcast = false;
                    mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
                } else {
                    finishPendingBroadcastLocked();
                    return;
                }
            } else {
                // Broadcasted power state is asleep.  Send awake if needed.
                if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
                    mPendingWakeUpBroadcast = false;
                    mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
                } else {
                    finishPendingBroadcastLocked();
                    return;
                }
            }

            mBroadcastStartTime = SystemClock.uptimeMillis();
            powerState = mBroadcastedInteractiveState;
        }
        //event log记录
        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);

        if (powerState == INTERACTIVE_STATE_AWAKE) {
             //发送亮屏广播
            sendWakeUpBroadcast();
        } else {
            sendGoToSleepBroadcast();
        }
    }

(14) sendWakeUpBroadcast 函数分析:

    private void sendWakeUpBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending wake up broadcast.");
        }
         
        if (mActivityManagerInternal.isSystemReady()) {
           //若AMS已经加载完成。
            //发送亮屏广播,针对所有的USER
            mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                    mWakeUpBroadcastDone, mHandler, 0, null, null);
        } else {
            //log记录:
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
            sendNextBroadcast();
        }
    }

mScreenOnIntent 对象的定义:

        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
        mScreenOnIntent.addFlags(
                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);

流程总结:

 [1] 当收到电话铃声时,此时按下Power键,则停止响铃或结束通话。

 [2] 当正在通话时,此时按下Power键,则关掉电话。 

 [3] 亮屏广播流程: 
     发送Intent.ACTION_SCREEN_ON的流程。

PhoneWindowManager.java::interceptKeyBeforeQueueing()
---> PhoneWindowManager.java::interceptPowerKeyDown()
---> PhoneWindowManager.java::wakeUpFromPowerKey()
---> PhoneWindowManager.java::wakeUp()
---> PowerManager.java::wakeUp()
---> PowerManagerService.java::wakeUp()
---> PowerManagerService.java::wakeDisplayGroup()
---> PowerManagerService.java::wakeDisplayGroupNoUpdateLocked()
---> PowerManagerService.java::setWakefulnessLocked()
---> PowerManagerService.java::setGlobalWakefulnessLocked()
---> Notifier.java::onWakefulnessChangeStarted()
---> Notifier.java:: handleEarlyInteractiveChange()
---> Notifier.java:: updatePendingBroadcastLocked()
---> Notifier.java::updatePendingBroadcastLocked()
---> Notifier.java::sendNextBroadcast()
---> Notifier.java::sendWakeUpBroadcast()

三.  DisplayPowerController处理

     DisplayPowerController 管理设备Display状态,主要处理近距sensor,亮灭屏.

    PMS updatePowerStateLocked中进行DPC侧业务处理的发起

   (1) updatePowerStateLocked函数:

            // Phase 3: Update display power state.
            final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);

    /**
     * Updates the display power state asynchronously.
     * When the update is finished, the ready state of the displays will be updated.  The display
     * controllers post 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 {@code true} if all displays became ready; {@code false} otherwise
     */
    private boolean updateDisplayPowerStateLocked(int dirty) {

       ...

           //申请电源的状态。

                final boolean ready = 
mDisplayManagerInternal.requestPowerState(groupId,
                        displayPowerRequest, mRequestWaitForNegativeProximity);

...

}

这里最后调用了mDisplayManagerInternal的requestPowerState方法,DisplayManagerInternal是一个抽象类,其具体实现的类是DisplayManagerService,在其重写的方法中发起了对DPC的调用。

四. 阻塞亮屏

在DPC中,最主要的一个业务就是进行亮屏前的最后准备,为什么说是亮屏前呢?因为里面有一个非常重要的环节就是阻塞亮屏,试想如果直接点亮屏幕,可能会出现什么情况,首先可能出现窗口还没有绘制,用户会观看到整个窗口绘制的过程,或者锁屏没有绘制,这样用户体验很差,所以在点亮屏幕前,我们需要进行一个阻塞亮屏的流程。

(1) requestPowerState 函数:

android/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

    /**
     * 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 (changed) {
                mDisplayReadyLocked = false;

                /
                if (!mPendingRequestChangedLocked) {

                   /如果没有等待正在处理电源状态信息,将状态变成正在等待处理状态。
                    mPendingRequestChangedLocked = true;
                    sendUpdatePowerStateLocked();
                }
            }
...
}

    private void sendUpdatePowerStateLocked() {
        if (!mStopped && !mPendingUpdatePowerStateLocked) {
            mPendingUpdatePowerStateLocked = true;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
            mHandler.sendMessage(msg);
        }
    }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_POWER_STATE:
                    updatePowerState();
                    break;

 (2) updatePowerState函数分析:

    private void updatePowerState() {
        // Update the power state request.
        // 更新power 状态
        final boolean mustNotify;
        final int previousPolicy;
        boolean mustInitialize = false;
        int brightnessAdjustmentFlags = 0;
        //将BrightnessReasonTemp 清空
        mBrightnessReasonTemp.set(null);
        synchronized (mLock) {
            //DisplayPowerController若已经停止,则直接返回。
            if (mStopped) {
                return;
            }
            //恢复mPendingUpdatePowerStateLocked 便于sendUpdatePowerStateLocked函数
            mPendingUpdatePowerStateLocked = false;
            if (mPendingRequestLocked == null) {
                //mPendingRequestLocked变量为null,说明requestPowerState没有被调用,所以需要等待。
                return; // wait until first actual power request
            }

            if (mPowerRequest == null) {
                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
                updatePendingProximityRequestsLocked();
                mPendingRequestChangedLocked = false;
                mustInitialize = true;
                // Assume we're on and bright until told otherwise, since that's the state we turn
                // on in.
                previousPolicy = DisplayPowerRequest.POLICY_BRIGHT;
            } else if (mPendingRequestChangedLocked) {
                previousPolicy = mPowerRequest.policy;
                mPowerRequest.copyFrom(mPendingRequestLocked);
                updatePendingProximityRequestsLocked();
                mPendingRequestChangedLocked = false;
                mDisplayReadyLocked = false;
            } else {
                previousPolicy = mPowerRequest.policy;
            }

            mustNotify = !mDisplayReadyLocked;
        }

        // Compute the basic display state using the policy.
        // We might override this below based on other factors.
        // Initialise brightness as invalid.
        int state;
        //初始化亮度状态为无效
        float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        boolean performScreenOffTransition = false;
        switch (mPowerRequest.policy) {
            //灭屏状态
            case DisplayPowerRequest.POLICY_OFF:
                state = Display.STATE_OFF;
                performScreenOffTransition = true;
                break;
            //doze状态 
            case DisplayPowerRequest.POLICY_DOZE:
                if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
                    state = mPowerRequest.dozeScreenState;
                } else {
                    state = Display.STATE_DOZE;
                }
                //不允许在低电量情况下,不允许自动调节亮度.
                if (!mAllowAutoBrightnessWhileDozingConfig) {
                    //针对doze 进行设置.
                    brightnessState = mPowerRequest.dozeScreenBrightness;
                    mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
                }
                break;
            case DisplayPowerRequest.POLICY_VR:
                state = Display.STATE_VR;
                break;
            case DisplayPowerRequest.POLICY_DIM:
            case DisplayPowerRequest.POLICY_BRIGHT:
            default:
                state = Display.STATE_ON;
                break;
        }
        assert(state != Display.STATE_UNKNOWN);

        // Initialize things the first time the power state is changed.
        //初始化,则需要实例化数据
        if (mustInitialize) {
            initialize(state);
        }

        // Apply the proximity sensor.
        //判断是否存在ProximitySensor
        if (mProximitySensor != null) {
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
                // At this point the policy says that the screen should be on, but we've been
                // asked to listen to the prox sensor to adjust the display state, so lets make
                // sure the sensor is on.
                setProximitySensorEnabled(true);
                //mScreenOffBecauseOfProximity 为false,表示远离屏幕.
                //sensor的距离是有效的.
                //mIgnoreProximityUntilChanged 忽略
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE
                        && !mIgnoreProximityUntilChanged) {
                    // Prox sensor already reporting "near" so we should turn off the screen.
                    // Also checked that we aren't currently set to ignore the proximity sensor
                    // temporarily.
                    //屏幕关闭因为靠近屏幕
                    mScreenOffBecauseOfProximity = true;
                    //
                    sendOnProximityPositiveWithWakelock();
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                // The policy says that we should have the screen on, but it's off due to the prox
                // and we've been asked to wait until the screen is far from the user to turn it
                // back on. Let keep the prox sensor on so we can tell when it's far again.
                setProximitySensorEnabled(true);
            } else {
                // We haven't been asked to use the prox sensor and we're not waiting on the screen
                // to turn back on...so lets shut down the prox sensor.
                setProximitySensorEnabled(false);
                mWaitingForNegativeProximity = false;
            }

            if (mScreenOffBecauseOfProximity
                    && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
                // The screen *was* off due to prox being near, but now it's "far" so lets turn
                // the screen back on.  Also turn it back on if we've been asked to ignore the
                // prox sensor temporarily.
                mScreenOffBecauseOfProximity = false;
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
            mIgnoreProximityUntilChanged = false;
        }

        if (!mLogicalDisplay.isEnabled()
                || mLogicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
                || mScreenOffBecauseOfProximity) {
            state = Display.STATE_OFF;
        }

        // Animate the screen state change unless already animating.
        // The transition may be deferred, so after this point we will use the
        // actual state instead of the desired one.
        final int oldState = mPowerState.getScreenState();
        // 准备执行屏幕变化动画,这里也可以认为是发起亮屏动画
        animateScreenStateChange(state, performScreenOffTransition);
        //获取屏幕状态,此时已经设置新的屏幕状态
        state = mPowerState.getScreenState();
        //如果屏幕此时的状态为灭屏,设置亮度为0
        if (state == Display.STATE_OFF) {
            brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
            //说明亮度调节的原因
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
        }

        // Always use the VR brightness when in the VR state.
        //若处于VR状态,则调节相应VR的亮度
        if (state == Display.STATE_VR) {
            brightnessState = mScreenBrightnessForVr;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
        }
        //brightnessState是非法数字,并且screen Brightness的Override 是有效值
        //将screen Brightness的Override的值赋值给brightnessState
        if ((Float.isNaN(brightnessState))
                && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
           
            brightnessState = mPowerRequest.screenBrightnessOverride;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
            mAppliedScreenBrightnessOverride = true;
        } else {
            //将mAppliedScreenBrightnessOverride 对应值设置为无效
            mAppliedScreenBrightnessOverride = false;
        }

        //在Doze模式下自动调节亮度是否可用
        final boolean autoBrightnessEnabledInDoze =
                mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
        //自动调节亮度是否可用
        final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && Float.isNaN(brightnessState)
                    && mAutomaticBrightnessController != null;

        //用户是否设置了亮度
        final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();

        // Use the temporary screen brightness if there isn't an override, either from
        // WindowManager or based on the display state.
        //使用临时亮度
        if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
            brightnessState = mTemporaryScreenBrightness;
            mAppliedTemporaryBrightness = true;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
        } else {
            mAppliedTemporaryBrightness = false;
        }
        //自动亮度调节
        final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
        //使用自动调节亮度,则将mTemporaryAutoBrightnessAdjustment 值可以赋值为无效值
        if (autoBrightnessAdjustmentChanged) {
            mTemporaryAutoBrightnessAdjustment = Float.NaN;
        }

        // Use the autobrightness adjustment override if set.
        final float autoBrightnessAdjustment;
        if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
            autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
            mAppliedTemporaryAutoBrightnessAdjustment = true;
        } else {
            autoBrightnessAdjustment = mAutoBrightnessAdjustment;
            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
            mAppliedTemporaryAutoBrightnessAdjustment = false;
        }
        // Apply brightness boost.
        // We do this here after deciding whether auto-brightness is enabled so that we don't
        // disable the light sensor during this temporary state.  That way when boost ends we will
        // be able to resume normal auto-brightness behavior without any delay.
        if (mPowerRequest.boostScreenBrightness
                && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) {
            brightnessState = PowerManager.BRIGHTNESS_MAX;
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
            mAppliedBrightnessBoost = true;
        } else {
            mAppliedBrightnessBoost = false;
        }

        // If the brightness is already set then it's been overridden by something other than the
        // user, or is a temporary adjustment.
        boolean userInitiatedChange = (Float.isNaN(brightnessState))
                && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);

        boolean hadUserBrightnessPoint = false;
        // Configure auto-brightness.
        if (mAutomaticBrightnessController != null) {
            hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
            mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                    mBrightnessConfiguration,
                    mLastUserSetScreenBrightness,
                    userSetBrightnessChanged, autoBrightnessAdjustment,
                    autoBrightnessAdjustmentChanged, mPowerRequest.policy);
        }

        if (mBrightnessTracker != null) {
            mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
        }

        boolean updateScreenBrightnessSetting = false;

        // Apply auto-brightness.
        boolean slowChange = false;
        if (Float.isNaN(brightnessState)) {
            float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
            if (autoBrightnessEnabled) {
                brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness();
                newAutoBrightnessAdjustment =
                        mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
            }
            if (isValidBrightnessValue(brightnessState)
                    || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
                // Use current auto-brightness value and slowly adjust to changes.
                brightnessState = clampScreenBrightness(brightnessState);
                if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
                    slowChange = true; // slowly adapt to auto-brightness
                }
                updateScreenBrightnessSetting = true;
                mAppliedAutoBrightness = true;
                mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
            } else {
                mAppliedAutoBrightness = false;
            }
            if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
                // If the autobrightness controller has decided to change the adjustment value
                // used, make sure that's reflected in settings.
                putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
            } else {
                // Adjustment values resulted in no change
                brightnessAdjustmentFlags = 0;
            }
        } else {
            // Any non-auto-brightness values such as override or temporary should still be subject
            // to clamping so that they don't go beyond the current max as specified by HBM
            // Controller.
            brightnessState = clampScreenBrightness(brightnessState);
            mAppliedAutoBrightness = false;
            brightnessAdjustmentFlags = 0;
        }

        // Use default brightness when dozing unless overridden.
        if ((Float.isNaN(brightnessState))
                && Display.isDozeState(state)) {
            brightnessState = clampScreenBrightness(mScreenBrightnessDozeConfig);
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
        }

        // Apply manual brightness.
        if (Float.isNaN(brightnessState)) {
            brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
            if (brightnessState != mCurrentScreenBrightnessSetting) {
                // The manually chosen screen brightness is outside of the currently allowed
                // range (i.e., high-brightness-mode), make sure we tell the rest of the system
                // by updating the setting.
                updateScreenBrightnessSetting = true;
            }
            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
        }

        // The current brightness to use has been calculated at this point (minus the adjustments
        // like low-power and dim), and HbmController should be notified so that it can accurately
        // calculate HDR or HBM levels. We specifically do it here instead of having HbmController
        // listen to the brightness setting because certain brightness sources (just as an app
        // override) are not saved to the setting, but should be reflected in HBM
        // calculations.
        mHbmController.onBrightnessChanged(brightnessState);

        if (updateScreenBrightnessSetting) {
            // Tell the rest of the system about the new brightness in case we had to change it
            // for things like auto-brightness or high-brightness-mode. Note that we do this
            // before applying the low power or dim transformations so that the slider
            // accurately represents the full possible range, even if they range changes what
            // it means in absolute terms.
            putScreenBrightnessSetting(brightnessState, /* updateCurrent */ true);
        }

        // We save the brightness info *after* the brightness setting has been changed so that
        // the brightness info reflects the latest value.
        saveBrightnessInfo(getScreenBrightnessSetting());

        // Apply dimming by at least some minimum amount when user activity
        // timeout is about to expire.
        if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
            if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
                brightnessState = Math.max(
                        Math.min(brightnessState - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
                                mScreenBrightnessDimConfig),
                        PowerManager.BRIGHTNESS_MIN);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
            }
            if (!mAppliedDimming) {
                slowChange = false;
            }
            mAppliedDimming = true;
        } else if (mAppliedDimming) {
            slowChange = false;
            mAppliedDimming = false;
        }
        // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
        // as long as it is above the minimum threshold.
        if (mPowerRequest.lowPowerMode) {
            if (brightnessState > PowerManager.BRIGHTNESS_MIN) {
                final float brightnessFactor =
                        Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
                brightnessState = Math.max(lowPowerBrightnessFloat, PowerManager.BRIGHTNESS_MIN);
                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
            }
            if (!mAppliedLowPower) {
                slowChange = false;
            }
            mAppliedLowPower = true;
        } else if (mAppliedLowPower) {
            slowChange = false;
            mAppliedLowPower = false;
        }

        // Animate the screen brightness when the screen is on or dozing.
        // Skip the animation when the screen is off or suspended or transition to/from VR.
        if (!mPendingScreenOff) {
            if (mSkipScreenOnBrightnessRamp) {
                if (state == Display.STATE_ON) {
                    if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
                        mInitialAutoBrightness = brightnessState;
                        mSkipRampState = RAMP_STATE_SKIP_INITIAL;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
                            && mUseSoftwareAutoBrightnessConfig
                            && !BrightnessSynchronizer.floatEquals(brightnessState,
                            mInitialAutoBrightness)) {
                        mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
                        mSkipRampState = RAMP_STATE_SKIP_NONE;
                    }
                } else {
                    mSkipRampState = RAMP_STATE_SKIP_NONE;
                }
            }

            final boolean wasOrWillBeInVr =
                    (state == Display.STATE_VR || oldState == Display.STATE_VR);
            final boolean initialRampSkip =
                    state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
            // While dozing, sometimes the brightness is split into buckets. Rather than animating
            // through the buckets, which is unlikely to be smooth in the first place, just jump
            // right to the suggested brightness.
            final boolean hasBrightnessBuckets =
                    Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
            // If the color fade is totally covering the screen then we can change the backlight
            // level without it being a noticeable jump since any actual content isn't yet visible.
            final boolean isDisplayContentVisible =
                    mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
            final boolean brightnessIsTemporary =
                    mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
            // We only want to animate the brightness if it is between 0.0f and 1.0f.
            // brightnessState can contain the values -1.0f and NaN, which we do not want to
            // animate to. To avoid this, we check the value first.
            // If the brightnessState is off (-1.0f) we still want to animate to the minimum
            // brightness (0.0f) to accommodate for LED displays, which can appear bright to the
            // user even when the display is all black. We also clamp here in case some
            // transformations to the brightness have pushed it outside of the currently
            // allowed range.
            float animateValue = clampScreenBrightness(brightnessState);

            //Tinno: add by qipeng.wang for bug:DGF-21  date:2022-11-07 begin
            if(mBrightnessReasonTemp.reason == BrightnessReason.REASON_TEMPORARY && TinnoFeature.FEATURE_HMD_BRIGHTNESS_CURVE) {
               if(animateValue < 0.8189f){
                   Settings.System.putIntForUser(mContext.getContentResolver(), "brightness_boost_mode", 0, UserHandle.USER_CURRENT);
               }
            }
            //Tinno: add by qipeng.wang for bug:DGF-21  date:2022-11-07 begin

            // If there are any HDR layers on the screen, we have a special brightness value that we
            // use instead. We still preserve the calculated brightness for Standard Dynamic Range
            // (SDR) layers, but the main brightness value will be the one for HDR.
            float sdrAnimateValue = animateValue;
            if (mHbmController.getHighBrightnessMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
                    && ((mBrightnessReason.modifier & BrightnessReason.MODIFIER_DIMMED) == 0
                    || (mBrightnessReason.modifier & BrightnessReason.MODIFIER_LOW_POWER) == 0)) {
                // We want to scale HDR brightness level with the SDR level
                animateValue = mHbmController.getHdrBrightnessValue();
            }

            final float currentBrightness = mPowerState.getScreenBrightness();
            final float currentSdrBrightness = mPowerState.getSdrScreenBrightness();
            //animateValue 必须是有效值,animateValue必须和上次不一样
              if (isValidBrightnessValue(animateValue)
                    && (animateValue != currentBrightness
                    || sdrAnimateValue != currentSdrBrightness)) {
                if (initialRampSkip || hasBrightnessBuckets
                        || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                    //设置屏幕亮度
                    animateScreenBrightness(animateValue, sdrAnimateValue,
                            SCREEN_ANIMATION_RATE_MINIMUM);
                } else {
                    boolean isIncreasing = animateValue > currentBrightness;
                    final float rampSpeed;
                    if (isIncreasing && slowChange) {
                        rampSpeed = mBrightnessRampRateSlowIncrease;
                    } else if (isIncreasing && !slowChange) {
                        rampSpeed = mBrightnessRampRateFastIncrease;
                    } else if (!isIncreasing && slowChange) {
                        rampSpeed = mBrightnessRampRateSlowDecrease;
                    } else {
                        rampSpeed = mBrightnessRampRateFastDecrease;
                    }
                    //设置屏幕亮度
                    animateScreenBrightness(animateValue, sdrAnimateValue, rampSpeed);
                }
            }

            if (!brightnessIsTemporary) {
                if (userInitiatedChange && (mAutomaticBrightnessController == null
                        || !mAutomaticBrightnessController.hasValidAmbientLux())) {
                    // If we don't have a valid lux reading we can't report a valid
                    // slider event so notify as if the system changed the brightness.
                    userInitiatedChange = false;
                }
                notifyBrightnessChanged(brightnessState, userInitiatedChange,
                        hadUserBrightnessPoint);
            }

        }

        // Log any changes to what is currently driving the brightness setting.
        if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '"
                    + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
                    + "', previous reason: '" + mBrightnessReason + "'.");

            if(mBrightnessReasonTemp.reason == BrightnessReason.REASON_SCREEN_OFF && mScreenOffBecauseOfProximity){
                StatusBarManager statusBarManager = (StatusBarManager) mContext
                        .getSystemService(android.app.Service.STATUS_BAR_SERVICE);
                if(statusBarManager != null){
                    statusBarManager.collapsePanels();
                }
            }
            mBrightnessReason.set(mBrightnessReasonTemp);
        } else if (mBrightnessReasonTemp.reason == BrightnessReason.REASON_MANUAL
                && userSetBrightnessChanged) {
            Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
        }

        // Update display white-balance.
        if (mDisplayWhiteBalanceController != null) {
            if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
                mDisplayWhiteBalanceController.setEnabled(true);
                mDisplayWhiteBalanceController.updateDisplayColorTemperature();
            } else {
                mDisplayWhiteBalanceController.setEnabled(false);
            }
        }

        // Determine whether the display is ready for use in the newly requested state.
        // Note that we do not wait for the brightness ramp animation to complete before
        // reporting the display is ready because we only need to ensure the screen is in the
        // right power state even as it continues to converge on the desired brightness.
        final boolean ready = mPendingScreenOnUnblocker == null &&
                (!mColorFadeEnabled ||
                        (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
                && mPowerState.waitUntilClean(mCleanListener);
        final boolean finished = ready
                && !mScreenBrightnessRampAnimator.isAnimating();

        // 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(mDisplayId);
        }

        // Grab a wake lock if we have unfinished business.
        if (!finished && !mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Unfinished business...");
            }
            mCallbacks.acquireSuspendBlocker();
            mUnfinishedBusiness = true;
        }

        // Notify the power manager when ready.
        if (ready && mustNotify) {
            // Send state change.
            synchronized (mLock) {
                if (!mPendingRequestChangedLocked) {
                    mDisplayReadyLocked = true;

                    if (DEBUG) {
                        Slog.d(TAG, "Display ready!");
                    }
                }
            }
            sendOnStateChangedWithWakelock();
        }

        // Release the wake lock when we have no unfinished business.
        if (finished && mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Finished business...");
            }
            mUnfinishedBusiness = false;
            mCallbacks.releaseSuspendBlocker();
        }

        // Record if dozing for future comparison.
        mDozing = state != Display.STATE_ON;

        if (previousPolicy != mPowerRequest.policy) {
            logDisplayPolicyChanged(mPowerRequest.policy);
        }
    }

(3) android/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

    private void animateScreenBrightness(float target, float sdrTarget, float rate) {
        if (DEBUG) {
            Slog.d(TAG, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget
                    + ", rate=" + rate);
        }
        mScreenBrightnessRampAnimator.setDisplayId(mDisplayId);
        if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) {
            Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
            // TODO(b/153319140) remove when we can get this from the above trace invocation
            SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
            noteScreenBrightness(target);
        }
    }

(4) mScreenBrightnessRampAnimator 的定义和对应的参数

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

        mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
                //first Property
                DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
                //second Property
                DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);

//DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT定义:

    public static final FloatProperty SCREEN_BRIGHTNESS_FLOAT =
            new FloatProperty("screenBrightnessFloat") {
                @Override
                public void setValue(DisplayPowerState object, float value) {
                    object.setScreenBrightness(value);
                }

                @Override
                public Float get(DisplayPowerState object) {
                    return object.getScreenBrightness();
                }
            };

(4)  DisplayPowerState.setScreenBrightness 函数调用

    /**
     * Sets the display brightness.
     *
     * @param brightness The brightness, ranges from 0.0f (minimum) to 1.0f (brightest), or is -1f
     *                   (off).
     */
    public void setScreenBrightness(float brightness) {
        if (mScreenBrightness != brightness) {
            if (DEBUG) {
                Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
            }

            mScreenBrightness = brightness;
            if (mScreenState != Display.STATE_OFF) {
                mScreenReady = false;
               / /更新背光值。
                scheduleScreenUpdate();
            }
        }
    }
    private void scheduleScreenUpdate() {
        if (!mScreenUpdatePending) {
            mScreenUpdatePending = true;
            postScreenUpdateThreadSafe();
        }
    }

    private void postScreenUpdateThreadSafe() {
        mHandler.removeCallbacks(mScreenUpdateRunnable);
        //通过handle的方式
        mHandler.post(mScreenUpdateRunnable);
    }
    private final Runnable mScreenUpdateRunnable = new Runnable() {
        @Override
        public void run() {
            mScreenUpdatePending = false;

            float brightnessState = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
            float sdrBrightnessState = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f
                            ? mSdrScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
             //设置状态
            if (mPhotonicModulator.setState(mScreenState, brightnessState, sdrBrightnessState)) {
                if (DEBUG) {
                    Slog.d(TAG, "Screen ready");
                }
                mScreenReady = true;
                invokeCleanListenerIfNeeded();
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Screen not ready");
                }
            }
        }
    };

(5)frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java::PhotonicModulator

        public boolean setState(int state, float brightnessState, float sdrBrightnessState) {
            synchronized (mLock) {
                boolean stateChanged = state != mPendingState;
                boolean backlightChanged = brightnessState != mPendingBacklight
                        || sdrBrightnessState != mPendingSdrBacklight;
                if (stateChanged || backlightChanged) {
                    if (DEBUG) {
                        Slog.d(TAG, "Requesting new screen state: state="
                                + Display.stateToString(state) + ", backlight=" + brightnessState);
                    }

                    mPendingState = state;
                    mPendingBacklight = brightnessState;
                    mPendingSdrBacklight = sdrBrightnessState;
                    boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
                    mStateChangeInProgress = stateChanged || mStateChangeInProgress;
                    mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;

                    if (!changeInProgress) {
                        //唤醒锁==>直接找到mLock.wait()
                        mLock.notifyAll();
                    }
                }
                return !mStateChangeInProgress;
            }
        }

直接唤醒mLock.wait(),调用mBlanker.requestDisplayState()

        @Override
        public void run() {
            for (;;) {
                // Get pending change.
                final int state;
                final boolean stateChanged;
                final float brightnessState;
                final float sdrBrightnessState;
                final boolean backlightChanged;
                synchronized (mLock) {
                    state = mPendingState;
                    stateChanged = (state != mActualState);
                    brightnessState = mPendingBacklight;
                    sdrBrightnessState = mPendingSdrBacklight;
                    backlightChanged = brightnessState != mActualBacklight
                            || sdrBrightnessState != mActualSdrBacklight;
                    if (!stateChanged) {
                        // State changed applied, notify outer class.
                        postScreenUpdateThreadSafe();
                        mStateChangeInProgress = false;
                    }
                    if (!backlightChanged) {
                        mBacklightChangeInProgress = false;
                    }
                    boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState);
                    boolean changed = stateChanged || backlightChanged;
​​​​​​​                    //若是无效状态或者状态没有改变,则处于等待状态
                    if (!valid || !changed) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException ex) {
                            if (mStopped) {
                                return;
                            }
                        }
                        continue;
                    }
                    mActualState = state;
                    mActualBacklight = brightnessState;
                    mActualSdrBacklight = sdrBrightnessState;
                }

                // Apply pending change.
                if (DEBUG) {
                    Slog.d(TAG, "Updating screen state: id=" + mDisplayId +  ", state="
                            + Display.stateToString(state) + ", backlight=" + brightnessState
                            + ", sdrBacklight=" + sdrBrightnessState);
                }
                mBlanker.requestDisplayState(mDisplayId, state, brightnessState,
                        sdrBrightnessState);
            }
        }
    }

(6)frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java

    /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */
    private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
        // Synchronized to avoid race conditions when updating multiple display states.
        @Override
        public synchronized void requestDisplayState(int displayId, int state, float brightness,
                float sdrBrightness) {
            boolean allInactive = true;
            boolean allOff = true;
            final boolean stateChanged;
            synchronized (mSyncRoot) {
                final int index = mDisplayStates.indexOfKey(displayId);
                if (index > -1) {
                    final int currentState = mDisplayStates.valueAt(index);
                    stateChanged = state != currentState;
                    if (stateChanged) {
                        final int size = mDisplayStates.size();
                        for (int i = 0; i < size; i++) {
                            final int displayState = i == index ? state : mDisplayStates.valueAt(i);
                            if (displayState != Display.STATE_OFF) {
                                allOff = false;
                            }
                            if (Display.isActiveState(displayState)) {
                                allInactive = false;
                            }
                            if (!allOff && !allInactive) {
                                break;
                            }
                        }
                    }
                } else {
                    stateChanged = false;
                }
            }

            // The order of operations is important for legacy reasons.
            //当状态是Display.STATE_OFF时
            if (state == Display.STATE_OFF) {
                requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
            }

            if (stateChanged) {
                mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff);
            }
            //当状态不是Display.STATE_OFF时
            if (state != Display.STATE_OFF) {
                requestDisplayStateInternal(displayId, state, brightness, sdrBrightness);
            }
        }
    };
    private void requestDisplayStateInternal(int displayId, int state, float brightnessState,
            float sdrBrightnessState) {
        if (state == Display.STATE_UNKNOWN) {
            state = Display.STATE_ON;
        }

        brightnessState = clampBrightness(state, brightnessState);
        sdrBrightnessState = clampBrightness(state, sdrBrightnessState);

        // Update the display state within the lock.
        // Note that we do not need to schedule traversals here although it
        // may happen as a side-effect of displays changing state.
        final Runnable runnable;
        final String traceMessage;
        synchronized (mSyncRoot) {
            final int index = mDisplayStates.indexOfKey(displayId);

            final BrightnessPair brightnessPair =
                    index < 0 ? null : mDisplayBrightnesses.valueAt(index);
            if (index < 0 || (mDisplayStates.valueAt(index) == state
                    && brightnessPair.brightness == brightnessState
                    && brightnessPair.sdrBrightness == sdrBrightnessState)) {
                return; // Display no longer exists or no change.
            }

            if (Trace.isTagEnabled(Trace.TRACE_TAG_POWER)) {
                traceMessage = Display.stateToString(state)
                           + ", brightness=" + brightnessState
                           + ", sdrBrightness=" + sdrBrightnessState;
                Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_POWER,
                        "requestDisplayStateInternal:" + displayId,
                        traceMessage, displayId);
            }

            mDisplayStates.setValueAt(index, state);
            brightnessPair.brightness = brightnessState;
            brightnessPair.sdrBrightness = sdrBrightnessState;

            runnable = 
//更新显示状态​​​​​​​
updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId)
                    .getPrimaryDisplayDeviceLocked());
            if (Trace.isTagEnabled(Trace.TRACE_TAG_POWER)) {
                Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_POWER,
                        "requestDisplayStateInternal:" + displayId, displayId);
            }
        }

        // Setting the display power state can take hundreds of milliseconds
        // to complete so we defer the most expensive part of the work until
        // after we have exited the critical section to avoid blocking other
        // threads for a long time.
        if (runnable != null) {
            runnable.run();
        }
    }
    private Runnable updateDisplayStateLocked(DisplayDevice device) {
        // Blank or unblank the display immediately to match the state requested
        // by the display power controller (if known).
        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
            if (display == null) {
                return null;
            }
            final int displayId = display.getDisplayIdLocked();
            final int state = mDisplayStates.get(displayId);

            // Only send a request for display state if display state has already been initialized.
            if (state != Display.STATE_UNKNOWN) {
                final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
                return device.requestDisplayStateLocked(state, brightnessPair.brightness,
                        brightnessPair.sdrBrightness);
            }
        }
        return null;
    }

(7) frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java

        @Override
        public Runnable requestDisplayStateLocked(final int state, final float brightnessState,
                final float sdrBrightnessState) {

                return new Runnable() {
                    @Override
                    public void run() {


                        // Apply brightness changes given that we are in a non-suspended state.
                        if (brightnessChanged || vrModeChange) {

                            setDisplayBrightness(brightnessState, sdrBrightnessState);
                            mBrightnessState = brightnessState;
                            mSdrBrightnessState = sdrBrightnessState;
                        }

                       
                    }

                    private void setVrMode(boolean isVrEnabled) {
                        if (DEBUG) {
                            Slog.d(TAG, "setVrMode("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }
                        mBacklightAdapter.setVrMode(isVrEnabled);
                    }

                    private void setDisplayState(int state) {
                        if (DEBUG || MTK_DEBUG) {
                            Slog.d(TAG, "setDisplayState("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }

                        // We must tell sidekick to stop controlling the display before we
                        // can change its power mode, so do that first.
                        if (mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#endDisplayControl");
                            try {
                                mSidekickInternal.endDisplayControl();
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                            mSidekickActive = false;
                        }
                        final int mode = getPowerModeForState(state);
                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
                                + "id=" + physicalDisplayId
                                + ", state=" + Display.stateToString(state) + ")");
                        try {
                            mSurfaceControlProxy.setDisplayPowerMode(token, mode);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                        // If we're entering a suspended (but not OFF) power state and we
                        // have a sidekick available, tell it now that it can take control.
                        if (Display.isSuspendedState(state) && state != Display.STATE_OFF
                                && mSidekickInternal != null && !mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#startDisplayControl");
                            try {
                                mSidekickActive = mSidekickInternal.startDisplayControl(state);
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                        }
                    }

                    private void setDisplayBrightness(float brightnessState,
                            float sdrBrightnessState) {


                        if (DEBUG || MTK_DEBUG) {
                            Slog.d(TAG, "setDisplayBrightness("
                                    + "id=" + physicalDisplayId
                                    + ", brightnessState=" + brightnessState
                                    + ", sdrBrightnessState=" + sdrBrightnessState + ")");
                        }

                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
                                + "id=" + physicalDisplayId + ", brightnessState="
                                + brightnessState + ", sdrBrightnessState=" + sdrBrightnessState
                                + ")");
                        try {
                            final float backlight = brightnessToBacklight(brightnessState);
                            final float sdrBacklight = brightnessToBacklight(sdrBrightnessState);

                            final float nits = backlightToNits(backlight);
                            final float sdrNits = backlightToNits(sdrBacklight);

                            mBacklightAdapter.setBacklight(sdrBacklight, sdrNits, backlight, nits);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(brightnessState));
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "SdrScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(
                                            sdrBrightnessState));
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }
        // Set backlight within min and max backlight values
        void setBacklight(float sdrBacklight, float sdrNits, float backlight, float nits) {
            if (mUseSurfaceControlBrightness || mForceSurfaceControl) {
                if (BrightnessSynchronizer.floatEquals(
                        sdrBacklight, PowerManager.BRIGHTNESS_INVALID_FLOAT)) {
                    mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, backlight);
                } else {
                    mSurfaceControlProxy.setDisplayBrightness(mDisplayToken, sdrBacklight, sdrNits,
                            backlight, nits);
                }
            } else if (mBacklight != null) {
               //设置背光
                mBacklight.setBrightness(backlight);
            }
        }

(7)frameworks/base/services/core/java/com/android/server/lights/LightsService.java

    private final class LightImpl extends LogicalLight {

        private LightImpl(Context context, HwLight hwLight) {
            mHwLight = hwLight;
        }

        @Override
        public void setBrightness(float brightness) {
            setBrightness(brightness, BRIGHTNESS_MODE_USER);
        }

        @Override
        public void setBrightness(float brightness, int brightnessMode) {
            if (Float.isNaN(brightness)) {
                Slog.w(TAG, "Brightness is not valid: " + brightness);
                return;
            }
            synchronized (this) {
                // LOW_PERSISTENCE cannot be manually set
                if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
                    Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mHwLight.id
                            + ": brightness=" + brightness);
                    return;
                }
                int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt(brightness);
                int color = brightnessInt & 0x000000ff;
                color = 0xff000000 | (color << 16) | (color << 8) | color;
                setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
            }
        }
        private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
            if (shouldBeInLowPersistenceMode()) {
                brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE;
            } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
                brightnessMode = mLastBrightnessMode;
            }

            if (!mInitialized || color != mColor || mode != mMode || onMS != mOnMS ||
                    offMS != mOffMS || mBrightnessMode != brightnessMode) {
                if (DEBUG) {
                    Slog.v(TAG, "setLight #" + mHwLight.id + ": color=#"
                            + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
                }
                mInitialized = true;
                mLastColor = mColor;
                mColor = color;
                mMode = mode;
                mOnMS = onMS;
                mOffMS = offMS;
                mBrightnessMode = brightnessMode;
                setLightUnchecked(color, mode, onMS, offMS, brightnessMode);
            }
        }
        private void setLightUnchecked(int color, int mode, int onMS, int offMS,
                int brightnessMode) {
            Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLightState(" + mHwLight.id + ", 0x"
                    + Integer.toHexString(color) + ")");
            try {
                if (mVintfLights != null) {
                    HwLightState lightState = new HwLightState();
                    lightState.color = color;
                    lightState.flashMode = (byte) mode;
                    lightState.flashOnMs = onMS;
                    lightState.flashOffMs = offMS;
                    lightState.brightnessMode = (byte) brightnessMode;
                    mVintfLights.get().setLightState(mHwLight.id, lightState);
                } else {
                    // 这是一个native方法
                    setLight_native(mHwLight.id, color, mode, onMS, offMS, brightnessMode);
                }
            } catch (RemoteException | UnsupportedOperationException ex) {
                Slog.e(TAG, "Failed issuing setLightState", ex);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_POWER);
            }
        }

(8) frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp

static const JNINativeMethod method_table[] = {
    { "setLight_native", "(IIIIII)V", (void*)setLight_native },
};

static void setLight_native(
        JNIEnv* /* env */,
        jobject /* clazz */,
        jint light,
        jint colorARGB,
        jint flashMode,
        jint onMS,
        jint offMS,
        jint brightnessMode) {

    if (!sLightSupported) {
        return;
    }

    if (!validate(light, flashMode, brightnessMode)) {
        return;
    }

    Type type = static_cast(light);
    LightState state = constructState(
        colorARGB, flashMode, onMS, offMS, brightnessMode);

    {
        android::base::Timer t;
        sp hal = ILight::getService();
        if (hal == nullptr) {
            sLightSupported = false;
            return;
        }
        Return ret = hal->setLight(type, state);
        processReturn(ret, type, state);
        if (t.duration() > 50ms) ALOGD("Excessive delay setting light");
    }
}

 (9)androids/vendor/mediatek/proprietary/hardware/liblights/aidl/default/Lights.cpp

/* LCD BACKLIGHT */
char const*const LCD_FILE
        = "/sys/class/leds/lcd-backlight/brightness";
static int
set_light_backlight(struct light_device_t* dev,
        struct light_state_t const* state)
{
    int err = 0;
    int brightness = rgb_to_brightness(state);
    pthread_mutex_lock(&g_lock);
    g_backlight = brightness;
    err = write_int(LCD_FILE, brightness);
    if (g_haveTrackballLight) {
        handle_trackball_light_locked(dev);
    }
    pthread_mutex_unlock(&g_lock);
    return err;
}

五. 从按下power键到亮屏的流程小结: 

-->com_android_server_input_InputManagerService.cpp:: interceptKeyBeforeQueueing()

 -->InputManagerService.java::interceptKeyBeforeQueueing()

-->InputManagerCallback.java::interceptKeyBeforeQueueing()

-->PhoneWindowManager.java::interceptKeyBeforeQueueing()
---> PhoneWindowManager.java::interceptPowerKeyDown()
---> PhoneWindowManager.java::wakeUpFromPowerKey()
---> PhoneWindowManager.java::wakeUp()
---> PowerManager.java::wakeUp()
---> PowerManagerService.java::wakeUp()
---> PowerManagerService.java::wakeDisplayGroup()

---> PowerManagerService.java::wakeDisplayGroupNoUpdateLocked()
---> PowerManagerService.java::updatePowerStateLocked()

---> PowerManagerService.java::updateDisplayPowerStateLocked()

---> DisplayPowerController.java::requestPowerState()

---> DisplayPowerController.java::sendUpdatePowerStateLocked()

---> DisplayPowerController.java::updatePowerState()

---> DisplayPowerController.java::animateScreenBrightness()

---> RampAnimator.java::DualRampAnimator::animateTo()

---> DisplayPowerState.java::SCREEN_BRIGHTNESS_FLOAT::setValue()

---> DisplayPowerState.java::setScreenBrightness()

---> DisplayPowerState.java::scheduleScreenUpdate()

---> DisplayPowerState.java::postScreenUpdateThreadSafe()

---> DisplayPowerState.java::mScreenUpdateRunnable::run()

---> DisplayPowerState.java::PhotonicModulator::setState() ==调用mLock.notifyAll()唤醒锁

---> DisplayPowerState.java::PhotonicModulator::​run() 

---> DisplayManagerService.java::mDisplayBlanker::requestDisplayState()

 ---> DisplayManagerService.java::requestDisplayStateInternal()

---> DisplayManagerService.java::updateDisplayStateLocked() 

---> LocalDisplayAdapter.java::requestDisplayStateLocked()

---> LocalDisplayAdapter.java::setDisplayBrightness()

---> LocalDisplayAdapter.java::sBacklightAdapter::setBacklight()

--->LightsService.java::setBrightness()

--->LightsService.java::setLightLocked()

--->LightsService.java::setLightUnchecked()

-->LightsService.java::setLight_native() == 调用native方法

-->com_android_server_lights_LightsService.cpp::setLight_native()

Return ret = hal->setLight(type, state);

....(对HAL层不熟悉,跳过)

--->lights.cpp::set_light_backlight()   ===>写入节点亮屏

六.log 验证:

抓取日志的命令:

按照上面的分析,专门加日志。

sudo adb logcat -b all | grep -E "lights|LightsService|LocalDisplayAdapter|DisplayPowerState|RampAnimator|DisplayPowerController|DisplayPowerController2|DisplayManagerService|PowerGroup|PowerManagerService|PowerManager|PhoneWindowManager|InputManagerCallback|InputManagerService|InputManager-JNI|light"
 

 下面是AndroidU项目打印的日志:可以看看和Android T 大部分逻辑是一样的。

12-09 15:03:25.674  1210  2448 E InputManager-JNI: com_android_server_input_InputManagerService.cpp::interceptKeyBeforeQueueing
12-09 15:03:25.674  1210  2448 E InputManagerService: interceptKeyBeforeQueueing
12-09 15:03:25.674  1210  2448 E InputManagerCallback: interceptKeyBeforeQueueing
12-09 15:03:25.674  1210  2448 E PhoneWindowManager: interceptKeyBeforeQueueing
12-09 15:03:25.676  1210  2448 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.676  1210  2448 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.676  1210  2448 E PowerGroup: updateLocked
12-09 15:03:25.676  1210  2448 E DisplayManagerService: requestPowerState
12-09 15:03:25.676  1210  2448 E DisplayPowerController2: requestPowerState
12-09 15:03:25.677  1210  2447 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.677  1210  2447 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.677  1210  2447 E PowerGroup: updateLocked
12-09 15:03:25.677  1210  2447 E DisplayManagerService: requestPowerState
12-09 15:03:25.677  1210  2447 E DisplayPowerController2: requestPowerState
12-09 15:03:25.686  1210  2949 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.686  1210  2949 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.686  1210  2949 E PowerGroup: updateLocked
12-09 15:03:25.686  1210  2949 E DisplayManagerService: requestPowerState
12-09 15:03:25.686  1210  2949 E DisplayPowerController2: requestPowerState
12-09 15:03:25.699  1210  4329 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.699  1210  4329 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.699  1210  4329 E PowerGroup: updateLocked
12-09 15:03:25.699  1210  4329 E DisplayManagerService: requestPowerState
12-09 15:03:25.699  1210  4329 E DisplayPowerController2: requestPowerState
12-09 15:03:25.711  1210  5026 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.712  1210  5026 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.712  1210  5026 E PowerGroup: updateLocked
12-09 15:03:25.712  1210  5026 E DisplayManagerService: requestPowerState
12-09 15:03:25.712  1210  5026 E DisplayPowerController2: requestPowerState
12-09 15:03:25.722  1210  5026 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.722  1210  5026 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.722  1210  5026 E PowerGroup: updateLocked
12-09 15:03:25.722  1210  5026 E DisplayManagerService: requestPowerState
12-09 15:03:25.722  1210  5026 E DisplayPowerController2: requestPowerState
12-09 15:03:25.733  1210  4329 E PowerManagerService: updatePowerStateLocked 
12-09 15:03:25.733  1210  4329 E PowerManagerService: updatePowerGroupsLocked
12-09 15:03:25.734  1210  2770 E DisplayPowerState: postScreenUpdateThreadSafe
12-09 15:03:25.735  1210  1344 E DisplayPowerState: mScreenUpdateRunnable::run
12-09 15:03:25.735  1210  1344 E DisplayPowerState: PhotonicModulator::setState
12-09 15:03:25.736  1210  4329 E PowerGroup: updateLocked
12-09 15:03:25.736  1210  4329 E DisplayManagerService: requestPowerState
12-09 15:03:25.737  1210  4329 E DisplayPowerController2: requestPowerState
12-09 15:03:25.805  1210  1344 I DisplayPowerController2[0]: Unblocked screen on after 311 ms
12-09 15:03:25.806  1210  1344 E DisplayPowerController2: updatePowerState
12-09 15:03:25.806  1210  1344 E DisplayPowerController2: updatePowerStateInternal
12-09 15:03:25.810  1210  1344 E DisplayPowerState: scheduleScreenUpdate
12-09 15:03:25.810  1210  1344 E DisplayPowerState: postScreenUpdateThreadSafe
12-09 15:03:25.818  1210  1344 E DisplayPowerState: mScreenUpdateRunnable::run
12-09 15:03:25.818  1210  1344 E DisplayPowerState: PhotonicModulator::setState
12-09 15:03:25.818  1210  1344 E DisplayPowerState: PhotonicModulator::setState::mLock.notifyAll
12-09 15:03:25.818  1210  1344 E DisplayPowerController2: sendUpdatePowerState
12-09 15:03:25.818  1210  1344 E DisplayPowerController2: sendUpdatePowerStateLocked
12-09 15:03:25.818  1210  2770 E DisplayPowerState: postScreenUpdateThreadSafe
12-09 15:03:25.818  1210  2770 E DisplayManagerService: requestDisplayState
12-09 15:03:25.819  1210  2770 E DisplayManagerService: requestDisplayStateInternal
12-09 15:03:25.819  1210  2770 E DisplayManagerService: updateDisplayStateLocked
12-09 15:03:25.819  1210  2770 E LocalDisplayAdapter: requestDisplayStateLocked
12-09 15:03:25.819  1210  2770 E LocalDisplayAdapter: setDisplayBrightness
12-09 15:03:25.819  1210  2770 E LocalDisplayAdapter: BacklightAdapter::setBacklight
12-09 15:03:25.819  1210  2770 E LightsService: setBrightness(float brightness)
12-09 15:03:25.819  1210  2770 E LightsService: setBrightness(float brightness, int brightnessMode)
12-09 15:03:25.819  1210  1344 E DisplayPowerController2: updatePowerState
12-09 15:03:25.819  1210  1344 E DisplayPowerController2: updatePowerStateInternal
12-09 15:03:25.819  1210  2770 E LightsService: setLightLocked
12-09 15:03:25.819  1210  2770 E LightsService: setLightUnchecked
12-09 15:03:25.820   688   688 D android.hardware.lights-service.mediatek:  Lights setting state for id=0, color=ffffffff
12-09 15:03:25.820   688   688 D android.hardware.lights-service.mediatek:  set_light_backlight, level=255, onMS=0, offMS=0
12-09 15:03:25.820   688   688 D android.hardware.lights-service.mediatek:  write 255 to /sys/class/leds/lcd-backlight/brightness
12-09 15:03:25.820   688   688 D android.hardware.lights-service.mediatek: write 255 to /sys/class/leds/lcd-backlight/brightness, result: 0
12-09 15:03:25.821  1210  2770 E DisplayPowerState: postScreenUpdateThreadSafe
12-09 15:03:25.823  1071  1071 I (3)[1071:AALMain]mtk_leds backlight_debug_log(119): [BL] Set Backlight directly T:1413.809,L:255 map:255
12-09 15:03:25.834  1071  1071 I (3)[1071:AALMain][PWM] disp_pwm_set_backlight_cmdq: (id = 0x1, level_1024 = 787), old = 0
12-09 15:03:25.834  1071  1071 I (3)[1071:AALMain][PWM] disp_pwm_backlight_status: backlight is on (1), power:(1), pwm id: (0)
12-09 15:03:25.829  1000  1071 D AAL     : onBacklightChanged: 0/1023 -> 1023/1023(phy:4095/4095)
12-09 15:03:25.830  1000  1071 D AAL     : onBacklightChanged: change screen state 0(Off) -> 3(On)
 

你可能感兴趣的:(framework,android)