(本文讲解基于API23)
电源管理主要由PowerManagerService 负责, 那我们就先从 PowerManagerService讲起
PowerManagerService是系统核心服务之一, 由SystemServer 来启动。 首先我们看到SystemServer 类的main方法
SystemServer .java
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
从注释可以看出, zygote会启动这个main方法, 并new 一个SystemServer, 并知性run方法
在线程的run方法中,会启动各种系统服务, 其中与本文主题有关的代码如下:
SystemServer .java
@Override
public void run() {
......
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
}
在run方法中,会调用三个启动服务的方法, 其中startBootstrapServices 启动有相互依赖关系的服务, startCoreServices 启动一些没有相互依赖关系的核心服务, startOtherServices 启动其他服务
PowerManagerService 是在startBootstrapServices 中启动, 我们来一起看一下源码:
SystemServer .java
private void startBootstrapServices() {
......
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
......
}
private void startOtherServices() {
......
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
......
}
通过调用startService来启动PowerManagerService , 源码如下:
SystemServiceManager.java
public <T extends SystemService> T startService(Class<T> serviceClass) {
......
// Create the service.
......
final T service;
......
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
......
// Register it.
mServices.add(service);
// Start it.
......
service.onStart();
......
return service;
}
通过反射机制, 调用了PowerManagerService 的构造函数, 并注册到SystemService 中, 然后调用onStart 方法启动了PowerManagerService
下面看一下 PowerManagerService 的构造方法
PowerManagerService.java
public PowerManagerService(Context context) {
......
//建立handle,处理一下异步操作
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
mHalAutoSuspendModeEnabled = false;
mHalInteractiveModeEnabled = true;
mWakefulness = WAKEFULNESS_AWAKE;
nativeInit();
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
}
}
@Override
public void onStart() {
//注册binder服务
publishBinderService(Context.POWER_SERVICE, new BinderService());
//注册本地服务
publishLocalService(PowerManagerInternal.class, new LocalService());
//设置看门狗
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
......
// 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.
mBatteryStats = BatteryStatsService.getService();
......
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for broadcasts from other components of the system.
IntentFilter filter = new IntentFilter();
......
// Register for settings changes.
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false, mSettingsObserver, UserHandle.USER_ALL);
......
}
wakeLock 是应用程序获取电力资源的途径,, 只要还有地方在使用WakeLock , 系统就不会进入休眠状态。
WakeLock 通过 PowerManager 的 newWakeLock 方法获得。
public WakeLock newWakeLock(int levelAndFlags, String tag) {
// 验证参数是否正确
validateWakeLockParameters(levelAndFlags, tag);
// new一个新的WakeLock 对象
return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
}
WakeLock 的构造方法如下:
PowerManager.java--------------------------
WakeLock(int flags, String tag, String packageName) {
// flags参数用于控制休眠状态, 可选值
/*不受电源键影响, CPU on , 屏幕和键盘off PARTIAL_WAKE_LOCK
* 按下电源键会进入休眠,CPU 屏幕,键盘都工作 FULL_WAKE_LOCK
* 按下电源键会进入休眠, 屏幕变暗, 键盘关闭 SCREEN_DIM_WAKE_LOCK
* 按下电源键会进入休眠, 屏幕工作, 键盘关闭SCREEN_BRIGHT_WAKE_LOCK
* 当距离传感器发现被遮挡,关闭屏幕 PROXIMITY_SCREEN_OFF_WAKE_LOCK
* 用于来电提醒和提示框 ACQUIRE_CAUSES_WAKEUP
* WakeLock 释放之后屏幕不会立刻黑屏, 会延长一段时间 ON_AFTER_RELEASE */
mFlags = flags;
mTag = tag;
......
//建立一个Binder 作为token,并监视客户端生死情况
mToken = new Binder();
......
}
public void acquire() {
synchronized (mToken) {
acquireLocked();
}
}
private void acquireLocked() {
if (!mRefCounted || mCount++ == 0) {
// Do this even if the wake lock is already thought to be held (mHeld == true)
// because non-reference counted wake locks are not always properly released.
// For example, the keyguard's wake lock might be forcibly released by the
// power manager without the keyguard knowing. A subsequent call to acquire
// should immediately acquire the wake lock once again despite never having
// been explicitly released by the keyguard.
mHandler.removeCallbacks(mReleaser);
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
try {
mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
mHistoryTag);
} catch (RemoteException e) {
}
mHeld = true;
}
}
这里可以看到, 调用了PowerManagerService 里面的 acquireWakeLock
PowerManagerService.java ----------------------------------------------------
@Override // Binder call
public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag) {
......
//检查权限
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
......
//调用acquireWakeLockInternal
acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
......
}