Android O 8.0 电源键亮屏分析

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

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

首先, 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 触发底层亮屏

    原文作者:CocoDoll
    原文地址: https://www.jianshu.com/p/295addaad5d7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞