Step 1:
frameworks\base\services\java\com\android\server\SystemServer.java
开启PowerManagerService服务
private void startOtherServices() {
...
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
...
}
Step 2:
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
接下来分析下PowerManagerService载开机启动的时候准备过程
主要工作流程如下:
1.获取缺省,最大,最小的三种屏幕亮度
2.创建SystemSensorManager对象,用于和SensorService交互。SensorService是一个native的Service,也存在于SystemServer进程中,管理各种传感设备。
3.创建Notifer对象。Notifer对象用于广播系统中和power相关的变化,例如屏幕关闭和打开
4.创建WirelessChargerService对象,用于无线充电检测的传感器
5.调用DisplayManagerService的initPowerManagement()的方法来初始化Power管理模块
6.注册Observer监听系统设置的变化。
7.注册监听其他模块的Intent。
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
mSystemReady = true;
mAppOps = appOps;
//获取DreamManagerService
mDreamManager = getLocalService(DreamManagerInternal.class);
//获取DisplayManagerService
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mPolicy = getLocalService(WindowManagerPolicy.class);
//获得BatteryManagerService
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
//以下获取最大缺省,最大和最小屏幕亮度
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
if (DEBUG_SPEW) {
Slog.d(TAG, "mScreenBrightnessSettingMinimum = " + mScreenBrightnessSettingMinimum +
" mScreenBrightnessSettingMinimum = " + mScreenBrightnessSettingMaximum +
" mScreenBrightnessSettingDefault = " + mScreenBrightnessSettingDefault);
}
//创建缺省SensorManager对象,用于和SensorService交互
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
// The notifier runs on the system server's main looper so as not to interfere
// with the animations and other critical functions of the power manager.
//得到BatteryStatsService的引用对象
mBatteryStats = BatteryStatsService.getService();
//创建Notifier对象
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
//创建检测无线充电对象WirelessChargerDetector
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
//创建系统设置变化的对象
mSettingsObserver = new SettingsObserver(mHandler);
//初始化LightsService对象
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
mButtonLight = mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS);
mBacklight = mLightsManager.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
//初始化Power模块
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for broadcasts from other components of the system.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);//屏保启动广播
filter.addAction(Intent.ACTION_DREAMING_STOPPED);//屏保关闭广播
mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);//用户切换广播
mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);//Dock 插拔事件广播
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
// Register for SD Hot Plug notification
filter = new IntentFilter();
filter.addAction(Intent.ACTION_SD_INSERTED);//SD 插入事件广播
filter.addDataScheme("file");
mContext.registerReceiver(new SDHotPlugReceiver(), filter, null, mHandler);
// Register for wfd notification
mContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED),
null, mHandler);
filter = new IntentFilter();
filter.addAction("com.mediatek.SCREEN_TIMEOUT_MINIMUM");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) {
Slog.d(TAG, "SCREEN_TIMEOUT_MINIMUM.");
}
mPreWakeUpWhenPluggedOrUnpluggedConfig = mWakeUpWhenPluggedOrUnpluggedConfig;
mWakeUpWhenPluggedOrUnpluggedConfig = false;
mUserActivityTimeoutMin = true;
}
}, filter, null, mHandler);
filter = new IntentFilter();
filter.addAction("com.mediatek.SCREEN_TIMEOUT_NORMAL");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) {
Slog.d(TAG, "SCREEN_TIMEOUT_NORMAL.");
}
mWakeUpWhenPluggedOrUnpluggedConfig = mPreWakeUpWhenPluggedOrUnpluggedConfig;
mUserActivityTimeoutMin = false;
}
}, filter, null, mHandler);
// Register for settings changes.
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.THEATER_MODE_ON),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOUBLE_TAP_TO_WAKE),
false, mSettingsObserver, UserHandle.USER_ALL);
// Go.
if (DEBUG) {
Slog.d(TAG, "system ready!");
}
readConfigurationLocked();
updateSettingsLocked();
mDirty |= DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
}
Step 3:
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
updatePowerStatedLocked是整个PowerManagerService的核心方法,所有的之前状态变量的数值以及相关服务都需要载目前这个方法进行操作
接下来针对具体方法具体介绍。
private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {//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);//设置DIRTY_STAY_ON是否发生变化
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);//是根据PowerManagerService中所以的WackLock对象的类型,计算一个最终的类型集合
updateUserActivitySummaryLocked(now, dirtyPhase1);//用于判断最后一次调用userActivity的时间,计算现在是否可以将表示屏幕状态的变量mUserActivitySummary的值设置为SCREEN_STATE_DIM(变暗)或者SCREEN_STATE_OFF(关闭)
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();//在sys/power 存储数据
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
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 (DEBUG_SPEW) {
Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
+ ", mIsPowered=" + mIsPowered
+ ", oldPlugType=" + oldPlugType
+ ", mPlugType=" + mPlugType
+ ", mBatteryLevel=" + mBatteryLevel);
}
if (wasPowered != mIsPowered || oldPlugType != mPlugType) {//是否充电或者充电类型改变了
mDirty |= DIRTY_IS_POWERED;
// 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)) {
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();//更新低功耗模式
}
}
}
updateStayOnLocked
我理解成表示手机的某种状态,如是否在充电,屏幕亮度的情况
private void updateStayOnLocked(int dirty) {
if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {//当dirty是电池状态和设置的状态改变时
final boolean wasStayOn = mStayOn;
if (mStayOnWhilePluggedInSetting != 0//这个值从资源中读取,一般设置的话代表哪种充电时可以常亮
&& !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
//看有没有设mMaximumScreenOffTimeoutFromDeviceAdmin屏幕最大亮屏.
mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);//用于判断是否在充电
} else {
mStayOn = false;
}
if (mStayOn != wasStayOn) {
mDirty |= DIRTY_STAY_ON;
}
}
}
updateScreenBrightnessBoostLocked(mDirty);//更新屏幕亮度状态
以下逻辑可以理解为判断当前屏幕是否为最亮状态,如果是当前手机状态是最亮状态,发送一个延迟消息,回头再次进行判断。
如果不是,走到下面的mScreenBrightnessBoostInProgress设置为false,走到mNotifier.onScreenBrightnessBoostChanged();对屏幕状态变化进行设置
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);//发送一个延迟的消息,到最亮屏幕结束的时候接受到消息,将标志位置为DIRTY_SCREEN_BRIGHTNESS_BOOST后,重新再回到这个函数
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, boostTimeout);
return;
}
}
mScreenBrightnessBoostInProgress = false;//回到这个函数时,直接将这个屏幕最亮状态的标志位改成false
mNotifier.onScreenBrightnessBoostChanged();
userActivityNoUpdateLocked(now,
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
}
}
updateWakeLockSummaryLocked
//是根据PowerManagerService中所以的WackLock对象的类型,计算一个最终的类型集合
private void updateWakeLockSummaryLocked(int dirty) {
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
mWakeLockSummary = 0;
final int numWakeLocks = mWakeLocks.size();
for (int i = 0; i < numWakeLocks; i++) {
final WakeLock wakeLock = mWakeLocks.get(i);
switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {//先根据wakelock的flag,mWakeLockSummary或上各种状态
case PowerManager.PARTIAL_WAKE_LOCK://只保存CPU运行,屏幕背光和键盘背光关闭
if (!wakeLock.mDisabled) {
// We only respect this if the wake lock is not disabled.
mWakeLockSummary |= WAKE_LOCK_CPU;
}
break;
case PowerManager.FULL_WAKE_LOCK://CPU,屏幕背光和键盘背光都不关闭
mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
break;
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK://CPU和屏幕背光不关闭,键盘背光关闭
mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
break;
case PowerManager.SCREEN_DIM_WAKE_LOCK://CPU和屏幕背光不关闭,键盘背光关闭,但是CPU和屏幕背光可以变暗
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://让屏保管理器实现doze模式
mWakeLockSummary |= WAKE_LOCK_DOZE;
break;
case PowerManager.DRAW_WAKE_LOCK://让屏保管理器实现DRAW模式
mWakeLockSummary |= WAKE_LOCK_DRAW;
break;
}
}
// Cancel wake locks that make no sense based on the current state.
if (mWakefulness != WAKEFULNESS_DOZING) {
mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);//下面根据各种状态,将上面或上的mWakeLockSummary,有的减去
}
if (mWakefulness == WAKEFULNESS_ASLEEP
|| (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
| WAKE_LOCK_BUTTON_BRIGHT);
if (mWakefulness == WAKEFULNESS_ASLEEP) {
/* Power Key Force Wakeup to Keep Proximity Wakelock */
// 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) {//只要有屏幕锁,cpu锁必须持有
if (mWakefulness == WAKEFULNESS_AWAKE) {
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_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));
}
}
}
updateUserActivitySummaryLocked();//用于判断最后一次调用userActivity的时间,计算现在是否可以将表示屏幕状态的变量mUserActivitySummary的值设置为SCREEN_STATE_DIM(变暗)或者SCREEN_STATE_OFF(关闭)
备注userActivity用于用户进程向PowerManagerService报告当前用户影响休眠的时间
/**
* Updates the value of mUserActivitySummary to summarize the user requested
* state of the system such as whether the screen should be bright or dim.
* Note that user activity is ignored when the system is asleep.
*
* This function must have no other side-effects.
*/
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);
Slog.d(TAG+"zewei","updateUserActivitySummaryLocked" + "start");
long nextTimeout = 0;
/*状态为awake dreaming dozing,否则mUserActivitySummary = 0*/
if (mWakefulness == WAKEFULNESS_AWAKE
|| mWakefulness == WAKEFULNESS_DREAMING
|| mWakefulness == WAKEFULNESS_DOZING) {
final int sleepTimeout = getSleepTimeoutLocked();/*睡眠时间*/
final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);//灭屏的timeout
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);//屏幕由亮变暗的timeout
final int screenButtonLightDuration = getButtonLightDurationLocked(screenOffTimeout);
Slog.d(TAG+"zewei","updateUserActivitySummaryLocked" + "mWakefulness == WAKEFULNESS_AWAKE || mWakefulness == WAKEFULNESS_DREAMING || mWakefulness == WAKEFULNESS_DOZING wwwww "
+ "sleepTimeout == " + sleepTimeout +" " + "screenOffTimeout == " + screenOffTimeout + " " + "screenDimDuration ==" + screenDimDuration + " " + "screenButtonLightDuration == " + screenButtonLightDuration);
mUserActivitySummary = 0;
if (mLastUserActivityTime >= mLastWakeTime) {//userActivity的time大于上次唤醒的时间
if ( (mLastUserActivityButtonTime >= mLastWakeTime) && (now < mLastUserActivityButtonTime + screenButtonLightDuration) ) {
mUserActivitySummary |= USER_ACTIVITY_BUTTON_BRIGHT;
mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
nextTimeout = mLastUserActivityButtonTime + screenButtonLightDuration;
Slog.d(TAG+"zewei","updateUserActivitySummaryLocked" +"(mLastUserActivityButtonTime >= mLastWakeTime) && (now < mLastUserActivityButtonTime + screenButtonLightDuration) wwwww "
+ "nextTimeout == " + nextTimeout);
} else if (now < mLastUserActivityTime + screenOffTimeout - screenDimDuration) {
nextTimeout = mLastUserActivityTime + screenOffTimeout - screenDimDuration;//这个时间代表是比较亮的一个时间的结束点
mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
Slog.d(TAG+"zewei","updateUserActivitySummaryLocked" +"now < mLastUserActivityTime + screenOffTimeout - screenDimDuration wwwww "
+ "nextTimeout == " + nextTimeout);
} else {
nextTimeout = mLastUserActivityTime + screenOffTimeout;//这个时间代表是比较暗的一个时间的结束点
Slog.d(TAG+"zewei","else wwwww "
+ "nextTimeout == " + nextTimeout);
if (now < nextTimeout) {
mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
Slog.d(TAG+"zewei","mLastUserActivityTime >= mLastWakeTime wwwww");
}
}
}
if (mUserActivitySummary == 0
&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
Slog.d(TAG+"zewei","mUserActivitySummary == 0&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime wwwww " + "nextTimeout == " + nextTimeout);
if (now < nextTimeout) {
Slog.d(TAG+"zewei","mUserActivitySummary == 0&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime" + "now < nextTimeout wwwww ");
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) {
Slog.d(TAG+"zewei","mUserActivitySummary == 0 wwwww ");
if (sleepTimeout >= 0) {
final long anyUserActivity = Math.max(mLastUserActivityTime,
mLastUserActivityTimeNoChangeLights);
if (anyUserActivity >= mLastWakeTime) {
nextTimeout = anyUserActivity + sleepTimeout;
if (now < nextTimeout) {
mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
}
}
} else {
mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
nextTimeout = -1;//该值为-1,下面就不会发送消息了
Slog.d(TAG+"zewei","mUserActivitySummary == 0 wwwww " + "nextTimeout == " + nextTimeout);
}
}
if (mUserActivitySummary != 0 && nextTimeout >= 0) {
Slog.d(TAG+"zewei","mUserActivitySummary != 0 && nextTimeout >= 0 wwwww ");
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextTimeout);//到下个时间timeout结束的时候发送消息,重新进入这个函数
}
} else {
mUserActivitySummary = 0;
}
if (DEBUG_SPEW) {
Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
+ PowerManagerInternal.wakefulnessToString(mWakefulness)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
}
}
}
updateDreamLocked(dirtyPhase2, displayBecameReady);//判断是否启动屏保
private void updateDreamLocked(int dirty, boolean displayBecameReady) {
if ((dirty & (DIRTY_WAKEFULNESS
| DIRTY_USER_ACTIVITY
| DIRTY_WAKE_LOCKS
| DIRTY_BOOT_COMPLETED
| DIRTY_BOOT_IPO
| DIRTY_SETTINGS
| DIRTY_IS_POWERED
| DIRTY_STAY_ON
| DIRTY_SD_STATE
| DIRTY_PROXIMITY_POSITIVE
| DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
if (mDisplayReady) {
scheduleSandmanLocked();
}
}
}
Step 4:
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
updateSuspendBlockerLocked();//在sys/power 存储数据
private void updateSuspendBlockerLocked() {
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//看cpu是否要持锁
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();//现在Display没好,需要持Display的锁
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);//调用JNI
}
// First acquire suspend blockers if needed.、
//如果不能休眠,调用底层的wak_lock 函数
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.acquire();
mHoldingWakeLockSuspendBlocker = true;
}
//如果需要保持屏幕长亮,调用底层的wak_lock 函数
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);
}
}
Step 4:
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
接下来我们看下acquire和release方法的具体情况 @Override
public void acquire() {
synchronized (this) {
mReferenceCount += 1;
if (mReferenceCount == 1) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
}
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
nativeAcquireSuspendBlocker(mName);
}
}
}
@Override
public void release() {
synchronized (this) {
mReferenceCount -= 1;
if (mReferenceCount == 0) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
}
nativeReleaseSuspendBlocker(mName);
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
} else if (mReferenceCount < 0) {
Slog.wtf(TAG, "Suspend blocker \"" + mName
+ "\" was released without being acquired!", new Throwable());
mReferenceCount = 0;
}
}
}
Step 5:
frameworks\base\services\core\jni\com_android_server_power_PowerManagerService.cpp
接下来我们看下
nativeReleaseSuspendBlocker 在JNI层的实现
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}
static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
release_wake_lock(name.c_str());
}
Step 6:
hardware\libhardware_legacy\power\power.cconst char * const OLD_PATHS[] = {
"/sys/android_power/acquire_partial_wake_lock",
"/sys/android_power/release_wake_lock",
};
const char * const NEW_PATHS[] = {
"/sys/power/wake_lock",
"/sys/power/wake_unlock",
};
...
initialize_fds(void)
{
// XXX: should be this:
//pthread_once(&g_initialized, open_file_descriptors);
// XXX: not this:
if (g_initialized == 0) {
if(open_file_descriptors(NEW_PATHS) < 0)
open_file_descriptors(OLD_PATHS);
g_initialized = 1;
}
}
int
acquire_wake_lock(int lock, const char* id)
{
initialize_fds();
// ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);
if (g_error) return -g_error;
int fd;
if (lock == PARTIAL_WAKE_LOCK) {
fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
}
else {
return -EINVAL;
}
return write(fd, id, strlen(id));
}
int
release_wake_lock(const char* id)
{
initialize_fds();
// ALOGI("release_wake_lock id='%s'\n", id);
if (g_error) return -g_error;
ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));
return len >= 0;
}
Step 7:
至于kernel层与HAL层怎么进行交互的,我这边没有进行仔细分析了,但是通过搜索代码信息发现基本上走到这里处理wacklock
int pm_wake_lock(const char *buf)
{
const char *str = buf;
struct wakelock *wl;
u64 timeout_ns = 0;
size_t len;
int ret = 0;
if (!capable(CAP_BLOCK_SUSPEND))
return -EPERM;
while (*str && !isspace(*str))
str++;
len = str - buf;
if (!len)
return -EINVAL;
if (*str && *str != '\n') {
/* Find out if there's a valid timeout string appended. */
ret = kstrtou64(skip_spaces(str), 10, &timeout_ns);
if (ret)
return -EINVAL;
}
mutex_lock(&wakelocks_lock);
wl = wakelock_lookup_add(buf, len, true);
if (IS_ERR(wl)) {
ret = PTR_ERR(wl);
goto out;
}
if (timeout_ns) {
u64 timeout_ms = timeout_ns + NSEC_PER_MSEC - 1;
do_div(timeout_ms, NSEC_PER_MSEC);
__pm_wakeup_event(&wl->ws, timeout_ms);
} else {
__pm_stay_awake(&wl->ws);
}
wakelocks_lru_most_recent(wl);
out:
mutex_unlock(&wakelocks_lock);
return ret;
}
int pm_wake_unlock(const char *buf)
{
struct wakelock *wl;
size_t len;
int ret = 0;
if (!capable(CAP_BLOCK_SUSPEND))
return -EPERM;
len = strlen(buf);
if (!len)
return -EINVAL;
if (buf[len-1] == '\n')
len--;
if (!len)
return -EINVAL;
mutex_lock(&wakelocks_lock);
wl = wakelock_lookup_add(buf, len, false);
if (IS_ERR(wl)) {
ret = PTR_ERR(wl);
goto out;
}
__pm_relax(&wl->ws);
wakelocks_lru_most_recent(wl);
wakelocks_gc();
out:
mutex_unlock(&wakelocks_lock);
return ret;
}