美文网首页
Android O 8.0 电源键亮屏分析

Android O 8.0 电源键亮屏分析

作者: CocoDoll | 来源:发表于2018-06-14 16:15 被阅读1007次

    我们按下电源键就会灭屏,再按一下就会唤醒屏幕,这个是怎样的过程呢。

    电源键有许多额外功能,为了能让这个主题更加清晰,额外代码尽量不去分析,另外这篇文章主要是跟踪代码,所以也会贴出更全的源码,帮助分析

    首先, PhoneWindowManager.java 会有对Power按键的拦截:

                case KeyEvent.KEYCODE_POWER: {

                    // Any activity on the power button stops the accessibility shortcut

                    cancelPendingAccessibilityShortcutAction();

                    result &= ~ACTION_PASS_TO_USER;

                    isWakeKey = false; // wake-up will be handled separately

                    //按下亮屏,抬起灭屏 我们同样可以在自己的手机上得到这种结果

                    if (down) {//按下亮屏

                        interceptPowerKeyDown(event, interactive);

                    } else {//抬起灭屏

                        interceptPowerKeyUp(event, interactive, canceled);

                    }

                    break;

                }

    那看起来,主要逻辑就是 interceptPowerKeyDown 与 interceptPowerKeyUp了。

    interceptPowerKeyDown 按下过程:

    ....

            if (!mPowerKeyHandled) {//当按键没有被处理

                if (interactive) {//交互活动状态

                    // When interactive, we're already awake.

                    // Wait for a long press or for the button to be released to decide what to do.

                    if (hasLongPressOnPowerBehavior()) {

                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

                        msg.setAsynchronous(true);

                        mHandler.sendMessageDelayed(msg,

                                ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());

                    }

                } else {

      //这个方法,可以放在其他按键的down事件中,也可以起到唤醒屏幕的作用

      //当然也可以用PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK 结合亮屏

                    wakeUpFromPowerKey(event.getDownTime()); //关键点:唤醒

    //长按

                    if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {

                        Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);

                        msg.setAsynchronous(true);

                        mHandler.sendMessageDelayed(msg,

                                ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());

                        mBeganFromNonInteractive = true;

                    } else { //多次按

                        final int maxCount = getMaxMultiPressPowerCount();

                        if (maxCount <= 1) {

                            mPowerKeyHandled = true;

                        } else {

                            mBeganFromNonInteractive = true;

                        }

                    }

                }

            }

    ..........

    我们看到了wakeUpFromPowerKey 这个方法是唤醒动作

    private void wakeUpFromPowerKey(long eventTime) {

            wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");

     }

    再继续

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {

            final boolean theaterModeEnabled = isTheaterModeEnabled();

            if (!wakeInTheaterMode && theaterModeEnabled) {

                return false;

            }

            if (theaterModeEnabled) {

                Settings.Global.putInt(mContext.getContentResolver(),

                        Settings.Global.THEATER_MODE_ON, 0);

            }

            mPowerManager.wakeUp(wakeTime, reason);//关键点

            return true;

        }

    这个 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

    继续跟进到 PowerManager.java  里面的方法大都是 PowerManagerService的实现

    public void wakeUp(long time) {

            try {

                mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());

            } catch (RemoteException e) {

                throw e.rethrowFromSystemServer();

            }

        }

    PowerManagerService

    @Override // Binder call

            public void wakeUp(long eventTime, String reason, String opPackageName) {

                if (eventTime > SystemClock.uptimeMillis()) {

                    throw new IllegalArgumentException("event time must not be in the future");

                }

        //检查调用者是否有DEVICE_POWER 权限  Not for use by third-party applications.

                mContext.enforceCallingOrSelfPermission(

                        android.Manifest.permission.DEVICE_POWER, null);

                final int uid = Binder.getCallingUid();

                final long ident = Binder.clearCallingIdentity();

                try {

                    wakeUpInternal(eventTime, reason, uid, opPackageName, uid); //关键点

                } finally {

                    Binder.restoreCallingIdentity(ident);

                }

            }

        private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,

                int opUid) {

            synchronized (mLock) {

                if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {// 通知消息

                    updatePowerStateLocked(); //更新电池状态

                }

            }

        }

        private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,

                String opPackageName, int opUid) {

    .....

            setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);

            return true;

        }

        @VisibleForTesting

        void setWakefulnessLocked(int wakefulness, int reason) {

            if (mWakefulness != wakefulness) {

        .....

                if (mNotifier != null) { //wakefulness = WAKEFULNESS_AWAKE

                    mNotifier.onWakefulnessChangeStarted(wakefulness, reason);//通知状态改变

                }

            }

        }

    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) {

            final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);

            // 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);// 更新awake状态

                }

            });

            if (mInteractive != interactive) {

                // Finish up late behaviors if needed.

                if (mInteractiveChanging) {//更改为true才会继续[2]

                    handleLateInteractiveChange(); // 唤醒后更新唤醒状态信息

                }

            ......

        mInteractiveChanging = true; // 这一步先执行了 handleLateInteractiveChange 才会执行[1]

                handleEarlyInteractiveChange();//开始唤醒

            }

        }

        /**

        * Handle early interactive state changes such as getting applications or the lock

        * screen running and ready for the user to see (such as when turning on the screen).

        */

        private void handleEarlyInteractiveChange() {

            synchronized (mLock) {

                if (mInteractive) {

                    // Waking up...

                    mHandler.post(new Runnable() {

                        @Override

                        public void run() {

                            // Note a SCREEN tron event is logged in PowerManagerService.

    //mPolicy 是 WindowManagerPolicy 而PhoneWindowManager 是其实现

                            mPolicy.startedWakingUp(); //我们的跟踪点

                        }

                    });

                    // Send interactive broadcast.

                    mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;

                    mPendingWakeUpBroadcast = true;

                    updatePendingBroadcastLocked();

                } else { //这部分代码包含了 go to sleep的过程也可以看看

                    // Going to sleep...

                    // Tell the policy that we started going to sleep.

                    final int why = translateOffReason(mInteractiveChangeReason);

                    mHandler.post(new Runnable() {

                        @Override

                        public void run() {

                            mPolicy.startedGoingToSleep(why);

                        }

                    });

                }

            }

        }

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

    // Called on the PowerManager's Notifier thread.

        @Override

        public void startedWakingUp() { //唤醒屏幕

            EventLog.writeEvent(70000, 1);

            if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");

            // Since goToSleep performs these functions synchronously, we must

            // do the same here.  We cannot post this work to a handler because

            // that might cause it to become reordered with respect to what

            // may happen in a future call to goToSleep.

            synchronized (mLock) {

                mAwake = true;

                updateWakeGestureListenerLp(); //根据awake状态 处理手势sensor监听

                updateOrientationListenerLp(); //根据awake状态 处理 OrientationSensor 监听

                updateLockScreenTimeout(); //锁屏处理

            }

            if (mKeyguardDelegate != null) {

                mKeyguardDelegate.onStartedWakingUp(); //状态栏变化 以及相关唤醒相关回调

            }

        }

    我们再回到 PMS的wakeUpInternal

    if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {// 上面跟踪完了

                    updatePowerStateLocked(); //再从这里开始

    }

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

    /**

        * Updates the global power state based on dirty bits recorded in mDirty.

        *

        * This is the main function that performs power state transitions.

        * We centralize them here so that we can recompute the power state completely

        * each time something important changes, and ensure that we do it the same

        * way each time.  The point is to gather all of the transition logic here.

        */

        protected void updatePowerStateLocked() {

            if (!mSystemReady || mDirty == 0) {

                return;

            }

            if (!Thread.holdsLock(mLock)) {

                Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");

            }

            Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");

            try {

                // Phase 0: Basic state updates.

                updateIsPoweredLocked(mDirty);//更新电池基本信息:是否充电,插入,电量

                updateStayOnLocked(mDirty); //更新mDirty

                updateScreenBrightnessBoostLocked(mDirty);//更新屏幕亮度以及发送通知。

                // Phase 1: Update wakefulness.

                // Loop because the wake lock and user activity computations are influenced

                // by changes in wakefulness.

                final long now = SystemClock.uptimeMillis();

                int dirtyPhase2 = 0;

                for (;;) {

                    int dirtyPhase1 = mDirty;

                    dirtyPhase2 |= dirtyPhase1;

                    mDirty = 0;

    //通过PowerManager.WAKE_LOCK_LEVEL_MASK 这个Mask 更新mWakeLockSummary的值,

    //后面会根据这个值影响display显示

                    updateWakeLockSummaryLocked(dirtyPhase1);

    // Updates the value of mUserActivitySummary to summarize the user requested

    // state of the system such as whether the screen should be bright or dim.

    // Note that user activity is ignored when the system is asleep.

                    updateUserActivitySummaryLocked(now, dirtyPhase1);

                    if (!updateWakefulnessLocked(dirtyPhase1)) {

                        break;

                    }

                }

                // Phase 2: Update display power state.

                boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//更新屏幕显示亮屏

                // Phase 3: Update dream state (depends on display ready signal).

                updateDreamLocked(dirtyPhase2, displayBecameReady);

                // Phase 4: Send notifications, if needed.

                finishWakefulnessChangeIfNeededLocked();// 关键点:发送唤醒通知

                // Phase 5: Update suspend blocker.

                // Because we might release the last suspend blocker here, we need to make sure

                // we finished everything else first!

                updateSuspendBlockerLocked(); //激活hal层 以及cpu

            } finally {

                Trace.traceEnd(Trace.TRACE_TAG_POWER);

            }

        }

        /**

        * Updates the display power state asynchronously.

        * When the update is finished, mDisplayReady will be set to true.  The display

        * controller posts a message to tell us when the actual display power state

        * has been updated so we come back here to double-check and finish up.

        *

        * This function recalculates the display power state each time.

        *

        * @return True if the display became ready.

        */

        private boolean updateDisplayPowerStateLocked(int dirty) {

                mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); //更新亮屏policy为POLICY_BRIGHT

          .........

                mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,

                        mRequestWaitForNegativeProximity);//跳转到DisplayManagerService 显示的一些逻辑处理

        }

        int getDesiredScreenPolicyLocked() {

    .......

            if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0

                    || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0

                    || !mBootCompleted

                    || mScreenBrightnessBoostInProgress) {

                return DisplayPowerRequest.POLICY_BRIGHT; //更新policy

            }

    .......

        }

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

    @Override

            public boolean requestPowerState(DisplayPowerRequest request,

                    boolean waitForNegativeProximity) {

                return mDisplayPowerController.requestPowerState(request,

                        waitForNegativeProximity);//DisplayPowerController

            }

    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 && !mPendingRequestChangedLocked) {

                    mPendingRequestChangedLocked = true;

                    sendUpdatePowerStateLocked(); //实际上就是个handler发送消息处理

                }

    ......

        }

        private void sendUpdatePowerStateLocked() {

            if (!mPendingUpdatePowerStateLocked) {

                mPendingUpdatePowerStateLocked = true;

                Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);

                msg.setAsynchronous(true);

                mHandler.sendMessage(msg);

            }

        }

        .....

                    case MSG_UPDATE_POWER_STATE:

                        updatePowerState();

                        break;

        .....

    private void updatePowerState() {

    //这个方法太长就不贴了 其中包括更新Proximity sensor信息

    //重置动画信息, 更新屏幕状态  state = Display.STATE_OFF/STATE_ON 等等

    //还有一些对autoBrightness, lowPowerMode的处理, 还有屏幕亮度变化的动画过程

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

    }

        //这个方法主要跟踪setScreenState 屏幕状态变化

        private void animateScreenStateChange(int target, boolean performScreenOffTransition) {

    ......

            if (mDisplayBlanksAfterDozeConfig

                    && Display.isDozeState(mPowerState.getScreenState())

                    && !Display.isDozeState(target)) {

                // Some display hardware will blank itself on the transition between doze and non-doze

                // but still on display states. In this case we want to report to policy that the

                // display has turned off so it can prepare the appropriate power on animation, but we

                // don't want to actually transition to the fully off state since that takes

                // significantly longer to transition from.

                setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);

            }

            // If we were in the process of turning off the screen but didn't quite

            // finish.  Then finish up now to prevent a jarring transition back

            // to screen on if we skipped blocking screen on as usual.

            if (mPendingScreenOff && target != Display.STATE_OFF) {

                setScreenState(Display.STATE_OFF);

                mPendingScreenOff = false;

                mPowerState.dismissColorFadeResources();

            }

            if (target == Display.STATE_ON) {

                // Want screen on.  The contents of the screen may not yet

                // be visible if the color fade has not been dismissed because

                // its last frame of animation is solid black.

                if (!setScreenState(Display.STATE_ON)) {

                    return; // screen on blocked

                }

    .........

        }

        private boolean setScreenState(int state) {

            return setScreenState(state, false /*reportOnly*/);

        }

        private boolean setScreenState(int state, boolean reportOnly) {

    ..........

                if (!reportOnly) {

                    mPowerState.setScreenState(state); // DisplayPowerState.setScreenState 状态变化的通知【1】

                    // Tell battery stats about the transition.

                    try {

                        mBatteryStats.noteScreenState(state); //电池状态信息变化

                    } catch (RemoteException ex) {

                        // same process

                    }

                }

    ............

    //PoneWindowManager的实现【2】

    mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);

     }

    我们先把比较短的【2】走完

    public class PhoneWindowManager implements WindowManagerPolicy

      .....

        // Called on the DisplayManager's DisplayPowerController thread.

        @Override

        public void screenTurningOn(final ScreenOnListener screenOnListener) {

            if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");

            updateScreenOffSleepToken(false);

            synchronized (mLock) {

                mScreenOnEarly = true;

                mScreenOnFully = false;

                mKeyguardDrawComplete = false;

                mWindowManagerDrawComplete = false;

                mScreenOnListener = screenOnListener;

                if (mKeyguardDelegate != null) {

                    mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);

                    mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,

                            getKeyguardDrawnTimeout()); //调用finishKeyguardDrawn(); 完成绘制

    //锁屏逻辑处理

    //KeyguardServiceDelegate-> KeyguardService -> KeyguardViewMediator -> StatusBarKeyguardViewManager

                    mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);

                } else {

                    if (DEBUG_WAKEUP) Slog.d(TAG,

                            "null mKeyguardDelegate: setting mKeyguardDrawComplete.");

                    finishKeyguardDrawn(); //如果mKeyguardDelegate null 仍然会走到这里

                }

            }

        }

        private void finishKeyguardDrawn() {

            // ... eventually calls finishWindowsDrawn which will finalize our screen turn on

            // as well as enabling the orientation change logic/sensor.

            mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,

                    WAITING_FOR_DRAWN_TIMEOUT); //主要这个消息的处理

        }

        final Runnable mWindowManagerDrawCallback = new Runnable() {

            @Override

            public void run() {

                if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");

                mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);

            }

        };

    case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:

    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");

    finishWindowsDrawn();

    break;

        private void finishWindowsDrawn() {

            synchronized (mLock) {

                if (!mScreenOnEarly || mWindowManagerDrawComplete) {

                    return; // Screen is not turned on or we did already handle this case earlier.

                }

                mWindowManagerDrawComplete = true;

            }

            finishScreenTurningOn();

        }

        private void finishScreenTurningOn() {

            final ScreenOnListener listener;

            final boolean enableScreen;

    .....

            if (listener != null) {

                listener.onScreenOn(); //回调

            }

            if (enableScreen) {

                try {

                    mWindowManager.enableScreenIfNeeded();

                } catch (RemoteException unhandled) {

                }

            }

        }

    WindowManagerService

    @Override

        public void enableScreenIfNeeded() {

            synchronized (mWindowMap) {

                enableScreenIfNeededLocked();

            }

        }

        void enableScreenIfNeededLocked() {

            if (mDisplayEnabled) {

                return;

            }

            if (!mSystemBooted && !mShowingBootMessages) {

                return;

            }

            mH.sendEmptyMessage(H.ENABLE_SCREEN);

        }

            case ENABLE_SCREEN: {

                performEnableScreen(); // 开机启动也会走到这个方法,这里包括surfaceFlinger 渲染 mInputMonitor派发,并且调用AMS的bootAnimationComplete处理

                break;

            }

    【1】我们再来看看电亮屏幕的过程

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

    /**

        * Sets whether the screen is on, off, or dozing.

        */

        public void setScreenState(int state) {

            if (mScreenState != state) {

                if (DEBUG) {

                    Slog.d(TAG, "setScreenState: state=" + state);

                }

                mScreenState = state;

                mScreenReady = false;

                scheduleScreenUpdate();//通过handler另起一个线程处理

            }

        }

        private void scheduleScreenUpdate() {

            if (!mScreenUpdatePending) {

                mScreenUpdatePending = true;

                postScreenUpdateThreadSafe();

            }

        }

        private void postScreenUpdateThreadSafe() {

            mHandler.removeCallbacks(mScreenUpdateRunnable);

            mHandler.post(mScreenUpdateRunnable);

        }

        private final Runnable mScreenUpdateRunnable = new Runnable() {

            @Override

            public void run() {

                mScreenUpdatePending = false;

                int brightness = mScreenState != Display.STATE_OFF

                        && mColorFadeLevel > 0f ? mScreenBrightness : 0;

        //关键点, 通过mPhotonicModulator 更新状态

                if (mPhotonicModulator.setState(mScreenState, brightness)) {

                    if (DEBUG) {

                        Slog.d(TAG, "Screen ready");

                    }

                    mScreenReady = true;

                    invokeCleanListenerIfNeeded();

                } else {

                    if (DEBUG) {

                        Slog.d(TAG, "Screen not ready");

                    }

                }

            }

        };

    //通过PhotonicModulator是个线程并且是DisplayPowerState的子类,这里主要更新状态的处理

            public boolean setState(int state, int backlight) {

                synchronized (mLock) {

                    boolean stateChanged = state != mPendingState;

                    boolean backlightChanged = backlight != mPendingBacklight;

                    if (stateChanged || backlightChanged) {

                        if (DEBUG) {

                            Slog.d(TAG, "Requesting new screen state: state="

                                    + Display.stateToString(state) + ", backlight=" + backlight);

                        }

                        mPendingState = state;

                        mPendingBacklight = backlight;//我们找到了背光,这个在哪里用呢?

                        boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;

                        mStateChangeInProgress = stateChanged || mStateChangeInProgress;

                        mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;

                        if (!changeInProgress) {

                            mLock.notifyAll();

                        }

                    }

                    return !mStateChangeInProgress;

                }

            }

    //再来看看DisplayPowerState 的构造函数, 原来PhotonicModulator在初始化的时候就一直在后台运行,

     //只要setState状态变化,就会触发一些机制

     public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {

    mHandler = new Handler(true /*async*/);

    mChoreographer = Choreographer.getInstance();

    mBlanker = blanker;

    mColorFade = colorFade;

    mPhotonicModulator = new PhotonicModulator();

    mPhotonicModulator.start();//跑起来了

      }

        //我们再看看 PhotonicModulator 这个线程的run方法

            @Override

            public void run() {

                for (;;) {

                    // Get pending change.

                    final int state;

                    final boolean stateChanged;

                    final int backlight;

                    final boolean backlightChanged;

                    synchronized (mLock) {

                        state = mPendingState;

                        stateChanged = (state != mActualState);

                        backlight = mPendingBacklight; //用到了刚才的背光

                        backlightChanged = (backlight != mActualBacklight);

                        if (!stateChanged) {

                            // State changed applied, notify outer class.

                            postScreenUpdateThreadSafe();

                            mStateChangeInProgress = false;

                        }

                        if (!backlightChanged) {

                            mBacklightChangeInProgress = false;

                        }

                        if (!stateChanged && !backlightChanged) {

                            try {

                                mLock.wait();

                            } catch (InterruptedException ex) { }

                            continue;

                        }

                        mActualState = state;

                        mActualBacklight = backlight;

                    }

                    // Apply pending change.

                    if (DEBUG) {

                        Slog.d(TAG, "Updating screen state: state="

                                + Display.stateToString(state) + ", backlight=" + backlight);

                    }

                   //DisplayBlanker是个接口 在DisplayManagerService的 子类LocalService 会有它的实现

                    mBlanker.requestDisplayState(state, backlight);//关键步骤 继续走下去

                }

            }

    LocalService 的实现:

    private final class LocalService extends DisplayManagerInternal {

            @Override

            public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,

                    SensorManager sensorManager) {

                synchronized (mSyncRoot) {

                    DisplayBlanker blanker = new DisplayBlanker() {

                        @Override

                        public void requestDisplayState(int state, int brightness) {

                            // The order of operations is important for legacy reasons.

                            if (state == Display.STATE_OFF) {

                                requestGlobalDisplayStateInternal(state, brightness);

                            }

                            callbacks.onDisplayStateChange(state);

                            if (state != Display.STATE_OFF) {

                                requestGlobalDisplayStateInternal(state, brightness);

                            }

                        }

                    };

                    mDisplayPowerController = new DisplayPowerController(

                            mContext, callbacks, handler, sensorManager, blanker);

                }

            }

    .............

      }

    private void requestGlobalDisplayStateInternal(int state, int brightness) {

            if (state == Display.STATE_UNKNOWN) {

                state = Display.STATE_ON;

            }

            if (state == Display.STATE_OFF) {

                brightness = PowerManager.BRIGHTNESS_OFF;

            } else if (brightness < 0) {

                brightness = PowerManager.BRIGHTNESS_DEFAULT;

            } else if (brightness > PowerManager.BRIGHTNESS_ON) {

                brightness = PowerManager.BRIGHTNESS_ON;

            }

            synchronized (mTempDisplayStateWorkQueue) {

    ......

                    synchronized (mSyncRoot) {

                        if (mGlobalDisplayState == state

                                && mGlobalDisplayBrightness == brightness) {

                            return; // no change

                        }

                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("

                                + Display.stateToString(state)

                                + ", brightness=" + brightness + ")");

                        mGlobalDisplayState = state;

                        mGlobalDisplayBrightness = brightness;

                        applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);//继续跟踪

                    }

                    ........

        }

    private void applyGlobalDisplayStateLocked(List workQueue) {

            final int count = mDisplayDevices.size();

            for (int i = 0; i < count; i++) {

                DisplayDevice device = mDisplayDevices.get(i);

                Runnable runnable = updateDisplayStateLocked(device);

                if (runnable != null) {

                    workQueue.add(runnable); //队列处理

                }

            }

        }

    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) {

        //DisplayDevice 是一个接口他的实现在LocalDisplayAdapter的子类LocalDisplayDevice中

                return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);

            }

            return null;

        }

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

    //这部分代码很多 主要是亮度的状态的处理 还包括vr的一些逻辑 我们看主要的

    @Override

            public Runnable requestDisplayStateLocked(final int state, final int brightness) {

      // Defer actually setting the display state until after we have exited

                    // the critical section since it can take hundreds of milliseconds

                    // to complete.

                    return new Runnable() {

                        @Override

                        public void run() {

                            // Apply brightness changes given that we are in a non-suspended state.

                            if (brightnessChanged || vrModeChange) {

                                setDisplayBrightness(brightness);//主要跟踪逻辑

                            }

                            // Enter the final desired state, possibly suspended.

                            if (state != currentState) {

                                setDisplayState(state);

                            }

                        }

                        private void setDisplayBrightness(int brightness) {

                            try {

                                mBacklight.setBrightness(brightness); //就是这里了

                                Trace.traceCounter(Trace.TRACE_TAG_POWER,

                                        "ScreenBrightness", brightness);

                            } finally {

                                Trace.traceEnd(Trace.TRACE_TAG_POWER);

                            }

                        }

                    };

                }

                return null;

            }

    LocalDisplayAdapter.java

    构造函数中初始化了  mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);

    并且在 requestDisplayStateLocked(); 中调用  mBacklight.setBrightness(brightness);

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

    找到setBrightness的实现:

    @Override

            public void setBrightness(int brightness) {

                setBrightness(brightness, BRIGHTNESS_MODE_USER);

            }

            @Override

            public void setBrightness(int brightness, int brightnessMode) {

                synchronized (this) {

    ........

                    int color = brightness & 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) {

                  ..........

                    Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"

                            + Integer.toHexString(color) + ")");

                    try {

                        setLight_native(mId, color, mode, onMS, offMS, brightnessMode);

                    } finally {

                        Trace.traceEnd(Trace.TRACE_TAG_POWER);

                    }

                }

            }

    最终是调用native方法 setLight_native

    继续跟踪到JNI

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

    static void setLight_native(

            JNIEnv* /* env */,

            jobject /* clazz */,

            jint light,

            jint colorARGB,

            jint flashMode,

            jint onMS,

            jint offMS,

            jint brightnessMode) {

    sp hal = LightHal::associate();

    Type type = static_cast(light);

    LightState state = constructState(

            colorARGB, flashMode, onMS, offMS, brightnessMode);

    {

           //通过LightHal调用setLight

           android::base::Timer t; Return ret = hal->setLight(type, state);

            processReturn(ret, type, state);

        }

    }

    继续往下,我们跟到了hardware

    hardware/interfaces/light/2.0/default/Light.cpp

    Light::Light(std::map &&lights)

      : mLights(std::move(lights)) {}

    // Methods from ::android::hardware::light::V2_0::ILight follow.Return Light::setLight(Type type, const LightState& state) {

        auto it = mLights.find(type);

        ...

        light_device_t* hwLight = it->second;

        ....

        int ret = hwLight->set_light(hwLight, &legacyState);

    }

    set_light 是调用的关键函数, 跟踪调用路径 hwLight -> it->second -> mLights 发现是一个集合,找到赋值点

    通过HIDL new出集合中的对象

    ILight* HIDL_FETCH_ILight(const char* /* name */) { std::map lights;

        for(auto const &pair : kLogicalLights) {

            Type type = pair.first;

            const char* name = pair.second;

            light_device_t* light = getLightDevice(name);

        }

        ....

        return new Light(std::move(lights));

    }

    集合:

    const static std::map kLogicalLights = {

        {Type::BACKLIGHT,    LIGHT_ID_BACKLIGHT},

        {Type::KEYBOARD,      LIGHT_ID_KEYBOARD},

        {Type::BUTTONS,      LIGHT_ID_BUTTONS},

        {Type::BATTERY,      LIGHT_ID_BATTERY},

        {Type::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS},

        {Type::ATTENTION,    LIGHT_ID_ATTENTION},

        {Type::BLUETOOTH,    LIGHT_ID_BLUETOOTH},

        {Type::WIFI,          LIGHT_ID_WIFI}

    };

    LIGHT_ID_BACKLIGHT在hardware/libhardware/include/hardware/lights.h 有声明

    #define LIGHT_ID_BACKLIGHT "backlight"

    继续跟踪LIGHT_ID_BACKLIGHT

    在hardware/qcom/display/liblight/lights.c 我们发现

    /** Open a new instance of a lights device using name */

    static int open_lights(const struct hw_module_t* module, char const* name,

            struct hw_device_t** device)

    {

        // 设置对应name的led节点

        if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {

    .......

                set_light = set_light_backlight;

        } else if (0 == strcmp(LIGHT_ID_BATTERY, name))

            set_light = set_light_battery;

        else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))

            set_light = set_light_notifications;

        else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {

    .......

        dev->set_light = set_light;

        return 0;

    }

    static int set_light_backlight(struct light_device_t* dev,

            struct light_state_t const* state)

    {

        ...

        g_last_backlight_mode = state->brightnessMode;

        if (!err) {

            if (!access(LCD_FILE, F_OK)) {

                err = write_int(LCD_FILE, brightness);//背光节点

            } else {

                err = write_int(LCD_FILE2, brightness);

            }

        }

        ...........

        pthread_mutex_unlock(&g_lock);

        return err;

    }

    char const*const LCD_FILE

            = "/sys/class/leds/lcd-backlight/brightness";//最终作用的节点

    char const*const LCD_FILE2

            = "/sys/class/backlight/panel0-backlight/brightness";

    char const*const BUTTON_FILE

            = "/sys/class/leds/button-backlight/brightness";

    char const*const PERSISTENCE_FILE

            = "/sys/class/graphics/fb0/msm_fb_persist_mode";

    代码还是比较枯燥的,很难沉下心分析,但是还是有收获。

    总结:

          1. PhonewindowManger 对按键的拦截,以及后续对startedWakingUp的调用

          2. PowerManagerService 对电池状态的更新和消息通知

          3. DisplayPowerController与DisplayManagerService 对显示的逻辑处理

          4. LightsService通过jni 触发底层亮屏

    相关文章

      网友评论

          本文标题:Android O 8.0 电源键亮屏分析

          本文链接:https://www.haomeiwen.com/subject/dbyyeftx.html