PowerManagerService 提供Android系统的电源管理服务,主要功能是控制系统待机状态,屏幕显示,亮度调节,光线/距离传感器的控制等。
相关代码在以下文件中:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/os/PowerManager.java
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
frameworks/base/core/java/android/os/PowerManagerInternal.java
frameworks/base/services/core/java/com/android/server/power/Notifier.java
device/qcom/common/power/power.c
system/core/libsuspend/autosuspend.c
hardware/libhardware_legacy/power/power.c
跟其他系统服务一样,PowerManagerService也是继承于SystemService并通过SystemServer启动。
frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
......
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
......
}
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemService
implements Watchdog.Monitor {
......
}
在SystemServer的startBootstrapServices中,通过SystemServiceManager.startService启动了PowerManagerService,下面首先来看PowerManagerService构造方法。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public PowerManagerService(Context context) {
super(context);
// mContext赋值为SystemContext
mContext = context;
// 创建消息处理线程并启动,创建关联消息处理线程的handler对象
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
qcNsrmPowExt = new QCNsrmPowerExtension(this);
synchronized (mLock) {
// 创建"PowerManagerService.WakeLocks"的SuspendBlocker
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
// 创建"PowerManagerService.Display"的SuspendBlocker
mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
// 请求DisplaySuspendBlocker,禁止系统进入休眠
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
mHalAutoSuspendModeEnabled = false;
mHalInteractiveModeEnabled = true;
// 设置mWakefulness为唤醒状态
mWakefulness = WAKEFULNESS_AWAKE;
// 进入到native层初始化
nativeInit();
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
}
}
PowerManagerService构造函数中首先创建了处理消息的进程及对应的handler对象以进行消息处理,然后创建SuspendBlocker对象,用于WakeLocks与Display,
a、PowerManagerService.WakeLocks,主要用于控制CPU的唤醒;
b、PowerManagerService.Display 主要用于控制屏幕的点亮和熄灭;
并设置mWakefulness的初始状态为WAKEFULNESS_AWAKE,
最后进入到native层初始化。下面先看一下关于mWakefulness的定义。
继续回到PowerManagerService构造函数的native初始化中,首先来看nativeInit的实现。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static const JNINativeMethod gPowerManagerServiceMethods[] = {
/* name, signature, funcPtr */
{ "nativeInit", "()V",
(void*) nativeInit },
{ "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
(void*) nativeAcquireSuspendBlocker },
{ "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
(void*) nativeReleaseSuspendBlocker },
{ "nativeSetInteractive", "(Z)V",
(void*) nativeSetInteractive },
{ "nativeSetAutoSuspend", "(Z)V",
(void*) nativeSetAutoSuspend },
{ "nativeSendPowerHint", "(II)V",
(void*) nativeSendPowerHint },
{ "nativeSetFeature", "(II)V",
(void*) nativeSetFeature },
};
PowerManagerService中的native方法定义如上,nativeInit即调用nativeInit()。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeInit(JNIEnv* env, jobject obj) {
// 创建一个全局对象,引用PMS
gPowerManagerServiceObj = env->NewGlobalRef(obj);
// 利用hw_get_module加载power模块
status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
(hw_module_t const**)&gPowerModule);
if (!err) {
gPowerModule->init(gPowerModule);
} else {
ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
}
}
nativeInit的主要任务时装载power模块,该模块由厂商实现,以高通为例,如下。
device/qcom/common/power/power.c
tatic struct hw_module_methods_t power_module_methods = {
.open = NULL,
};
struct power_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = POWER_MODULE_API_VERSION_0_2,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = POWER_HARDWARE_MODULE_ID,
.name = "QCOM Power HAL",
.author = "Qualcomm",
.methods = &power_module_methods,
},
.init = power_init,
.powerHint = power_hint,
.setInteractive = set_interactive,
};
power_module中实现了init,powerHint,setInteractive,nativeInit最终调用到HAL power模块的power_init具体实现中。接着看native初始化nativeSetAutoSuspend的实现。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (enable) {
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
autosuspend_enable();
} else {
ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");
autosuspend_disable();
}
}
system/core/libsuspend/autosuspend.c
int autosuspend_disable(void)
{
int ret;
ret = autosuspend_init();
if (ret) {
return ret;
}
ALOGV("autosuspend_disable\n");
if (!autosuspend_enabled) {
return 0;
}
ret = autosuspend_ops->disable();
if (ret) {
return ret;
}
autosuspend_enabled = false;
return 0;
}
nativeSetAutoSuspend最终调用到libsuspend(参考Android电源管理系列之libsuspend)的autosuspend_disable禁止系统休眠。继续看native初始化nativeSetInteractive,nativeSetFeature的实现。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (gPowerModule) {
if (enable) {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
gPowerModule->setInteractive(gPowerModule, true);
} else {
ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
gPowerModule->setInteractive(gPowerModule, false);
}
}
}
static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
int data_param = data;
if (gPowerModule && gPowerModule->setFeature) {
gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param);
}
}
同nativeInit一样,最终都是调用到HAL power模块的具体实现中。以上是构造函数的分析流程,下面继续看PowerManagerService在系统启动过程中回调onStart(),onBootPhase(),systemReady()的实现。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void onStart() {
publishBinderService(Context.POWER_SERVICE, new BinderService());
publishLocalService(PowerManagerInternal.class, new LocalService());
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
private final class BinderService extends IPowerManager.Stub {
......
}
private final class LocalService extends PowerManagerInternal {
......
}
onStart()中发布了BinderService,LocalService分别供其他进程,进程内其他服务调用,并将PowerManagerService加入到Watchdog监控中。
在system启动的一些阶段,系统会调用如下代码,主动回调SystemService的onBootPhase方法。
mSystemServiceManager.startBootPhase(SystemService.PHASE_XXXXXX);
public class SystemServiceManager {
public void startBootPhase(final int phase) {
// 阶段值会随着系统启动的进行越来越大,因此下一个阶段值肯定要大于当前阶段
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase; //保存当前阶段
// 遍历所有的SystemService,并回调它的onBootPhase方法。
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
try {
service.onBootPhase(mCurrentPhase); // 将阶段值也传进去
} catch (Exception ex) {
...
}
}
}
}
PHASE_XXXXXX指示了各个不同的启动阶段,定义如下:
public abstract class SystemService {
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
public static final int PHASE_LOCK_SETTINGS_READY = 480;
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
public static final int PHASE_BOOT_COMPLETED = 1000;
}
所以,在onBootPhase(int phase)中,我们可以根据phase中指示的启动阶段,做不同的操作!在自己设计新的系统服务时,这个很重要。因为一些操作需要系统环境的支持,有了这个回调函数及phase参数,我们就可以在合适的阶段做合适的操作了。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void onBootPhase(int phase) {
synchronized (mLock) {
if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
......
} else if (phase == PHASE_BOOT_COMPLETED) {
final long now = SystemClock.uptimeMillis();
// 设置mBootCompleted状态
mBootCompleted = true;
mDirty |= DIRTY_BOOT_COMPLETED;
// 更新userActivity及PowerState,后面分析
userActivityNoUpdateLocked(
now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
// 执行mBootCompletedRunnables中的runnable方法
if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");
for (Runnable r : mBootCompletedRunnables) {
BackgroundThread.getHandler().post(r);
}
}
mBootCompletedRunnables = null;
}
}
}
onBootPhase中主要设置mBootCompleted状态,更新PowerState状态,并执行mBootCompletedRunnables中的runnables方法(低电量模式会设置)。
另外,Java系统服务中一般还会实现一个方法:systemReady()。该方法在SystemServer.java–>startOtherServices()调用:
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
mSystemReady = true;
// 获取AppOpsService
mAppOps = appOps;
// 获取DreamManager
mDreamManager = getLocalService(DreamManagerInternal.class);
// 获取DisplayManagerService
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mPolicy = getLocalService(WindowManagerPolicy.class);
// 获取mBatteryService
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
// 获取屏幕默认,最大,最小亮度
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
// 获取SensorManager
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
mBatteryStats = BatteryStatsService.getService();
// 创建Notifier对象,用于广播power state的变化
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
// 无线充电检测
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
// 监听设置的变化
mSettingsObserver = new SettingsObserver(mHandler);
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for settings changes.
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
......
IVrManager vrManager =
(IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
try {
vrManager.registerListener(mVrStateCallbacks);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to register VR mode state listener: " + e);
}
// 读取配置
readConfigurationLocked();
updateSettingsLocked();
mDirty |= DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
// 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);
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
}
userActivity()接口用于用户进程向PowerManagerService报告用户影响系统休眠的活动。例如, 用户点击屏幕时,系统会调用该方法来告诉PowerManagerService用户点击的时间,这样PowerManagerService将更新内部保存的时间值,从而推迟系统休眠的时间。userActivity()方法主要通过调用内部的userActivityInternal()方法来完成工作。
下面首先来看userActivity的定义。
frameworks/base/core/java/android/os/PowerManager.java
/**
* User activity event type: Unspecified event type.
*/
public static final int USER_ACTIVITY_EVENT_OTHER = 0;
/**
* User activity event type: Button or key pressed or released.
*/
public static final int USER_ACTIVITY_EVENT_BUTTON = 1;
/**
* User activity event type: Touch down, move or up.
*/
public static final int USER_ACTIVITY_EVENT_TOUCH = 2;
/**
* User activity event type: Accessibility taking action on behalf of user.
*/
public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3;
@SystemApi
public void userActivity(long when, int event, int flags) {
try {
mService.userActivity(when, event, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private final class BinderService extends IPowerManager.Stub {
......
public void userActivity(long eventTime, int event, int flags) {
final long now = SystemClock.uptimeMillis();
......
if (eventTime > now) {
throw new IllegalArgumentException("event time must not be in the future");
}
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
userActivityInternal(eventTime, event, flags, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
......
}
PowerManager中userActivity请求调用服务端PowerManagerService BinderService的userActivity,即调用内部方法userActivityInternal。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private void userActivityInternal(long eventTime, int event, int flags, int uid) {
synchronized (mLock) {
if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
updatePowerStateLocked();
}
}
}
userActivityInternal中首先调用userActivityNoUpdateLocked更新相关数据及状态(userActivityNoUpdateLocked仅仅更新内部状态并不采取任何操作),然后调用updatePowerStateLocked更新所有PowerState,下面分析userActivityNoUpdateLocked的实现,updatePowerStateLocked是PowerManagerService的核心方法,在最后进行分析。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
// 如果发生时间是上一次休眠或唤醒前,或当前没有开机完成到systemReady,不采取操作直接返回
if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
|| !mBootCompleted || !mSystemReady) {
return false;
}
try {
// 更新mLastInteractivePowerHintTime时间
if (eventTime > mLastInteractivePowerHintTime) {
powerHintInternal(POWER_HINT_INTERACTION, 0);
mLastInteractivePowerHintTime = eventTime;
}
// 通过mNotifier通知BatteryStats UserActivity事件
mNotifier.onUserActivity(event, uid);
if (mUserInactiveOverrideFromWindowManager) {
mUserInactiveOverrideFromWindowManager = false;
mOverriddenTimeout = -1;
}
// 已灭屏,或调用该方法带有USER_ACTIVITY_FLAG_INDIRECT,不会更新用户活动时间,不进行处理
if (mWakefulness == WAKEFULNESS_ASLEEP
|| mWakefulness == WAKEFULNESS_DOZING
|| (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
return false;
}
// 根据flag是否在已变暗的情况下是否重启活动超时更新mLastUserActivityTimeNoChangeLights或mLastUserActivityTime,带有USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS标记时,会延长亮屏一会儿
// 并且设置mDirty DIRTY_USER_ACTIVITY
if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
if (eventTime > mLastUserActivityTimeNoChangeLights
&& eventTime > mLastUserActivityTime) {
mLastUserActivityTimeNoChangeLights = eventTime;
mDirty |= DIRTY_USER_ACTIVITY;
return true;
}
} else {
if (eventTime > mLastUserActivityTime) {
mLastUserActivityTime = eventTime;
mDirty |= DIRTY_USER_ACTIVITY;
return true;
}
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return false;
}
1.何时发生UserActivity
如果我们在Settings中设置sleep时间为15s,那么15秒内如果没有任何操作,屏幕就会熄灭(当然,WakeLock被释放是前提)。如果在这个时间内用户有操作:touch屏幕或者按下菜单键、返回键等,那么这时就会调用PowerManagerService的UserActivity方法,这样会重置那个timeout的时间。
这里有三个重要的时间,参考下图:
首先是screenOffTimeout,一般地,就是设置中的sleep时间,用户可选,有15s、30s、1min、2mins等。device admin和window manager可以override这个时间(PowerManager提供了相应的接口),但是override有要求:必须大于10s,并小于设置中的15s,否则是无意义的,如果这里override了,那么这个就是最终的结果,如果没有override,那么以setting中的为准。在我们后来的讨论中都假设用户选择了15s,而且没有override,所以screenOffTimeout=15s。
其次是screenDimDuration,它代表屏幕亮度处于dim的持续时间(屏幕的变化:bright–dim–off),它是0.2 * 15s=3s。如果用户在settings中设置的不是15s,而是1min,那么1min * 0.2=12s,当大于7s时,取7s。
最后是screenButtonLightDuration,它代表button持续点亮的时间,是0.3 * 15s=4.5s,它也有最大值:8s。
好了,假设在屏幕点亮状态下,我按下了menu键会怎么样呢?会触发UserActivity,同时User activity event type是USER_ACTIVITY_EVENT_BUTTON,那么从按下menu键开始后,button处于点亮状态,screen处于bright首先button的背光持续4.5s点亮,之后熄灭,经过7.5s后screen由bright变为dim,持续3s后,screen off。