这一节主要了解PowerManager,在Android系统中,电源管理是基于Linux电源管理的轻量级Android电源管理。电源管理主要是通过锁和定时器来切换系统的状态,使系统的功耗降至最低。Android系统的Framework层是接口层,为上面的应用层提供拿来即用的接口。
在Android Power Management系统中,Framework层涉及如下所示的文件:
/frameworks/base/core/java/android/os/PowerManager.java
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
PowerManager类
文件 PowerManager.java是提供给应用层调用的,最终的核心实现在文件 PowerManagerService中实现。在此文件PowerManager.java中定义了android.os.PowerManager,功能是控制设备的电源状态的切换。当通过函数 getSystemService(Context.POWER_SERVICE)获取PowerManager对象的时候,是通过构造函数 PowerManager(IPowerManagerservice,Handlerhandler){}来创建并获取的,而此IPowerManager 则是创建PowerManager实例的核心,而IPowerManager则是由PowerManagerService实现,所以,从本质上说PowerManager的大部分方法是由PowerManager Service实现的。
(1)定义类PowerManager和接口函数,具体代码如下所示:
/frameworks/base/core/java/android/os/PowerManager.java
@SystemService(Context.POWER_SERVICE)
public final class PowerManager {
@Deprecated
public static final int FULL_WAKE_LOCK = 0x0000001a;
public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;
public static final int DOZE_WAKE_LOCK = 0x00000040;
/**
* Brightness value for fully on.
* @hide
*/
public static final int BRIGHTNESS_ON = 255;
public static final int BRIGHTNESS_OFF = 0;
public static final int BRIGHTNESS_DEFAULT = -1;
...
}
(2)定义对外接口函数,以实现对电源状态的控制管理。其中函数goToSleep的功能是强制设备进入Sleep状态,函数wakeUp的功能是强制设备进入wakeUp状态:
public void goToSleep(long time) {
goToSleep(time, GO_TO_SLEEP_REASON_APPLICATION, 0);
}
public void goToSleep(long time, int reason, int flags) {
try {
mService.goToSleep(time, reason, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public void wakeUp(long time) {
try {
mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
(3)定义函数userActivity,功能是当发生User activity 事件时,电源设备会被切换到Full on的状态,并同时Reset Screen offtimer,具体代码如下所示:
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.DEVICE_POWER,
android.Manifest.permission.USER_ACTIVITY
})
public void userActivity(long when, int event, int flags) {
try {
mService.userActivity(when, event, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
提供PowerlManager功能
文件 PowerManagerService.java 是Power Management 系统中整个Framework 层文件的核心,这个类的作用就是提供PowerManager 的功能,以及整个电源管理状态机的运行。PowerManagerService服务是Android系统的上层的电源管理服务,主要负责系统待机、屏幕背光、按键背光、键盘背光以及用户事件的处理。通过锁的申请与释放,以及默认的待机时间来控制系统的待机状态;通过系统默认关闭屏的时间,以及用户操作的事件状态控制背光的亮和暗。另外,PowerManagerService 服务还包括了光线、距离传感器上层查询与控制,LCD亮度的调节最终也是由该服务完成。来看一下PowerManagerService.java的具体实现过程。
定义常量和变量
/**
* The power manager service is responsible for coordinating power management
* functions on the device.
*/
public final class PowerManagerService extends SystemService
implements Watchdog.Monitor {
...
// Summarizes the state of all active wakelocks.
private static final int WAKE_LOCK_CPU = 1 << 0;
private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
private static final int WAKE_LOCK_DOZE = 1 << 6;
private static final int WAKE_LOCK_DRAW = 1 << 7;
// Summarizes the user activity state.
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
// Default timeout in milliseconds. This is only used until the settings
// provider populates the actual default value (R.integer.def_screen_off_timeout).
private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
private static final int DEFAULT_SLEEP_TIMEOUT = -1;
// A bitfield that indicates what parts of the power state have
// changed and need to be recalculated.
private int mDirty;
// Indicates whether the device is awake or asleep or somewhere in between.
// This is distinct from the screen power state, which is managed separately.
private int mWakefulness;
}
mDirty:功能是表示power state的变化,在系统中一共定义了12个与之类似的变化,每一个state对应一个固定的数字,都是2的倍数。这样,当有若干个状态一起变化时就会按位取或,这样不但会得到一个唯一的结果,而且可以准确地标示出各个状态的变化。
mWakefulness:功能是标示device处于是醒着的、还是睡眠中的状态,或者处于两者之间的一种状态。这个状态是和 display的电源状态不同的,display 的电源状态是独立管理的。这个变量用来标示DIRTY_WAKEFULNESS这个power state 下的一个具体的内容。例如,当系统进入Draaming时,首先变化的是mDirty,在mDirty中监听DIRTY WAKEFULNESS的位置是否发生了变化,此时只是知道,DIRTY_WAKEFULNESS发生了变化,并不知道DIRTY_WAKEFULNESS发生了怎样的变化,并不知道 wakefulness 发生了怎样的变化。如果需要进一步了解系统wakefulness变成了什么,则需要查看mWakefulness的内容。
开机启动及处理
(1)当Android系统启动时,会调用文件SystemServer.java中的接口函数run,在此函数中将power服务加入到系统服务中,具体代码如下所示:
private void startBootstrapServices() {
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
}
与系统其他模块之间的交互
BatteryReceiver->handleBatteryStateChangedLocked() ACTION_BATTERY_CHANGED
DreamReceiver -> scheduleSandmanLocked() ACTION_DREAMING_STARTED ACTION_DREAMING_STOPPED
UserSwitchedReceiver -> handleSettingsChangedLocked() ACTION_USER_SWITCHED
DockReceiver -> updatePowerStateLocked(); ACTION_DOCK_EVENT
在文件PowerManagerService.java 中除了注册上述4个Receiver 之外,还定义了一个SettingsObserver 以监视系统中以下属性的变化。
SCREENSAVER_ENABLED:屏保的功能开启。
SCREENSAVER_ACTIVATE_ON_SLEEP:在睡眠时屏保启动。
SCREENSAVER_ACTIVE_ON_DOCK:连接底座并且屏保启动。
SCREEN_OFF_TIMEOUT:休眠时间。
STAY_ON_WHILE_PLUGGED_IN:有硬件插入并且屏幕开启。
SCREEN_BRIGHTNESS:屏幕的亮度。
SCREEN_BRIGHTNESS_MODE:屏幕亮度的模式。
分析:SettingObserver会监视到上述属性发生的变化,并且会调用SettingObserver中的onChange方法:
private final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
synchronized (mLock) {
handleSettingsChangedLocked();
}
}
}
可见,PowerManagerService不但能够接收用户的请求,被动地去做一些操作,而且还要主动地监视系统中一些重要属性的变化和重要事件的发生。无论是处理主动还是被动的操作,都会有对应的处理函数。