绪论
可以导致手机亮灭屏的因素有多种,而在本文中主要讲解按power键亮灭屏过程以及来电亮屏。在亮灭屏过程power中主要的实现类与功能如下所述:
PowerManagerService.java:以下简称PMS或者PowerMS,主要处理系统中与power相关的计算,然后决策系统该如何反应。同时协调power如何与系统其他模块的交互,比如没有用户活动时屏幕变暗等。
DisplayPowerController.java:以下简称DPC或者DisplayPC,管理display设备状态,在DisplayManagerService.java(简称DMS)中实例化一个对象,以DMS为桥梁与PMS进行交互。主要处理距离传感器,亮灭屏动画,以及计算屏幕目标亮度值。通过异步回调机制来通知PMS那些事情发生了改变。同时也与WMS进行交互。
DisplayPowerState.java:以下简称DPS,power通过其与系统进行交互,如调用其它模块设置屏幕状态与亮度。仅在DPC中实例化一个对象,它算是DPC的一部分只不过将其独立出来了。
Notifier.java:将power状态的重要变化,通过广播发送出去,并且参与了与AMS,WMS,IMP的交互。
ColorFade.java:负责屏幕由关到开,由开到关的一些GL动画,由DPC进行控制。
AutomaticBrightnessController.java:主要处理光传感器,将底层上传的参数进行处理计算,将计算的新的亮度值传给DPC。
RampAnimator.java:处理屏幕亮度渐变动画。
亮屏总览
在点击power键亮屏过程中,主要流程就是input对按键事件的传输,传送到上层处理。之后就是在power中进行对亮屏状态的处理,计算一系列的数值,并且与AMS,WMS等模块进行交互,最后调用底层LCD进行最终的设备状态与亮度的设置。在下面将会对各流程详细讲解。
Input传输Power键
当触发power键,kernel会将该事件中断,然后InputReader通过EventHub获取事件,并且对输入事件进行处理,之后交由InputDispatcher进行分发。如果该事件为key事件会先调用interceptKeyBeforeQueueing,提前对需要系统处理的事件进行处理。最终调到PhoneWindowManager类中的interceptKeyBeforeQueueing函数对该事件优先处理,对power键以及屏幕状态进行判断,来决定亮屏还是灭屏等操作。当需要亮屏时,会调用PowerMangerService中的wakeup函数进行处理。
从底层到上层的具体代码调用流程 InputReader.cpp->InputDispatcher.cpp->com_android_server_input_InputManagerService.cpp->InputManagerService.java->InputMonitor.java->WindowManagerPolicy.java->PhoneWindowManager.java最终来到java层处理按键事件.
- public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
- if (!mSystemBooted) { //系统还没有启动完成,不处理任何按键事件
- // If we have not yet booted, don't let key events do anything.
- return 0;
- }
- final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; //是否能与用户交互, 如果亮屏为true
- final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; //按键down事件
- final boolean canceled = event.isCanceled(); //事件被取消
- final int keyCode = event.getKeyCode(); //按键事件的code
- final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
- // Basic policy based on interactive state.
- int result;
- boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
- || event.isWakeKey(); //flags有wake标记,或者按键为KEYCODE_BACK, KEYCODE_MENU, KEYCODE_WAKEUP, KEYCODE_PAIRING, KEYCODE_STEM_1, KEYCODE_STEM_2, KEYCODE_STEM_3设置isWakeKey为true. power ,home键属于systemKey
- // If the key would be handled globally, just return the result, don't worry about special
- // key processing.
- if (isValidGlobalKey(keyCode)
- && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
- if (isWakeKey) { //如果按键时间有效, 并且在com.android.internal.R.xml.global_keys文件中配置了keycode. 如果是唤醒键就调用wakeUp唤醒屏幕
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
- }
- return result;
- }
- // Handle special keys. //处理特殊的按键事件 ,这里主要讲解power键事件
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK: //back键
- case KeyEvent.KEYCODE_VOLUME_DOWN: //音量下键
- case KeyEvent.KEYCODE_VOLUME_UP: //音量上键
- case KeyEvent.KEYCODE_VOLUME_MUTE: //静音键
- case KeyEvent.KEYCODE_ENDCALL: //挂断电话键
- case KeyEvent.KEYCODE_POWER: { //电源键
- result &= ~ACTION_PASS_TO_USER;
- isWakeKey = false; // wake-up will be handled separately
- if (down) { //power按下事件
- interceptPowerKeyDown(event, interactive); //处理power下键
- } else { //power键松开
- interceptPowerKeyUp(event, interactive, canceled); //处理power上键
- }
- break;
- }
- case KeyEvent.KEYCODE_SLEEP:
- case KeyEvent.KEYCODE_SOFT_SLEEP:
- case KeyEvent.KEYCODE_WAKEUP:
- 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:
- case KeyEvent.KEYCODE_CALL:
- case KeyEvent.KEYCODE_VOICE_ASSIST:
- case KeyEvent.KEYCODE_WINDOW:
- }
- }
- if (isWakeKey) { //如果除了power键, 别的按键也需要亮屏,就调用WakeUp亮屏
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
- }
- return result;
- }
- private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
- // Hold a wake lock until the power key is released.
- if (!mPowerKeyWakeLock.isHeld()) {
- mPowerKeyWakeLock.acquire(); //获取wakeLock,保持cpu唤醒状态
- }
- // Latch power key state to detect screenshot chord.
- if (interactive && !mScreenshotChordPowerKeyTriggered
- && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- mScreenshotChordPowerKeyTriggered = true;
- mScreenshotChordPowerKeyTime = event.getDownTime();
- interceptScreenshotChord(); //屏幕截屏
- }
- // Stop ringing or end call if configured to do so when power is pressed.
- TelecomManager telecomManager = getTelecommService(); //获取telecom
- boolean hungUp = false;
- if (telecomManager != null) {
- if (telecomManager.isRinging()) { //如果来电过程中,按power键手机将静音,停止响铃
- // 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(); //如果在Setting数据库中配置了,按power键挂断电话, 就将电话挂断
- }
- }
- //................
- // If the power key has still not yet been handled, then detect short
- // press, long press, or multi press and decide what to do. //如果power键还没有被处理,就判断是短按, 长按,还是多按来决定如何处理
- mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
- || mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
- 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()) { //如果屏幕是亮这的,长按power键 ,就处理长按事件
- Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg,
- ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
- }
- } else {
- wakeUpFromPowerKey(event.getDownTime()); //如果屏幕是休眠状态,就唤醒屏幕
- if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
- Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, //如果还是长按power键, 就再处理长按事件
- ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
- mBeganFromNonInteractive = true;
- } else {
- final int maxCount = getMaxMultiPressPowerCount();
- if (maxCount <= 1) {
- mPowerKeyHandled = true;
- } else {
- mBeganFromNonInteractive = true;
- }
- }
- }
- }
- }
- private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
- final boolean handled = canceled || mPowerKeyHandled;
- mScreenshotChordPowerKeyTriggered = false;
- cancelPendingScreenshotChordAction();
- cancelPendingPowerKeyAction();
- if (!handled) { //power键还没被处理
- // Figure out how to handle the key now that it has been released.
- mPowerKeyPressCounter += 1;
- final int maxCount = getMaxMultiPressPowerCount(); //多按的次数
- final long eventTime = event.getDownTime(); //按键发生的时间点
- if (mPowerKeyPressCounter < maxCount) {
- // This could be a multi-press. Wait a little bit longer to confirm.
- // Continue holding the wake lock. //等待一会调用powerPress处理
- Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
- interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
- return;
- }
- // No other actions. Handle it immediately.
- powerPress(eventTime, interactive, mPowerKeyPressCounter); //没有的的处理, 立即处理power down事件
- }
- // Done. Reset our state.
- finishPowerKeyPress(); //power键处理结束
- }
- private void finishPowerKeyPress() {
- mBeganFromNonInteractive = false;
- mPowerKeyPressCounter = 0;
- if (mPowerKeyWakeLock.isHeld()) {
- mPowerKeyWakeLock.release(); //释放wakLock
- }
- }
- private void powerPress(long eventTime, boolean interactive, int count) {
- if (mScreenOnEarly && !mScreenOnFully) {
- Slog.i(TAG, "Suppressed redundant power key press while "
- + "already in the process of turning the screen on.");
- return;
- }
- if (count == 2) {
- powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior); //处理按两次power键事件
- } else if (count == 3) {
- powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior); //处理按三次power键事件
- } else if (interactive && !mBeganFromNonInteractive) {
- switch (mShortPressOnPowerBehavior) {
- case SHORT_PRESS_POWER_NOTHING:
- break;
- case SHORT_PRESS_POWER_GO_TO_SLEEP: //灭屏
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: //灭屏,不经历doze流程
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
- mPowerManager.goToSleep(eventTime, //灭屏,不经历doze流程, 并返回home界面
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- launchHomeFromHotKey();
- break;
- case SHORT_PRESS_POWER_GO_HOME: //返回home界面
- launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
- break;
- }
- }
- }
- 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); //调用PowerManagerService唤醒屏幕
- return true;
- }
当power接收到亮灭屏调用后,会先进行设置手机wakefullness状态. 之后发送亮灭屏广播通知其他应用手机处于亮屏还是灭屏状态。
- private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
- String opPackageName, int opUid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
- }
- if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false; //判断是否要去亮屏
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
- try {
- switch (mWakefulness) {
- case WAKEFULNESS_ASLEEP:
- Slog.i(TAG, "Waking up from sleep due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DREAMING:
- Slog.i(TAG, "Waking up from dream due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DOZING:
- Slog.i(TAG, "Waking up from dozing due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- }
- mLastWakeTime = eventTime; //设置最后一次唤醒的时间
- setWakefulnessLocked(WAKEFULNESS_AWAKE, 0); //Notifier调用onWakefulnessChangeStarted发送亮屏广播
- mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid); //调用Notifier通知battery处理
- userActivityNoUpdateLocked( //更新最后一次用户事件的时间
- eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
- public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
- final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); //获取交互模式,亮屏为true, 灭屏为false
- 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); //与AMS交互处理
- }
- });
- // 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); //在input中记录现在的屏幕状态
- mInputMethodManagerInternal.setInteractive(interactive);
- // Notify battery stats.
- try {
- mBatteryStats.noteInteractive(interactive); //唤醒battery状态
- } catch (RemoteException ex) { }
- // Handle early behaviors.
- mInteractive = interactive;
- mInteractiveChangeReason = reason;
- mInteractiveChanging = true;
- handleEarlyInteractiveChange(); //初期处理交互模式改变
- }
- }
- private void handleEarlyInteractiveChange() {
- synchronized (mLock) {
- if (mInteractive) {
- // Waking up... //亮屏
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
- mPolicy.startedWakingUp(); //通过PhoneWindowManager系统开始亮屏, 更新转向监听器,手势监听器等
- }
- });
- // Send interactive broadcast.
- mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
- mPendingWakeUpBroadcast = true;
- updatePendingBroadcastLocked(); //更新亮屏广播
- } else {
- // Going to sleep... //灭屏
- // Tell the policy that we started going to sleep.
- final int why = translateOffReason(mInteractiveChangeReason);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mPolicy.startedGoingToSleep(why);
- }
- });
- }
- }
- }
- private void sendNextBroadcast() {
- final int powerState;
- synchronized (mLock) {
- if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
- // Broadcasted power state is unknown. Send wake up.
- mPendingWakeUpBroadcast = false;
- mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; //亮屏状态
- } 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;
- }
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
- if (powerState == INTERACTIVE_STATE_AWAKE) {
- sendWakeUpBroadcast(); //发送亮屏广播
- } else {
- sendGoToSleepBroadcast();
- }
- }
- mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); //亮屏广播intent
- mScreenOnIntent.addFlags( //前台广播
- Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
- private void sendWakeUpBroadcast() {
- if (DEBUG) {
- Slog.d(TAG, "Sending wake up broadcast.");
- }
- if (ActivityManagerNative.isSystemReady()) {
- mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
- mWakeUpBroadcastDone, mHandler, 0, null, null); //发送亮屏广播,并且其它模块全部处理完后, 自身接收亮屏广播
- } else {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
- sendNextBroadcast();
- }
- }
- private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
- SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
- sendNextBroadcast(); //自身接收到亮屏广播后, 之后会调用finishPendingBroadcastLocked,释放wakeLock
- }
- };
当wakefulness状态发生改变,AMS收到通知。如果亮屏操作,AMS就会通过函数comeOutOfSleepIfNeedLocked调用到ActivityStackSupervisor中,将sleep超时消息移除,如果抓的有partial锁,就将其释放,最后将在栈顶的activity显示出来。
power是通过WindowManagerPolicy与PhoneWindowManager进行交互,当屏幕在wakingup时需要通知window进行更新手势监听,更新方向监听,更新锁屏超时时间。最后通知keyguard屏幕点亮了,进行刷新锁屏界面时间,之后通过回调接口,回调回PhoneWindowManager的onShown函数,通知window keyguard准备完成。
当亮屏时通过InputManagerService将当前屏幕状态传入JNI中进行记录,当再次发生power键事件可以方便确认该事件是需要亮屏还是灭屏。
更新Power全局状态
当广播处理完毕后就会调用PMS的内部函数updatePowerStateLocked来更新全局电源状态。其实在PMS中很多函数都只是对一些必须的属性进行赋值,大部分最终都会调用到updatePowerStateLocked函数中进行功能执行,其中更新电源状态主要依据就是变量mDirty。mDirty就是用来记录power state的变化的标记位,这样的状态变化在系统中一共定义了12个,每一个状态对应一个固定的数字,都是2的倍数。这样,若有多个状态一块变化,进行按位取或这样结果既是唯一的,又能准确标记出各个状态的变化。在updatePowerStateLocked中主要做了如下事情:
一.首先判断手机是否处于充电状态,如果标记位DIRTY_BATTERY_STATE发生改变时就证明电池状态发生了改变,然后通过对比判断(通过电池前后变化与充电状态的变化),确认手机是否处于充电状态。如果手机处于充电状态会将表示充电的标记位记入mDirty中。当有USB插拔时我们也可以通过配置信息来决定是否需要点亮屏幕。并且是否在充电或者充电方式发生改变,系统都会认为发生了一次用户事件进行更新最后用户操作时间,以此来重新计算屏幕超时时间。
- private void updateIsPoweredLocked(int dirty) {
- if ((dirty & DIRTY_BATTERY_STATE) != 0) {
- final boolean wasPowered = mIsPowered; //是否在充电
- final int oldPlugType = mPlugType; //充电类型
- final boolean oldLevelLow = mBatteryLevelLow; //低电模式
- mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
- mPlugType = mBatteryManagerInternal.getPlugType();
- mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
- mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
- if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
- mDirty |= DIRTY_IS_POWERED; //如果充电中设置mDirty
- // Update wireless dock detection state.
- final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
- mIsPowered, mPlugType, mBatteryLevel); //无线充电
- // Treat plugging and unplugging the devices as a user activity.
- // Users find it disconcerting when they plug or unplug the device
- // and it shuts off right away.
- // Some devices also wake the device when plugged or unplugged because
- // they don't have a charging LED.
- final long now = SystemClock.uptimeMillis();
- if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
- dockedOnWirelessCharger)) { //插拔USB是否要点亮屏幕
- wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID,
- mContext.getOpPackageName(), Process.SYSTEM_UID);
- }
- userActivityNoUpdateLocked( //插拔USB算一次用户事件,重新设置最后一次用户事件的时间点
- now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
- // Tell the notifier whether wireless charging has started so that
- // it can provide feedback to the user.
- if (dockedOnWirelessCharger) {
- mNotifier.onWirelessChargingStarted();
- }
- }
- if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) { //低电模式
- if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateIsPoweredLocked: resetting low power snooze");
- }
- mAutoLowPowerModeSnoozing = false;
- }
- updateLowPowerModeLocked(); //更新低电模式
- }
- }
- }
- mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
- com.android.internal.R.bool.config_unplugTurnsOnScreen); //从xml文件中读取配置信息
- private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
- boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
- // Don't wake when powered unless configured to do so.
- if (!mWakeUpWhenPluggedOrUnpluggedConfig) { //如果配置为true, 可能会亮屏
- return false;
- }
- // Don't wake when undocked from wireless charger.
- // See WirelessChargerDetector for justification.
- if (wasPowered && !mIsPowered
- && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
- return false;
- }
- // Don't wake when docked on wireless charger unless we are certain of it.
- // See WirelessChargerDetector for justification.
- if (!wasPowered && mIsPowered
- && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
- && !dockedOnWirelessCharger) {
- return false;
- }
- // If already dreaming and becoming powered, then don't wake.
- if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
- return false;
- }
- // Don't wake while theater mode is enabled.
- if (mTheaterModeEnabled && !mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig) {
- return false;
- }
- // Otherwise wake up!
- return true;
- }
二:更新wakefulness
- for (;;) {
- int dirtyPhase1 = mDirty;
- dirtyPhase2 |= dirtyPhase1;
- mDirty = 0; //将mDirty清零,不影响下个循环
- updateWakeLockSummaryLocked(dirtyPhase1);
- updateUserActivitySummaryLocked(now, dirtyPhase1);
- if (!updateWakefulnessLocked(dirtyPhase1)) { //当updateWakefulnessLocked返回false跳出循环
- break;
- }
- }
updateWakeLockSummaryLocked函数将wakeLock的类型用mWakeLockSummary进行记录,最后与Wakefulness状态结合重新算出新的mWakeLockSummary值,在下面判断是否需要睡眠时会使用。
- private void updateWakeLockSummaryLocked(int dirty) {
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
- mWakeLockSummary = 0;
- final int numWakeLocks = mWakeLocks.size(); //获取所有的wakeLocks
- for (int i = 0; i < numWakeLocks; i++) { //遍历所有的wakeLocks, 将wakeLocks记录在mWakeLockSummary中
- final WakeLock wakeLock = mWakeLocks.get(i);
- switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
- case PowerManager.PARTIAL_WAKE_LOCK:
- if (!wakeLock.mDisabled) {
- // We only respect this if the wake lock is not disabled.
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- break;
- case PowerManager.FULL_WAKE_LOCK: //屏幕键盘全部点亮
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
- break;
- case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: //点亮屏幕
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
- break;
- case PowerManager.SCREEN_DIM_WAKE_LOCK: //dim锁
- mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM;
- break;
- case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: //距离灭屏
- mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- break;
- case PowerManager.DOZE_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DOZE;
- break;
- case PowerManager.DRAW_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DRAW;
- break;
- }
- }
- // Cancel wake locks that make no sense based on the current state.
- if (mWakefulness != WAKEFULNESS_DOZING) { //根据当前的屏幕状态, 取消不必要的wakeLocks
- mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
- }
- if (mWakefulness == WAKEFULNESS_ASLEEP //如果屏幕为休眠,就将屏幕高亮,dim锁取消
- || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
- mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
- | WAKE_LOCK_BUTTON_BRIGHT);
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
- mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- }
- }
- // Infer implied wake locks where necessary based on the current state.
- if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE) {
- mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE; //当WakeLock为亮屏锁或dim锁时,需要保持AWAKE状态。
- } else if (mWakefulness == WAKEFULNESS_DREAMING) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- }
- if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
- }
- }
- }
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
- | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT); //移除屏幕超时的Message
- long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- final int sleepTimeout = getSleepTimeoutLocked(); //获取睡眠超时时间
- final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); //获取屏幕超时时间
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); //获取dim持续时长
- final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
- mUserActivitySummary = 0;
- if (mLastUserActivityTime >= mLastWakeTime) { //最后一次的用户时间大于最后一次屏幕醒来的时间
- nextTimeout = mLastUserActivityTime //计算下一次屏幕要变为dim的时间
- + screenOffTimeout - screenDimDuration;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; //现在还早于屏幕超时, 设置现在用户活动为屏幕高亮
- } else {
- nextTimeout = mLastUserActivityTime + screenOffTimeout; //重新设置屏幕超时时间,进入dim阶段
- if (now < nextTimeout) { //进入dim阶段了
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0
- && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout) { //根据请求的policy来判断屏幕是高亮,还是dim状态
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0) { //如果mUserActivitySummary还没赋值
- if (sleepTimeout >= 0) {
- final long anyUserActivity = Math.max(mLastUserActivityTime,
- mLastUserActivityTimeNoChangeLights);
- if (anyUserActivity >= mLastWakeTime) {
- nextTimeout = anyUserActivity + sleepTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; //设置dream状态
- }
- }
- } else {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
- }
- if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
- if ((mUserActivitySummary &
- (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
- // Device is being kept awake by recent user activity
- if (nextTimeout >= now && mOverriddenTimeout == -1) {
- // Save when the next timeout would have occurred
- mOverriddenTimeout = nextTimeout;
- }
- }
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
- if (mUserActivitySummary != 0 && nextTimeout >= 0) { //mUserActivitySummary有值, 并且nextTimeout大于等于0, 发超时消息
- Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, nextTimeout); //发送屏幕超时的Message
- }
- } else {
- mUserActivitySummary = 0;
- }
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
- }
- }
- }
PowerManagerHandler接收屏幕超时的消息, 并且调用handleUserActivityTimeout进行处理, 该函数之后就在Handler线程中运行.
- /**
- * Handler for asynchronous operations performed by the power manager.
- */
- private final class PowerManagerHandler extends Handler {
- public PowerManagerHandler(Looper looper) {
- super(looper, null, true /*async*/);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_USER_ACTIVITY_TIMEOUT:
- handleUserActivityTimeout(); //处理用户超时事件
- break;
- case MSG_SANDMAN:
- handleSandman();
- break;
- case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
- handleScreenBrightnessBoostTimeout();
- break;
- }
- }
- }
- private void handleUserActivityTimeout() { // runs on handler thread
- synchronized (mLock) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "handleUserActivityTimeout");
- }
- mDirty |= DIRTY_USER_ACTIVITY; //设置有用户活动的mDirty值
- updatePowerStateLocked(); //更新电源状态, 最后去判断是否要睡眠
- }
- }
在updateWakefulnessLocked中主要根据是否存在wakeLock,用户活动进行判断设备是否需要进入睡眠状态。从函数isBeingKeptAwakeLocked可以看出当device拿着一个wake lock,有用户事件,有距离传感器等都不会灭屏进行睡眠状态。如果需要睡眠就会往下面调用,最后跳出循环。
- private boolean updateWakefulnessLocked(int dirty) {
- boolean changed = false;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
- | DIRTY_DOCK_STATE)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) { //mWakefulness为AWAKE, 并且到了睡觉时间, 就去睡觉
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
- }
- final long time = SystemClock.uptimeMillis();
- if (shouldNapAtBedTimeLocked()) {
- changed = napNoUpdateLocked(time, Process.SYSTEM_UID); //睡觉前先小憩一会
- } else {
- changed = goToSleepNoUpdateLocked(time,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); //直接睡觉
- }
- }
- }
- return changed;
- }
- private boolean isItBedTimeYetLocked() {// 对所有该唤醒的情况取反, 就是该休眠了
- return mBootCompleted && !isBeingKeptAwakeLocked();
- }
- private boolean isBeingKeptAwakeLocked() {
- return mStayOn //设置了stay on
- || mProximityPositive //距离传感器返回一个positive结果,保持唤醒
- || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0 //当有wake lock时保持唤醒
- || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
- | USER_ACTIVITY_SCREEN_DIM)) != 0 //有user activity时保持唤醒
- || mScreenBrightnessBoostInProgress;
- }
- mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
- mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0); //从settings数据库获取对应值
- mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
- mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0);
- private boolean shouldNapAtBedTimeLocked() { //当返回true, 设备自动nap
- return mDreamsActivateOnSleepSetting
- || (mDreamsActivateOnDockSetting
- && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
- }
- private boolean napNoUpdateLocked(long eventTime, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid);
- }
- if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "nap");
- try {
- Slog.i(TAG, "Nap time (uid " + uid +")...");
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DREAMING, 0); //设置WAKEFULNESS_DREAMING
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
调用goToSleepNoUpdateLocked进行睡眠, 当按power键灭屏是也会调用该函数.
- private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
- + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);
- }
- if (eventTime < mLastWakeTime
- || mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
- || !mBootCompleted || !mSystemReady) {
- return false; //判断设备是否应该睡眠
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
- try {
- switch (reason) { //输出灭屏的原因
- case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
- Slog.i(TAG, "Going to sleep due to device administration policy "
- + "(uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
- Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH:
- Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
- Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
- Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_HDMI:
- Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
- break;
- default:
- Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");
- reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
- break;
- }
- mLastSleepTime = eventTime;
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
- // 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++) { //遍历所有的wakeLocks, 将FULL, BRIGHT, DIM Locks,计入numWakeLocksCleared中
- 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;
- }
- }
- EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
- // Skip dozing if requested.
- if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
- reallyGoToSleepNoUpdateLocked(eventTime, uid); //如果没有doze流程,直接设置WAKEFULNESS_ASLEEP
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true; //返回true
- }
当跳出循环之后在函数updateDisplayPowerStateLocked中进行获取需要请求的设备电源状态是亮还是灭或者dim,判断是否开启了自动调节亮度开关,是否使用了距离传感器,并经过一系列的计算获取亮度值等,最终都记录到DisplayPowerRequest中,经过DMS传入DPC中,进行处理。
- private boolean updateDisplayPowerStateLocked(int dirty) {
- final boolean oldDisplayReady = mDisplayReady;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
- | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
- mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); //根据mWakefulness与mWakeLockSummary获得,设备新状态是DIM, BRIGHT, OFF还是DOZE
- // Determine appropriate screen brightness and auto-brightness adjustments.
- boolean brightnessSetByUser = true;
- int screenBrightness = mScreenBrightnessSettingDefault;
- float screenAutoBrightnessAdjustment = 0.0f; //自动亮度调节
- boolean autoBrightness = (mScreenBrightnessModeSetting ==
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); //是否开启自动亮度
- if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
- screenBrightness = mScreenBrightnessOverrideFromWindowManager;
- autoBrightness = false;
- brightnessSetByUser = false;
- } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
- screenBrightness = mTemporaryScreenBrightnessSettingOverride;
- } else if (isValidBrightness(mScreenBrightnessSetting)) {
- screenBrightness = mScreenBrightnessSetting;
- }
- if (autoBrightness) {
- screenBrightness = mScreenBrightnessSettingDefault; //自动亮度调节
- if (isValidAutoBrightnessAdjustment(
- mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
- screenAutoBrightnessAdjustment =
- mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
- } else if (isValidAutoBrightnessAdjustment(
- mScreenAutoBrightnessAdjustmentSetting)) {
- screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
- }
- }
- screenBrightness = Math.max(Math.min(screenBrightness, //获得请求亮度
- mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
- screenAutoBrightnessAdjustment = Math.max(Math.min(
- screenAutoBrightnessAdjustment, 1.0f), -1.0f);
- // Update display power request. //将数据记录在mDisplayPowerRequest中
- mDisplayPowerRequest.screenBrightness = screenBrightness;
- mDisplayPowerRequest.screenAutoBrightnessAdjustment =
- screenAutoBrightnessAdjustment;
- mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
- mDisplayPowerRequest.useAutoBrightness = autoBrightness;
- mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
- mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;
- mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
- mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
- if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
- && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
- }
- mDisplayPowerRequest.dozeScreenBrightness =
- mDozeScreenBrightnessOverrideFromDreamManager;
- } else {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
- mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
- }
- mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
- mRequestWaitForNegativeProximity); //调用requestPowerState请求电源状态
- mRequestWaitForNegativeProximity = false;
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
- + ", policy=" + mDisplayPowerRequest.policy
- + ", mWakefulness=" + mWakefulness
- + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
- + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", mBootCompleted=" + mBootCompleted
- + ", mScreenBrightnessBoostInProgress="
- + mScreenBrightnessBoostInProgress);
- }
- }
- return mDisplayReady && !oldDisplayReady;
- }
绪论
可以导致手机亮灭屏的因素有多种,而在本文中主要讲解按power键亮灭屏过程以及来电亮屏。在亮灭屏过程power中主要的实现类与功能如下所述:
PowerManagerService.java:以下简称PMS或者PowerMS,主要处理系统中与power相关的计算,然后决策系统该如何反应。同时协调power如何与系统其他模块的交互,比如没有用户活动时屏幕变暗等。
DisplayPowerController.java:以下简称DPC或者DisplayPC,管理display设备状态,在DisplayManagerService.java(简称DMS)中实例化一个对象,以DMS为桥梁与PMS进行交互。主要处理距离传感器,亮灭屏动画,以及计算屏幕目标亮度值。通过异步回调机制来通知PMS那些事情发生了改变。同时也与WMS进行交互。
DisplayPowerState.java:以下简称DPS,power通过其与系统进行交互,如调用其它模块设置屏幕状态与亮度。仅在DPC中实例化一个对象,它算是DPC的一部分只不过将其独立出来了。
Notifier.java:将power状态的重要变化,通过广播发送出去,并且参与了与AMS,WMS,IMP的交互。
ColorFade.java:负责屏幕由关到开,由开到关的一些GL动画,由DPC进行控制。
AutomaticBrightnessController.java:主要处理光传感器,将底层上传的参数进行处理计算,将计算的新的亮度值传给DPC。
RampAnimator.java:处理屏幕亮度渐变动画。
亮屏总览
在点击power键亮屏过程中,主要流程就是input对按键事件的传输,传送到上层处理。之后就是在power中进行对亮屏状态的处理,计算一系列的数值,并且与AMS,WMS等模块进行交互,最后调用底层LCD进行最终的设备状态与亮度的设置。在下面将会对各流程详细讲解。
Input传输Power键
当触发power键,kernel会将该事件中断,然后InputReader通过EventHub获取事件,并且对输入事件进行处理,之后交由InputDispatcher进行分发。如果该事件为key事件会先调用interceptKeyBeforeQueueing,提前对需要系统处理的事件进行处理。最终调到PhoneWindowManager类中的interceptKeyBeforeQueueing函数对该事件优先处理,对power键以及屏幕状态进行判断,来决定亮屏还是灭屏等操作。当需要亮屏时,会调用PowerMangerService中的wakeup函数进行处理。
从底层到上层的具体代码调用流程 InputReader.cpp->InputDispatcher.cpp->com_android_server_input_InputManagerService.cpp->InputManagerService.java->InputMonitor.java->WindowManagerPolicy.java->PhoneWindowManager.java最终来到java层处理按键事件.
- public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
- if (!mSystemBooted) { //系统还没有启动完成,不处理任何按键事件
- // If we have not yet booted, don't let key events do anything.
- return 0;
- }
- final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; //是否能与用户交互, 如果亮屏为true
- final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; //按键down事件
- final boolean canceled = event.isCanceled(); //事件被取消
- final int keyCode = event.getKeyCode(); //按键事件的code
- final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
- // Basic policy based on interactive state.
- int result;
- boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
- || event.isWakeKey(); //flags有wake标记,或者按键为KEYCODE_BACK, KEYCODE_MENU, KEYCODE_WAKEUP, KEYCODE_PAIRING, KEYCODE_STEM_1, KEYCODE_STEM_2, KEYCODE_STEM_3设置isWakeKey为true. power ,home键属于systemKey
- // If the key would be handled globally, just return the result, don't worry about special
- // key processing.
- if (isValidGlobalKey(keyCode)
- && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
- if (isWakeKey) { //如果按键时间有效, 并且在com.android.internal.R.xml.global_keys文件中配置了keycode. 如果是唤醒键就调用wakeUp唤醒屏幕
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
- }
- return result;
- }
- // Handle special keys. //处理特殊的按键事件 ,这里主要讲解power键事件
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK: //back键
- case KeyEvent.KEYCODE_VOLUME_DOWN: //音量下键
- case KeyEvent.KEYCODE_VOLUME_UP: //音量上键
- case KeyEvent.KEYCODE_VOLUME_MUTE: //静音键
- case KeyEvent.KEYCODE_ENDCALL: //挂断电话键
- case KeyEvent.KEYCODE_POWER: { //电源键
- result &= ~ACTION_PASS_TO_USER;
- isWakeKey = false; // wake-up will be handled separately
- if (down) { //power按下事件
- interceptPowerKeyDown(event, interactive); //处理power下键
- } else { //power键松开
- interceptPowerKeyUp(event, interactive, canceled); //处理power上键
- }
- break;
- }
- case KeyEvent.KEYCODE_SLEEP:
- case KeyEvent.KEYCODE_SOFT_SLEEP:
- case KeyEvent.KEYCODE_WAKEUP:
- 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:
- case KeyEvent.KEYCODE_CALL:
- case KeyEvent.KEYCODE_VOICE_ASSIST:
- case KeyEvent.KEYCODE_WINDOW:
- }
- }
- if (isWakeKey) { //如果除了power键, 别的按键也需要亮屏,就调用WakeUp亮屏
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
- }
- return result;
- }
- private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
- // Hold a wake lock until the power key is released.
- if (!mPowerKeyWakeLock.isHeld()) {
- mPowerKeyWakeLock.acquire(); //获取wakeLock,保持cpu唤醒状态
- }
- // Latch power key state to detect screenshot chord.
- if (interactive && !mScreenshotChordPowerKeyTriggered
- && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
- mScreenshotChordPowerKeyTriggered = true;
- mScreenshotChordPowerKeyTime = event.getDownTime();
- interceptScreenshotChord(); //屏幕截屏
- }
- // Stop ringing or end call if configured to do so when power is pressed.
- TelecomManager telecomManager = getTelecommService(); //获取telecom
- boolean hungUp = false;
- if (telecomManager != null) {
- if (telecomManager.isRinging()) { //如果来电过程中,按power键手机将静音,停止响铃
- // 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(); //如果在Setting数据库中配置了,按power键挂断电话, 就将电话挂断
- }
- }
- //................
- // If the power key has still not yet been handled, then detect short
- // press, long press, or multi press and decide what to do. //如果power键还没有被处理,就判断是短按, 长按,还是多按来决定如何处理
- mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
- || mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
- 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()) { //如果屏幕是亮这的,长按power键 ,就处理长按事件
- Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg,
- ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
- }
- } else {
- wakeUpFromPowerKey(event.getDownTime()); //如果屏幕是休眠状态,就唤醒屏幕
- if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
- Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, //如果还是长按power键, 就再处理长按事件
- ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
- mBeganFromNonInteractive = true;
- } else {
- final int maxCount = getMaxMultiPressPowerCount();
- if (maxCount <= 1) {
- mPowerKeyHandled = true;
- } else {
- mBeganFromNonInteractive = true;
- }
- }
- }
- }
- }
- private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
- final boolean handled = canceled || mPowerKeyHandled;
- mScreenshotChordPowerKeyTriggered = false;
- cancelPendingScreenshotChordAction();
- cancelPendingPowerKeyAction();
- if (!handled) { //power键还没被处理
- // Figure out how to handle the key now that it has been released.
- mPowerKeyPressCounter += 1;
- final int maxCount = getMaxMultiPressPowerCount(); //多按的次数
- final long eventTime = event.getDownTime(); //按键发生的时间点
- if (mPowerKeyPressCounter < maxCount) {
- // This could be a multi-press. Wait a little bit longer to confirm.
- // Continue holding the wake lock. //等待一会调用powerPress处理
- Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
- interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout());
- return;
- }
- // No other actions. Handle it immediately.
- powerPress(eventTime, interactive, mPowerKeyPressCounter); //没有的的处理, 立即处理power down事件
- }
- // Done. Reset our state.
- finishPowerKeyPress(); //power键处理结束
- }
- private void finishPowerKeyPress() {
- mBeganFromNonInteractive = false;
- mPowerKeyPressCounter = 0;
- if (mPowerKeyWakeLock.isHeld()) {
- mPowerKeyWakeLock.release(); //释放wakLock
- }
- }
- private void powerPress(long eventTime, boolean interactive, int count) {
- if (mScreenOnEarly && !mScreenOnFully) {
- Slog.i(TAG, "Suppressed redundant power key press while "
- + "already in the process of turning the screen on.");
- return;
- }
- if (count == 2) {
- powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior); //处理按两次power键事件
- } else if (count == 3) {
- powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior); //处理按三次power键事件
- } else if (interactive && !mBeganFromNonInteractive) {
- switch (mShortPressOnPowerBehavior) {
- case SHORT_PRESS_POWER_NOTHING:
- break;
- case SHORT_PRESS_POWER_GO_TO_SLEEP: //灭屏
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: //灭屏,不经历doze流程
- mPowerManager.goToSleep(eventTime,
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- break;
- case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
- mPowerManager.goToSleep(eventTime, //灭屏,不经历doze流程, 并返回home界面
- PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- launchHomeFromHotKey();
- break;
- case SHORT_PRESS_POWER_GO_HOME: //返回home界面
- launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
- break;
- }
- }
- }
- 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); //调用PowerManagerService唤醒屏幕
- return true;
- }
当power接收到亮灭屏调用后,会先进行设置手机wakefullness状态. 之后发送亮灭屏广播通知其他应用手机处于亮屏还是灭屏状态。
- private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
- String opPackageName, int opUid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
- }
- if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false; //判断是否要去亮屏
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
- try {
- switch (mWakefulness) {
- case WAKEFULNESS_ASLEEP:
- Slog.i(TAG, "Waking up from sleep due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DREAMING:
- Slog.i(TAG, "Waking up from dream due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- case WAKEFULNESS_DOZING:
- Slog.i(TAG, "Waking up from dozing due to"+opPackageName+" "+reason+" (uid " + reasonUid +")...");
- break;
- }
- mLastWakeTime = eventTime; //设置最后一次唤醒的时间
- setWakefulnessLocked(WAKEFULNESS_AWAKE, 0); //Notifier调用onWakefulnessChangeStarted发送亮屏广播
- mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid); //调用Notifier通知battery处理
- userActivityNoUpdateLocked( //更新最后一次用户事件的时间
- eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
- public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
- final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); //获取交互模式,亮屏为true, 灭屏为false
- 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); //与AMS交互处理
- }
- });
- // 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); //在input中记录现在的屏幕状态
- mInputMethodManagerInternal.setInteractive(interactive);
- // Notify battery stats.
- try {
- mBatteryStats.noteInteractive(interactive); //唤醒battery状态
- } catch (RemoteException ex) { }
- // Handle early behaviors.
- mInteractive = interactive;
- mInteractiveChangeReason = reason;
- mInteractiveChanging = true;
- handleEarlyInteractiveChange(); //初期处理交互模式改变
- }
- }
- private void handleEarlyInteractiveChange() {
- synchronized (mLock) {
- if (mInteractive) {
- // Waking up... //亮屏
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
- mPolicy.startedWakingUp(); //通过PhoneWindowManager系统开始亮屏, 更新转向监听器,手势监听器等
- }
- });
- // Send interactive broadcast.
- mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
- mPendingWakeUpBroadcast = true;
- updatePendingBroadcastLocked(); //更新亮屏广播
- } else {
- // Going to sleep... //灭屏
- // Tell the policy that we started going to sleep.
- final int why = translateOffReason(mInteractiveChangeReason);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mPolicy.startedGoingToSleep(why);
- }
- });
- }
- }
- }
- private void sendNextBroadcast() {
- final int powerState;
- synchronized (mLock) {
- if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
- // Broadcasted power state is unknown. Send wake up.
- mPendingWakeUpBroadcast = false;
- mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; //亮屏状态
- } 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;
- }
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
- if (powerState == INTERACTIVE_STATE_AWAKE) {
- sendWakeUpBroadcast(); //发送亮屏广播
- } else {
- sendGoToSleepBroadcast();
- }
- }
- mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); //亮屏广播intent
- mScreenOnIntent.addFlags( //前台广播
- Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
- private void sendWakeUpBroadcast() {
- if (DEBUG) {
- Slog.d(TAG, "Sending wake up broadcast.");
- }
- if (ActivityManagerNative.isSystemReady()) {
- mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
- mWakeUpBroadcastDone, mHandler, 0, null, null); //发送亮屏广播,并且其它模块全部处理完后, 自身接收亮屏广播
- } else {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
- sendNextBroadcast();
- }
- }
- private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
- SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
- sendNextBroadcast(); //自身接收到亮屏广播后, 之后会调用finishPendingBroadcastLocked,释放wakeLock
- }
- };
当wakefulness状态发生改变,AMS收到通知。如果亮屏操作,AMS就会通过函数comeOutOfSleepIfNeedLocked调用到ActivityStackSupervisor中,将sleep超时消息移除,如果抓的有partial锁,就将其释放,最后将在栈顶的activity显示出来。
power是通过WindowManagerPolicy与PhoneWindowManager进行交互,当屏幕在wakingup时需要通知window进行更新手势监听,更新方向监听,更新锁屏超时时间。最后通知keyguard屏幕点亮了,进行刷新锁屏界面时间,之后通过回调接口,回调回PhoneWindowManager的onShown函数,通知window keyguard准备完成。
当亮屏时通过InputManagerService将当前屏幕状态传入JNI中进行记录,当再次发生power键事件可以方便确认该事件是需要亮屏还是灭屏。
更新Power全局状态
当广播处理完毕后就会调用PMS的内部函数updatePowerStateLocked来更新全局电源状态。其实在PMS中很多函数都只是对一些必须的属性进行赋值,大部分最终都会调用到updatePowerStateLocked函数中进行功能执行,其中更新电源状态主要依据就是变量mDirty。mDirty就是用来记录power state的变化的标记位,这样的状态变化在系统中一共定义了12个,每一个状态对应一个固定的数字,都是2的倍数。这样,若有多个状态一块变化,进行按位取或这样结果既是唯一的,又能准确标记出各个状态的变化。在updatePowerStateLocked中主要做了如下事情:
一.首先判断手机是否处于充电状态,如果标记位DIRTY_BATTERY_STATE发生改变时就证明电池状态发生了改变,然后通过对比判断(通过电池前后变化与充电状态的变化),确认手机是否处于充电状态。如果手机处于充电状态会将表示充电的标记位记入mDirty中。当有USB插拔时我们也可以通过配置信息来决定是否需要点亮屏幕。并且是否在充电或者充电方式发生改变,系统都会认为发生了一次用户事件进行更新最后用户操作时间,以此来重新计算屏幕超时时间。
- private void updateIsPoweredLocked(int dirty) {
- if ((dirty & DIRTY_BATTERY_STATE) != 0) {
- final boolean wasPowered = mIsPowered; //是否在充电
- final int oldPlugType = mPlugType; //充电类型
- final boolean oldLevelLow = mBatteryLevelLow; //低电模式
- mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
- mPlugType = mBatteryManagerInternal.getPlugType();
- mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
- mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
- if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
- mDirty |= DIRTY_IS_POWERED; //如果充电中设置mDirty
- // Update wireless dock detection state.
- final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
- mIsPowered, mPlugType, mBatteryLevel); //无线充电
- // Treat plugging and unplugging the devices as a user activity.
- // Users find it disconcerting when they plug or unplug the device
- // and it shuts off right away.
- // Some devices also wake the device when plugged or unplugged because
- // they don't have a charging LED.
- final long now = SystemClock.uptimeMillis();
- if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
- dockedOnWirelessCharger)) { //插拔USB是否要点亮屏幕
- wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID,
- mContext.getOpPackageName(), Process.SYSTEM_UID);
- }
- userActivityNoUpdateLocked( //插拔USB算一次用户事件,重新设置最后一次用户事件的时间点
- now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
- // Tell the notifier whether wireless charging has started so that
- // it can provide feedback to the user.
- if (dockedOnWirelessCharger) {
- mNotifier.onWirelessChargingStarted();
- }
- }
- if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) { //低电模式
- if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateIsPoweredLocked: resetting low power snooze");
- }
- mAutoLowPowerModeSnoozing = false;
- }
- updateLowPowerModeLocked(); //更新低电模式
- }
- }
- }
- mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
- com.android.internal.R.bool.config_unplugTurnsOnScreen); //从xml文件中读取配置信息
- private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
- boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
- // Don't wake when powered unless configured to do so.
- if (!mWakeUpWhenPluggedOrUnpluggedConfig) { //如果配置为true, 可能会亮屏
- return false;
- }
- // Don't wake when undocked from wireless charger.
- // See WirelessChargerDetector for justification.
- if (wasPowered && !mIsPowered
- && oldPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
- return false;
- }
- // Don't wake when docked on wireless charger unless we are certain of it.
- // See WirelessChargerDetector for justification.
- if (!wasPowered && mIsPowered
- && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
- && !dockedOnWirelessCharger) {
- return false;
- }
- // If already dreaming and becoming powered, then don't wake.
- if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
- return false;
- }
- // Don't wake while theater mode is enabled.
- if (mTheaterModeEnabled && !mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig) {
- return false;
- }
- // Otherwise wake up!
- return true;
- }
二:更新wakefulness
- for (;;) {
- int dirtyPhase1 = mDirty;
- dirtyPhase2 |= dirtyPhase1;
- mDirty = 0; //将mDirty清零,不影响下个循环
- updateWakeLockSummaryLocked(dirtyPhase1);
- updateUserActivitySummaryLocked(now, dirtyPhase1);
- if (!updateWakefulnessLocked(dirtyPhase1)) { //当updateWakefulnessLocked返回false跳出循环
- break;
- }
- }
updateWakeLockSummaryLocked函数将wakeLock的类型用mWakeLockSummary进行记录,最后与Wakefulness状态结合重新算出新的mWakeLockSummary值,在下面判断是否需要睡眠时会使用。
- private void updateWakeLockSummaryLocked(int dirty) {
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
- mWakeLockSummary = 0;
- final int numWakeLocks = mWakeLocks.size(); //获取所有的wakeLocks
- for (int i = 0; i < numWakeLocks; i++) { //遍历所有的wakeLocks, 将wakeLocks记录在mWakeLockSummary中
- final WakeLock wakeLock = mWakeLocks.get(i);
- switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
- case PowerManager.PARTIAL_WAKE_LOCK:
- if (!wakeLock.mDisabled) {
- // We only respect this if the wake lock is not disabled.
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- break;
- case PowerManager.FULL_WAKE_LOCK: //屏幕键盘全部点亮
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
- break;
- case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: //点亮屏幕
- mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
- break;
- case PowerManager.SCREEN_DIM_WAKE_LOCK: //dim锁
- mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM;
- break;
- case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: //距离灭屏
- mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- break;
- case PowerManager.DOZE_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DOZE;
- break;
- case PowerManager.DRAW_WAKE_LOCK:
- mWakeLockSummary |= WAKE_LOCK_DRAW;
- break;
- }
- }
- // Cancel wake locks that make no sense based on the current state.
- if (mWakefulness != WAKEFULNESS_DOZING) { //根据当前的屏幕状态, 取消不必要的wakeLocks
- mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
- }
- if (mWakefulness == WAKEFULNESS_ASLEEP //如果屏幕为休眠,就将屏幕高亮,dim锁取消
- || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
- mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
- | WAKE_LOCK_BUTTON_BRIGHT);
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
- mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
- }
- }
- // Infer implied wake locks where necessary based on the current state.
- if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE) {
- mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE; //当WakeLock为亮屏锁或dim锁时,需要保持AWAKE状态。
- } else if (mWakefulness == WAKEFULNESS_DREAMING) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- }
- if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
- mWakeLockSummary |= WAKE_LOCK_CPU;
- }
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
- }
- }
- }
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
- | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT); //移除屏幕超时的Message
- long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- final int sleepTimeout = getSleepTimeoutLocked(); //获取睡眠超时时间
- final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout); //获取屏幕超时时间
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout); //获取dim持续时长
- final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
- mUserActivitySummary = 0;
- if (mLastUserActivityTime >= mLastWakeTime) { //最后一次的用户时间大于最后一次屏幕醒来的时间
- nextTimeout = mLastUserActivityTime //计算下一次屏幕要变为dim的时间
- + screenOffTimeout - screenDimDuration;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; //现在还早于屏幕超时, 设置现在用户活动为屏幕高亮
- } else {
- nextTimeout = mLastUserActivityTime + screenOffTimeout; //重新设置屏幕超时时间,进入dim阶段
- if (now < nextTimeout) { //进入dim阶段了
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0
- && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout) { //根据请求的policy来判断屏幕是高亮,还是dim状态
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0) { //如果mUserActivitySummary还没赋值
- if (sleepTimeout >= 0) {
- final long anyUserActivity = Math.max(mLastUserActivityTime,
- mLastUserActivityTimeNoChangeLights);
- if (anyUserActivity >= mLastWakeTime) {
- nextTimeout = anyUserActivity + sleepTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; //设置dream状态
- }
- }
- } else {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
- }
- if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
- if ((mUserActivitySummary &
- (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
- // Device is being kept awake by recent user activity
- if (nextTimeout >= now && mOverriddenTimeout == -1) {
- // Save when the next timeout would have occurred
- mOverriddenTimeout = nextTimeout;
- }
- }
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
- if (mUserActivitySummary != 0 && nextTimeout >= 0) { //mUserActivitySummary有值, 并且nextTimeout大于等于0, 发超时消息
- Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, nextTimeout); //发送屏幕超时的Message
- }
- } else {
- mUserActivitySummary = 0;
- }
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
- }
- }
- }
PowerManagerHandler接收屏幕超时的消息, 并且调用handleUserActivityTimeout进行处理, 该函数之后就在Handler线程中运行.
- /**
- * Handler for asynchronous operations performed by the power manager.
- */
- private final class PowerManagerHandler extends Handler {
- public PowerManagerHandler(Looper looper) {
- super(looper, null, true /*async*/);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_USER_ACTIVITY_TIMEOUT:
- handleUserActivityTimeout(); //处理用户超时事件
- break;
- case MSG_SANDMAN:
- handleSandman();
- break;
- case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
- handleScreenBrightnessBoostTimeout();
- break;
- }
- }
- }
- private void handleUserActivityTimeout() { // runs on handler thread
- synchronized (mLock) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "handleUserActivityTimeout");
- }
- mDirty |= DIRTY_USER_ACTIVITY; //设置有用户活动的mDirty值
- updatePowerStateLocked(); //更新电源状态, 最后去判断是否要睡眠
- }
- }
在updateWakefulnessLocked中主要根据是否存在wakeLock,用户活动进行判断设备是否需要进入睡眠状态。从函数isBeingKeptAwakeLocked可以看出当device拿着一个wake lock,有用户事件,有距离传感器等都不会灭屏进行睡眠状态。如果需要睡眠就会往下面调用,最后跳出循环。
- private boolean updateWakefulnessLocked(int dirty) {
- boolean changed = false;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
- | DIRTY_DOCK_STATE)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) { //mWakefulness为AWAKE, 并且到了睡觉时间, 就去睡觉
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
- }
- final long time = SystemClock.uptimeMillis();
- if (shouldNapAtBedTimeLocked()) {
- changed = napNoUpdateLocked(time, Process.SYSTEM_UID); //睡觉前先小憩一会
- } else {
- changed = goToSleepNoUpdateLocked(time,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); //直接睡觉
- }
- }
- }
- return changed;
- }
- private boolean isItBedTimeYetLocked() {// 对所有该唤醒的情况取反, 就是该休眠了
- return mBootCompleted && !isBeingKeptAwakeLocked();
- }
- private boolean isBeingKeptAwakeLocked() {
- return mStayOn //设置了stay on
- || mProximityPositive //距离传感器返回一个positive结果,保持唤醒
- || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0 //当有wake lock时保持唤醒
- || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
- | USER_ACTIVITY_SCREEN_DIM)) != 0 //有user activity时保持唤醒
- || mScreenBrightnessBoostInProgress;
- }
- mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
- mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0); //从settings数据库获取对应值
- mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
- mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0);
- private boolean shouldNapAtBedTimeLocked() { //当返回true, 设备自动nap
- return mDreamsActivateOnSleepSetting
- || (mDreamsActivateOnDockSetting
- && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
- }
- private boolean napNoUpdateLocked(long eventTime, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid);
- }
- if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
- return false;
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "nap");
- try {
- Slog.i(TAG, "Nap time (uid " + uid +")...");
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DREAMING, 0); //设置WAKEFULNESS_DREAMING
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
调用goToSleepNoUpdateLocked进行睡眠, 当按power键灭屏是也会调用该函数.
- private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
- + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);
- }
- if (eventTime < mLastWakeTime
- || mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
- || !mBootCompleted || !mSystemReady) {
- return false; //判断设备是否应该睡眠
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
- try {
- switch (reason) { //输出灭屏的原因
- case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
- Slog.i(TAG, "Going to sleep due to device administration policy "
- + "(uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
- Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH:
- Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
- Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
- Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");
- break;
- case PowerManager.GO_TO_SLEEP_REASON_HDMI:
- Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");
- break;
- default:
- Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");
- reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
- break;
- }
- mLastSleepTime = eventTime;
- mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
- // 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++) { //遍历所有的wakeLocks, 将FULL, BRIGHT, DIM Locks,计入numWakeLocksCleared中
- 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;
- }
- }
- EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);
- // Skip dozing if requested.
- if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
- reallyGoToSleepNoUpdateLocked(eventTime, uid); //如果没有doze流程,直接设置WAKEFULNESS_ASLEEP
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true; //返回true
- }
当跳出循环之后在函数updateDisplayPowerStateLocked中进行获取需要请求的设备电源状态是亮还是灭或者dim,判断是否开启了自动调节亮度开关,是否使用了距离传感器,并经过一系列的计算获取亮度值等,最终都记录到DisplayPowerRequest中,经过DMS传入DPC中,进行处理。
- private boolean updateDisplayPowerStateLocked(int dirty) {
- final boolean oldDisplayReady = mDisplayReady;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
- | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
- mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); //根据mWakefulness与mWakeLockSummary获得,设备新状态是DIM, BRIGHT, OFF还是DOZE
- // Determine appropriate screen brightness and auto-brightness adjustments.
- boolean brightnessSetByUser = true;
- int screenBrightness = mScreenBrightnessSettingDefault;
- float screenAutoBrightnessAdjustment = 0.0f; //自动亮度调节
- boolean autoBrightness = (mScreenBrightnessModeSetting ==
- Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); //是否开启自动亮度
- if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
- screenBrightness = mScreenBrightnessOverrideFromWindowManager;
- autoBrightness = false;
- brightnessSetByUser = false;
- } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
- screenBrightness = mTemporaryScreenBrightnessSettingOverride;
- } else if (isValidBrightness(mScreenBrightnessSetting)) {
- screenBrightness = mScreenBrightnessSetting;
- }
- if (autoBrightness) {
- screenBrightness = mScreenBrightnessSettingDefault; //自动亮度调节
- if (isValidAutoBrightnessAdjustment(
- mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
- screenAutoBrightnessAdjustment =
- mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
- } else if (isValidAutoBrightnessAdjustment(
- mScreenAutoBrightnessAdjustmentSetting)) {
- screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
- }
- }
- screenBrightness = Math.max(Math.min(screenBrightness, //获得请求亮度
- mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
- screenAutoBrightnessAdjustment = Math.max(Math.min(
- screenAutoBrightnessAdjustment, 1.0f), -1.0f);
- // Update display power request. //将数据记录在mDisplayPowerRequest中
- mDisplayPowerRequest.screenBrightness = screenBrightness;
- mDisplayPowerRequest.screenAutoBrightnessAdjustment =
- screenAutoBrightnessAdjustment;
- mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
- mDisplayPowerRequest.useAutoBrightness = autoBrightness;
- mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
- mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;
- mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
- mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
- if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
- && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
- }
- mDisplayPowerRequest.dozeScreenBrightness =
- mDozeScreenBrightnessOverrideFromDreamManager;
- } else {
- mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
- mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
- }
- mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
- mRequestWaitForNegativeProximity); //调用requestPowerState请求电源状态
- mRequestWaitForNegativeProximity = false;
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
- + ", policy=" + mDisplayPowerRequest.policy
- + ", mWakefulness=" + mWakefulness
- + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
- + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", mBootCompleted=" + mBootCompleted
- + ", mScreenBrightnessBoostInProgress="
- + mScreenBrightnessBoostInProgress);
- }
- }
- return mDisplayReady && !oldDisplayReady;
- }