本篇注意接着上篇【Android7.0 PowerManagerService 之亮灭屏(一)】继续分析量灭屏的流程,这篇主要分析PMS的状态计算和更新流程,也是PMS中最为重要和复杂的一部分电源状态管理。

接上篇继续,在Notifier的广播处理完毕后就会调用PMS的内部函数updatePowerStateLocked()来更新全局电源状态。
         任何涉及到电源的操作(如量灭屏和应用获取wakeLock锁等)PMS都会调用updatePowerStateLocked()来更新电源的全局状态。PMS用mDirty 来记录电源的状态变化,mDirty是按位操作的(状态变化在系统中一共定义了12个,每一个状态都是2的倍数安位操作即可取得或设置状态)updatePowerStateLocked()的作用就是根据目的前电源状态属性的设置和值的变化来更新mDirty中相应位的值。

这个函数看似很短其实很复杂,可是说是PMS的核心。在看代码前先有个大概的认识和了解以免写入代码的汪洋大海中找不到方向,这样看代码就会比较轻松很容易理解。
其实总结起来此函数主要做了如下两件事:

  • 1)判断手机的电源状态(是否充电以及电池状态)和影响电源状态的事件(USB插拔,充电方式变化等)将相应的电源状态更新到mDirty中记录
    2)更新wakefulnes,在一个死循环里(当updateWakefulnessLocked返回false跳出循环)判断是否有wakeLock事件,系统是否应该休眠,更新屏幕超时时间等

好了,让我们具体分析吧。

一、updatePowerStateLocked()概览

  private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {
return;
}
if (!Thread.holdsLock(mLock)) {
Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
} Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
try {
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
updateScreenBrightnessBoostLocked(mDirty); // Phase 1: Update wakefulness.
// Loop because the wake lock and user activity computations are influenced
// by changes in wakefulness.
final long now = SystemClock.uptimeMillis();
int dirtyPhase2 = 0;
for (;;) {
int dirtyPhase1 = mDirty;
dirtyPhase2 |= dirtyPhase1;
mDirty = 0; updateWakeLockSummaryLocked(dirtyPhase1);
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();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}

二、updatePowerStateLocked()具体分析

1)updateIsPoweredLocked()

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(   //重新设置最后一次用户事件的时间点,亮屏超时是根据最后一次无用户事件开始算的  
                    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();  //更新低电模式  
        }  
    }  
}  

2)updateStayOnLocked()

更新充电状态

    private void updateStayOnLocked(int dirty) {
if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
final boolean wasStayOn = mStayOn;
if (mStayOnWhilePluggedInSetting != 0
&& !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);
} else {
mStayOn = false;
} if (mStayOn != wasStayOn) {
mDirty |= DIRTY_STAY_ON;
}
}
}

3)updateScreenBrightnessBoostLocked()

更新屏幕亮度超时时间,发送 MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT

    private void updateScreenBrightnessBoostLocked(int dirty) {
if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
if (mScreenBrightnessBoostInProgress) {
final long now = SystemClock.uptimeMillis();
mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
final long boostTimeout = mLastScreenBrightnessBoostTime +
SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
if (boostTimeout > now) {
Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, boostTimeout);
return;
}
}
mScreenBrightnessBoostInProgress = false;
mNotifier.onScreenBrightnessBoostChanged();
userActivityNoUpdateLocked(now,
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
}
}

4)Update wakefulness()

进入循环,三个函数分别做下面三件事

A:updateWakeLockSummaryLocked() 将wakeLock的类型记录并与Wakefulness状态结合重新算出新的mWakeLockSummary值

B:updateUserActivitySummaryLocked()更新屏幕超时时间(根据最后一次用户事件与dim持续时间来计算屏幕超时的时间,与现在的时间进行对比,决定屏幕继续高亮还是变为dim状态)

C:updateWakefulnessLocked()根据是否有wakeLock,用户活动是否需要睡眠(当device拿着一个wake lock,有用户事件,有距离传感器等都不会灭屏睡眠)

for循环的第一项循环中将所有的状态都更新且此时没有重要的mDirty发生变化,则在下一次循环中mDirty的值为0, updateWakefulnessLocked返回false,就会跳出循环.

A:updateWakeLockSummaryLocked()

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记录在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:   
                    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));  
        }  
    }   }  

B:updateUserActivitySummaryLocked()

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);  //移除屏幕超时消息
  
        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;  //重置屏幕超时时间
                    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) {   
                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);   //发送屏幕超时消息 
            }  
        } else {  
            mUserActivitySummary = 0;  
        }  
  
        if (DEBUG_SPEW) {  
            Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="  
                    + PowerManagerInternal.wakefulnessToString(mWakefulness)  
                    + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)  
                    + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));  
        }  
    }  
}  

C:updateWakefulnessLocked()

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;  
}  

5)updateDisplayPowerStateLocked()

获取需要请求的设备电源状态(判断是否开启亮度自动调节开关、距离传感器)并计算屏幕亮度值等记录到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;  
}

6)updateDreamLocked()

此函数的作用就是异步处理Dream,在Dream结束后系统休眠。具体是通过发送Dream消息在handleSandman函数中处理()详细过程不再展开。

private void updateDreamLocked(int dirty, boolean displayBecameReady) {  
    if ((dirty & (DIRTY_WAKEFULNESS  
            | DIRTY_USER_ACTIVITY  
            | DIRTY_WAKE_LOCKS  
            | DIRTY_BOOT_COMPLETED  
            | DIRTY_SETTINGS  
            | DIRTY_IS_POWERED  
            | DIRTY_STAY_ON  
            | DIRTY_PROXIMITY_POSITIVE  
            | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {  
        if (mDisplayReady) {  
            scheduleSandmanLocked();  
        }  
    }  
}  private void scheduleSandmanLocked() {  
    if (!mSandmanScheduled) {  
        mSandmanScheduled = true;  
        Message msg = mHandler.obtainMessage(MSG_SANDMAN);  
        msg.setAsynchronous(true);  
        mHandler.sendMessage(msg);  
    }  

7)finishWakefulnessChangeIfNeededLocked()

只有在睡眠状态才会调用mNotifier.onWakefulnessChangeFinished()

private void finishWakefulnessChangeIfNeededLocked() {  
    if (mWakefulnessChanging && mDisplayReady) {  
        if (mWakefulness == WAKEFULNESS_DOZING  
                && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {  
            return; // wait until dream has enabled dozing  
        }  
        mWakefulnessChanging = false;  
        mNotifier.onWakefulnessChangeFinished();  
    }  
}  

8)updateSuspendBlockerLocked()

更新睡眠锁,以及是否持锁和释放锁

 private void updateSuspendBlockerLocked() {
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
final boolean autoSuspend = !needDisplaySuspendBlocker;
final boolean interactive = mDisplayPowerRequest.isBrightOrDim(); // Disable auto-suspend if needed.
// FIXME We should consider just leaving auto-suspend enabled forever since
// we already hold the necessary wakelocks.
if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(false);
} // First acquire suspend blockers if needed.
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.acquire();
mHoldingWakeLockSuspendBlocker = true;
}
if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
} // Inform the power HAL about interactive mode.
// Although we could set interactive strictly based on the wakefulness
// as reported by isInteractive(), it is actually more desirable to track
// the display policy state instead so that the interactive state observed
// by the HAL more accurately tracks transitions between AWAKE and DOZING.
// Refer to getDesiredScreenPolicyLocked() for details.
if (mDecoupleHalInteractiveModeFromDisplayConfig) {
// When becoming non-interactive, we want to defer sending this signal
// until the display is actually ready so that all transitions have
// completed. This is probably a good sign that things have gotten
// too tangled over here...
if (interactive || mDisplayReady) {
setHalInteractiveModeLocked(interactive);
}
} // Then release suspend blockers if needed.
if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.release();
mHoldingWakeLockSuspendBlocker = false;
}
if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.release();
mHoldingDisplaySuspendBlocker = false;
} // Enable auto-suspend if needed.
if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
}

三、综述

不废话了,一图省千言万语

Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()的更多相关文章

  1. Android7.0 PowerManagerService 之亮灭屏(一)

    本篇从按下power按键后,按键事件从InputManagerService 传到PhoneWindowManager.java开始分析power 按键做屏幕亮灭过程的分析,关于power 按键的其他 ...

  2. qcom 8953平台 LCD亮灭屏流程及LCD知识点总结【转】

    一.LK中亮屏流程 gcdb_display_init(),进行display初始化的起始地方: oem_panel_select(),在这里去选择哪一款屏,也可以在这里添加新一款屏: dsi_pan ...

  3. Android7.0 Doze模式分析(一)Doze介绍 &amp; DeviceIdleController

     參考:http://blog.csdn.net/gaugamela/article/details/52981984 在Android M中.Google就引入了Doze模式.它定义了一种全新的 ...

  4. WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

    上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们 ...

  5. WmS具体解释(二)之怎样理解Window和窗体的关系?基于Android7.0源代码

    上篇博客(WmS具体解释(一)之token究竟是什么?基于Android7.0源代码)中我们简要介绍了token的作用,这里涉及到的概念非常多,当中出现频率最高的要数Window和窗体这一对搭档了,那 ...

  6. Android横竖屏切换和灭屏亮屏时Activity的生命周期探究(1)

    研究这个问题的初衷在于项目中碰到了一个问题:横屏的时候灭屏再亮屏,亮屏的时候用户能够清晰的看到先启动竖屏(过程1)再切换到横屏的过程,因为灭屏的时候onSaveInstanceState()保存的时横 ...

  7. Android7.0 Phone应用源码分析(二) phone来电流程分析

    接上篇博文:Android7.0 Phone应用源码分析(一) phone拨号流程分析 今天我们再来分析下Android7.0 的phone的来电流程 1.1TelephonyFramework 当有 ...

  8. (三)开关检测来控制LED灯的亮灭

    开关检测案例一: 具体电路图如下: K1--K4闭合,控制 D1—D4 亮灭 产生的问题: 1.关于 R8 R9 R7 R10 的阻值选择问题,倘若太大的话,  比如10K 不管开关断开还是闭合,好像 ...

  9. Android7.0 多窗口你值得拥有

    Android7.0 多窗口你值得拥有 什么是多窗口分屏? 多窗口分屏其实在国内并不陌生,已经有一些手机和平板搭载了"分屏多任务"和"APP窗口化"功能,但这些 ...

随机推荐

  1. 【Intel AF 2.1 学习笔记一】AF程序结构

    Intel App Framework(原jqMobi)是用来开发hybrid app的开源免费框架,被intel收编之后发布了最新的2.1版本,最近正在学习.af的所谓程序结构,就是AF网页的架构, ...

  2. 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

    记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安 ...

  3. 网络上可供测试的Web Service

    网络上可供测试的Web Service 腾讯QQ在线状态 WEB 服务Endpoint: http://www.webxml.com.cn/webservices/qqOnlineWebService ...

  4. 使用System.Web.Optimization对CSS和JS文件合并压缩

    在ASP.NET MVC 中JS/CSS文件动态合并及压缩通过调用System.Web.Optimization定义的类ScriptBundle及StyleBundle来实现. 大致步骤如下: 1.A ...

  5. [Converge] Backpropagation Algorithm

    Ref: CS231n Winter 2016: Lecture 4: Backpropagation Ref: How to implement a NN:中文翻译版本 Ref: Jacobian矩 ...

  6. NHibernate 集合映射深入 (第五篇) <set>,<list>,<map>,<bag>

    一.集合外键 在NHibernate中,典型的用于映射集合类的元素有<set>,<list>,<map>,<bag>,<array>,< ...

  7. 上机题目(0基础)- 用数组实现记事本(Java)

    用java实现一个记事本程序,记录记下的按键,代码例如以下: package com.java.test; import java.awt.Graphics; import java.awt.even ...

  8. C#------Aspose.cells使用方法

    转载: http://www.cnblogs.com/muer/p/yaxle.html 代码: public ActionResult ImportData(HttpPostedFileBase f ...

  9. PMP用语集

    AC actual cost 实际成本 ACWP actual cost of work performed 已完工作实际成本 BAC budget at completion 完工预算 BCWP b ...

  10. java命令行操作

    一直使用eclipse操作java程序,但RMI程序需要命令行操作,故研究了下java的命令行操作. javac 用于编译.java文件,生成.class文件 假设文件夹dir下有pa.java和a. ...