PowerManagerService,DisplayPowerController,PhoneWindowManager之间的调用关系
在PowerManagerInternal中定义了四个类型
/**
* Wakefulness: The device is asleep. It can only be awoken by a call to wakeUp().
* The screen should be off or in the process of being turned off by the display controller.
* The device typically passes through the dozing state first.
*/
//表示系统当前处于休眠状态,只能被wakeUp()调用唤醒
public static final int WAKEFULNESS_ASLEEP = 0;
/**
* Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
* When the user activity timeout expires, the device may start dreaming or go to sleep.
*/
public static final int WAKEFULNESS_AWAKE = 1;
/**
* Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
* which ends the dream. The device goes to sleep when goToSleep() is called, when
* the dream ends or when unplugged.
* User activity may brighten the screen but does not end the dream.
*/
//表示系统当前正处于播放屏保的状态。
public static final int WAKEFULNESS_DREAMING = 2;
/**
* Wakefulness: The device is dozing. It is almost asleep but is allowing a special
* low-power "doze" dream to run which keeps the display on but lets the application
* processor be suspended. It can be awoken by a call to wakeUp() which ends the dream.
* The device fully goes to sleep if the dream cannot be started or ends on its own.
*/
//表示系统正处于“doze”状态。这种状态下只有低耗电的“屏保”可以运行,其他应用进程都被挂起。
public static final int WAKEFULNESS_DOZING = 3;
在PowerManagerService中最重要的就是updatePowerStateLocked方法
/**
* Updates the global power state based on dirty bits recorded in mDirty.
*
* This is the main function that performs power state transitions.
* We centralize them here so that we can recompute the power state completely
* each time something important changes, and ensure that we do it the same
* way each time. The point is to gather all of the transition logic here.
*/
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);
}
}
/**
* Updates the value of mIsPowered.
* Sets DIRTY_IS_POWERED if a change occurred.
*/
private void updateIsPoweredLocked(int dirty)
/**
* Updates the value of mStayOn.
* Sets DIRTY_STAY_ON if a change occurred.
*/
private void updateStayOnLocked(int dirty)
在for循环内最主要是三个更新状态
updateWakeLockSummaryLocked(dirtyPhase1);
updateUserActivitySummaryLocked(now, dirtyPhase1);
updateWakefulnessLocked(dirtyPhase1)
/**
* Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
* Note that most wake-locks are ignored when the system is asleep.
*
* This function must have no other side-effects.
*/
private void updateWakeLockSummaryLocked(int dirty)
遍历mWakeLocks集合中wakelock的数量,之后根据mFlags更新mWakeLockSummary的值,mWakeLockSummary是一个用来记录所有处于active状态WakeLock锁的标识值。
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) {
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;
}
}
//往下根据mWakefulness 的值如果不等于WAKEFULNESS_DOZING则将
//mWakeLockSummary中的mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);两个锁置位去掉。
// Cancel wake locks that make no sense based on the current state.
if (mWakefulness != WAKEFULNESS_DOZING) {
mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
}
//mWakefulness等于WAKEFULNESS_ASLEEP则将四个锁置位取反与去掉
//mWakeLockSummary等于WAKE_LOCK_DOZE则将三个锁置位取反与去掉
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) {
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) {
//mWakefulness 等于WAKEFULNESS_AWAKE唤醒则将 mWakeLockSummary 或上两个锁WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE。
if (mWakefulness == WAKEFULNESS_AWAKE) {
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
//mWakefulness等于WAKEFULNESS_DREAMING即处于屏保状态(dream)则或上WAKE_LOCK_CPU一个锁
} else if (mWakefulness == WAKEFULNESS_DREAMING) {
mWakeLockSummary |= WAKE_LOCK_CPU;
}
}
if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
mWakeLockSummary |= WAKE_LOCK_CPU;
}
}
}
/**
* 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);
long nextTimeout = 0;
if (mWakefulness == WAKEFULNESS_AWAKE
|| mWakefulness == WAKEFULNESS_DREAMING
|| mWakefulness == WAKEFULNESS_DOZING) {
final int sleepTimeout = getSleepTimeoutLocked();
//用户超时时间,即经过一段时间不活动进入休眠或屏保的时间,特殊情况外,该值为Settings中的休眠时长
final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
//Dim时长,即亮屏不操作,变暗多久休眠
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
mUserActivitySummary = 0;
if (mLastUserActivityTime >= mLastWakeTime) {
//下次睡眠时间=上次用户活动时间+休眠时间-Dim时间
nextTimeout = mLastUserActivityTime
+ screenOffTimeout - screenDimDuration;
//如果满足当前时间<下次屏幕超时时间,说明此时设备为亮屏状态,则将用户活动状态置为表示亮屏的USER_ACTIVITY_SCREEN_BRIGHT
if (now < nextTimeout) {
mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
} else {
nextTimeout = mLastUserActivityTime + screenOffTimeout;
//如果当前时间<上次活动时间+屏幕超时时间,这个值约为3s,说明此时设备为Dim状态,则将用户活动状态置为表示Dim的USER_ACTIVITY_SCREEN_DIM
if (now < nextTimeout) {
mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
}
}
}
...
...
...
if (mUserActivitySummary != 0 && nextTimeout >= 0) {
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
msg.setAsynchronous(true);
//发送定时Handler,到达时间后再次进行updatePowerStateLocked()
mHandler.sendMessageAtTime(msg, nextTimeout);
}
} else {
mUserActivitySummary = 0;
}
}
}
/**
* Updates the wakefulness of the device.
*
* This is the function that decides whether the device should start dreaming
* based on the current wake locks and user activity state. It may modify mDirty
* if the wakefulness changes.
*
* Returns true if the wakefulness changed and we need to restart power state calculation.
*/
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) {
//当前屏幕保持唤醒&&设备将要退出唤醒状态(睡眠or屏保)
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
final long time = SystemClock.uptimeMillis();
//是否在休眠时启用屏保
if (shouldNapAtBedTimeLocked()) {
//进入屏保,返回true
changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
} else {
//进入睡眠,返回true
changed = goToSleepNoUpdateLocked(time,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
}
}
}
return changed;
}
updateWakefulnessLocked用来判断跳出for的死循环
其中最主要的就是把一些参数信息封装进mDisplayPowerRequest,DisplayPowerRequest这个类是DisplayManageInternal类中的一个内部类,专门用于PowerManagerService和DisplayPowerController交互。
此处mDisplayManagerInternal.requestPowerState会在DisplayManagerService
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);
}
实际调用的是DisplayPowerController中的requestPowerState。
/**
* Updates the display power state asynchronously.
* When the update is finished, mDisplayReady will be set to true. The display
* controller posts a message to tell us when the actual display power state
* has been updated so we come back here to double-check and finish up.
*
* This function recalculates the display power state each time.
*
* @return True if the display became ready.
*/
private boolean updateDisplayPowerStateLocked(int dirty) {
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 | DIRTY_VR_MODE_CHANGED |
DIRTY_QUIESCENT)) != 0) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
// Determine appropriate screen brightness and auto-brightness adjustments.
...
...
// 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);
...
...
...
// Update display power request.
mDisplayPowerRequest.screenBrightness = screenBrightness;
mDisplayPowerRequest.screenAutoBrightnessAdjustment =
screenAutoBrightnessAdjustment;
mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
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);
mRequestWaitForNegativeProximity = false;
if ((dirty & DIRTY_QUIESCENT) != 0) {
sQuiescent = false;
}
}
return mDisplayReady && !oldDisplayReady;
}
PowerManagerService对应的JNI在com_android_server_power_PowerManagerService.cpp
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());
}
在hardware/libhardware_legacy/power.c中
const 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",
};
static int g_initialized = 0;
static int g_fds[OUR_FD_COUNT];
static int g_error = -1;
static int
open_file_descriptors(const char * const paths[])
{
int i;
for (i=0; i<OUR_FD_COUNT; i++) {
int fd = open(paths[i], O_RDWR | O_CLOEXEC);
if (fd < 0) {
g_error = -errno;
fprintf(stderr, "fatal error opening \"%s\": %s\n", paths[i],
strerror(errno));
return -1;
}
g_fds[i] = fd;
}
g_error = 0;
return 0;
}
static inline void
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;
size_t len;
ssize_t ret;
if (lock != PARTIAL_WAKE_LOCK) {
return -EINVAL;
}
fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
ret = write(fd, id, strlen(id));
if (ret < 0) {
return -errno;
}
return ret;
}
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));
if (len < 0) {
return -errno;
}
return len;
}
最后一个方法是updateSuspendBlockerLocked
mDecoupleHalAutoSuspendModeFromDisplayConfig:
该值表示是否将自动挂起状态和设备的屏幕显示状态(开/关)进行解耦。如果为false,则autosuspend_disable()函数会在屏幕亮之前调用,autosuspend_enable()函数会在屏幕灭之后调用,这种模式为使用传统电源管理功能的设备(如提前暂停/延迟恢复)提供最佳兼容性。如果为true,则autosuspend_display()和autosuspend_enable()将会被单独调用,不管屏幕正在亮或灭,这种模式使电源管理器可以在屏幕打开时挂起应用程序处理器。当指定了dozeComponent组件时,应将此资源设置为“true”,最大限度地节省电力,但并非所有设备都支持它。
mDecoupleHalInteractiveModeFromDisplayConfig:
表示是否将交互状态和设备的屏幕显示状态进行解耦。
如果为false,则当屏幕亮时调用setInteractive(…, true)函数,当屏幕灭时调用setInteractive(…, false)函数,此模式为希望将交互式状态绑定到显示状态的设备提供最佳兼容性。
如果为true,setInteractive()函数将会独立地调用,不管屏幕处于亮或灭,这种模式使电源管理器可以在显示器打开时减少时钟并禁用触摸控制器
private void updateSuspendBlockerLocked() {
//是否需要保持CPU活动状态的SuspendBlocker锁,具体表现为持有Partical WakeLock
final boolean needWakeLockSuspendBlocker =
((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
//是否需要保持CPU活动状态的SuspendBlocker锁,具体表现保持屏幕亮
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
//是否自动挂起,如果不需要屏幕保持唤醒,则说明可以自动挂起CPU
final boolean autoSuspend = !needDisplaySuspendBlocker;
//是否处于交互模式,屏幕处于Bright或者Dim状态时为true
final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
//mDecoupleHalAutoSuspendModeFromDisplayConfig:自动挂起模式和显示状态解偶
if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
//禁止CPU自动挂起模式
setHalAutoSuspendModeLocked(false);
}
//如果存在PARTIAL_WAKE_LOCK类型的WakeLock,申请mWakeLockSuspendBlocker锁
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.acquire();
mHoldingWakeLockSuspendBlocker = true;
}
//如果当前屏幕需要保持亮屏,申请mDisplaySuspendBlocker锁
if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
}
//
if (mDecoupleHalInteractiveModeFromDisplayConfig) {
//设置Hal层交互模式
if (interactive || mDisplayReady) {
//
setHalInteractiveModeLocked(interactive);
}
}
//如果不再持有PARTIAL_WAKELOCK类型的WakeLock锁,释放mWakeLockSuspendBlocker锁
if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.release();
mHoldingWakeLockSuspendBlocker = false;
}
//如果不再需要屏幕保持亮屏,释放mDisplaySuspendBlocker锁
if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.release();
mHoldingDisplaySuspendBlocker = false;
}
//启动自动挂起模式
if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
}