Android6.0上power改动比较大,粗略的看PowerManagerService的话感觉变动不大,只是在PowerManagerService的改动代码比较少,但是其实质改动较大,特别增加了这个DeviceIdleController,来控制设备的Idle状态。而当设备在idle状态时,它会忽略cpu的wakelock,Alarm等。
因此DeviceIdleController在power中的地位也是相当重要。
mSystemServiceManager.startService(DeviceIdleController.class);
在SystemServer中启动该服务。
我们先看下其构造函数:
public DeviceIdleController(Context context) {
super(context);
mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
}
private static File getSystemDir() {
return new File(Environment.getDataDirectory(), "system");
}
构造函数中,新建了一个file 是data/system/deviceidle.xml文件,然后新建了一个handler。
下面我们再看下onStart函数
@Override
public void onStart() {
final PackageManager pm = getContext().getPackageManager();
synchronized (this) {
mEnabled = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enableAutoPowerModes);
SystemConfig sysConfig = SystemConfig.getInstance();
ArraySet allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();.//从这个函数中读取哪个系统应用允许在idle状态下
for (int i=0; i allowPower = sysConfig.getAllowInPowerSave();
for (int i=0; i
我们再来看readConfigFileLocked来解析deviceidle.xml文件
void readConfigFileLocked() {
if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile());
mPowerSaveWhitelistUserApps.clear();
FileInputStream stream;
try {
stream = mConfigFile.openRead();
} catch (FileNotFoundException e) {
return;
}
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
readConfigFileLocked(parser);
} catch (XmlPullParserException e) {
} finally {
try {
stream.close();
} catch (IOException e) {
}
}
}
private void readConfigFileLocked(XmlPullParser parser) {
final PackageManager pm = getContext().getPackageManager();
try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
throw new IllegalStateException("no start tag found");
}
int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("wl")) {
String name = parser.getAttributeValue(null, "n");
if (name != null) {
try {
ApplicationInfo ai = pm.getApplicationInfo(name, 0);
mPowerSaveWhitelistUserApps.put(ai.packageName,//把解析出来的app放入这个变量
UserHandle.getAppId(ai.uid));
} catch (PackageManager.NameNotFoundException e) {
}
}
} else {
Slog.w(TAG, "Unknown element under : "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
下面我们再来看看updateWhitelistAppIdsLocked如何把白名单传给PowerManagerService
private void updateWhitelistAppIdsLocked() {
mPowerSaveWhitelistExceptIdleAppIdArray = buildAppIdArray(mPowerSaveWhitelistAppsExceptIdle,
mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds);
mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps,
mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
if (mLocalPowerManager != null) {
if (DEBUG) {
Slog.d(TAG, "Setting wakelock whitelist to "
+ Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
}
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
}
}
至于PowerManagerService的设置白名单函数,我们在后续博客分析。这边只要记住把白名单发给了PowerManagerService。
下面我们再来看看onBootPhase函数
public void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {//系统service启动好
synchronized (this) {
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
mBatteryStats = BatteryStatsService.getService();
mLocalPowerManager = getLocalService(PowerManagerInternal.class);
mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
mDisplayManager = (DisplayManager) getContext().getSystemService(
Context.DISPLAY_SERVICE);
mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
mSigMotionSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
mLocationManager = (LocationManager) getContext().getSystemService(
Context.LOCATION_SERVICE);
mLocationRequest = new LocationRequest()
.setQuality(LocationRequest.ACCURACY_FINE)
.setInterval(0)
.setFastestInterval(0)
.setNumUpdates(1);
mAnyMotionDetector = new AnyMotionDetector(//移动监测
(PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
mHandler, mSensorManager, this);
Intent intent = new Intent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0);//定义pendingIntent
Intent intentSensing = new Intent(ACTION_STEP_IDLE_STATE)
.setPackage("android")
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mSensingAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intentSensing, 0);
mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver, filter);//注册registerReceiver
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);//设置白名单
mDisplayManager.registerDisplayListener(mDisplayListener, null);//在displayManager中注册回调
updateDisplayLocked();
}
}
}
我们再来看DisplayListener和电池变化广播
private final DisplayManager.DisplayListener mDisplayListener
= new DisplayManager.DisplayListener() {
@Override public void onDisplayAdded(int displayId) {
}
@Override public void onDisplayRemoved(int displayId) {
}
@Override public void onDisplayChanged(int displayId) {
if (displayId == Display.DEFAULT_DISPLAY) {
synchronized (DeviceIdleController.this) {
updateDisplayLocked();
}
}
}
};
收到显示变化,调用updateDisplayLocked函数
void updateDisplayLocked() {
mCurDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
// We consider any situation where the display is showing something to be it on,
// because if there is anything shown we are going to be updating it at some
// frequency so can't be allowed to go into deep sleeps.
boolean screenOn = mCurDisplay.getState() == Display.STATE_ON;
if (DEBUG) Slog.d(TAG, "updateDisplayLocked: screenOn=" + screenOn);
if (!screenOn && mScreenOn) {
mScreenOn = false;
if (!mForceIdle) {//mForceIdle是dumpsys设置的
becomeInactiveIfAppropriateLocked();//灭屏
}
} else if (screenOn) {
mScreenOn = true;
if (!mForceIdle) {
becomeActiveLocked("screen", Process.myUid());//亮屏
}
}
}
电池变化会调用updateChargingLocked函数
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
int plugged = intent.getIntExtra("plugged", 0);
updateChargingLocked(plugged != 0);
} else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
}
}
}
};
updateChargingLocked函数逻辑和显示的差不多
void updateChargingLocked(boolean charging) {
if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
if (!charging && mCharging) {
mCharging = false;
if (!mForceIdle) {
becomeInactiveIfAppropriateLocked();
}
} else if (charging) {
mCharging = charging;
if (!mForceIdle) {
becomeActiveLocked("charging", Process.myUid());
}
}
}
我们再来看看becomeInactiveIfAppropriateLocked函数:
void becomeInactiveIfAppropriateLocked() {
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
if (((!mScreenOn && !mCharging) || mForceIdle) && mEnabled && mState == STATE_ACTIVE) {
// Screen has turned off; we are now going to become inactive and start
// waiting to see if we will ultimately go idle.
mState = STATE_INACTIVE;//改变状态
if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
resetIdleManagementLocked();//各种重置
scheduleAlarmLocked(mInactiveTimeout, false);
EventLogTags.writeDeviceIdle(mState, "no activity");
}
}
这个函数,当屏幕灭屏,不充电 mEnabled开启,并且状态是Active下进入判断。而mEnabled是默认关闭着,也就是这个类的功能是默认关闭着。
void scheduleAlarmLocked(long delay, boolean idleUntil) {
if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
if (mSigMotionSensor == null) {
// If there is no significant motion sensor on this device, then we won't schedule
// alarms, because we can't determine if the device is not moving. This effectively
// turns off normal exeuction of device idling, although it is still possible to
// manually poke it by pretending like the alarm is going off.
return;
}
mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
if (idleUntil) {
mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mNextAlarmTime, mAlarmIntent);
} else {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mNextAlarmTime, mAlarmIntent);
}
}
scheduleAlarmLocked函数会去设置一个Alarm,setIdleUntil和普通set区别是,当设备进入idle状态的时候只要setIdleUntil才会生效,具体后续需要分析AlarmManagerService。
收到Alarm的广播后会调用stepIdleStateLocked函数:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
int plugged = intent.getIntExtra("plugged", 0);
updateChargingLocked(plugged != 0);
} else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
}
}
}
};
stepIdleStateLocked函数
void stepIdleStateLocked() {
if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
EventLogTags.writeDeviceIdleStep();
final long now = SystemClock.elapsedRealtime();
if ((now+mConstants.MIN_TIME_TO_ALARM) > mAlarmManager.getNextWakeFromIdleTime()) {
// Whoops, there is an upcoming alarm. We don't actually want to go idle.
if (mState != STATE_ACTIVE) {
becomeActiveLocked("alarm", Process.myUid());
}
return;
}
switch (mState) {
case STATE_INACTIVE:
// We have now been inactive long enough, it is time to start looking
// for significant motion and sleep some more while doing so.
startMonitoringSignificantMotion();
scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);//设置alarm,到时间转到下一个状态
// Reset the upcoming idle delays.
mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
mNextIdleDelay = mConstants.IDLE_TIMEOUT;
mState = STATE_IDLE_PENDING;
if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
EventLogTags.writeDeviceIdle(mState, "step");
break;
}
我们再来看看startMonitoringSignificantMotion函数
void startMonitoringSignificantMotion() {
if (DEBUG) Slog.d(TAG, "startMonitoringSignificantMotion()");
if (mSigMotionSensor != null && !mSigMotionActive) {
mSensorManager.requestTriggerSensor(mSigMotionListener, mSigMotionSensor);
mSigMotionActive = true;
}
}
看下mSigMotionListener 回调
private final TriggerEventListener mSigMotionListener = new TriggerEventListener() {
@Override public void onTrigger(TriggerEvent event) {
synchronized (DeviceIdleController.this) {
significantMotionLocked();
}
}
};
significantMotionLocked函数:
void significantMotionLocked() {
if (DEBUG) Slog.d(TAG, "significantMotionLocked()");
// When the sensor goes off, its trigger is automatically removed.
mSigMotionActive = false;
handleMotionDetectedLocked(mConstants.MOTION_INACTIVE_TIMEOUT, "motion");
}
void handleMotionDetectedLocked(long timeout, String type) {
// The device is not yet active, so we want to go back to the pending idle
// state to wait again for no motion. Note that we only monitor for significant
// motion after moving out of the inactive state, so no need to worry about that.
if (mState != STATE_ACTIVE) {//这基本是重置idle状态
scheduleReportActiveLocked(type, Process.myUid());//取消idle状态
mState = STATE_ACTIVE;
mInactiveTimeout = timeout;
EventLogTags.writeDeviceIdle(mState, type);
becomeInactiveIfAppropriateLocked();//这是重新开始idle状态流程
}
}
scheduleReportActiveLocked函数
void scheduleReportActiveLocked(String activeReason, int activeUid) {
Message msg = mHandler.obtainMessage(MSG_REPORT_ACTIVE, activeUid,
mState == STATE_IDLE ? 1 : 0, activeReason);
mHandler.sendMessage(msg);
}
再看下消息处理:
case MSG_REPORT_ACTIVE: {
String activeReason = (String)msg.obj;
int activeUid = msg.arg1;
boolean needBroadcast = msg.arg2 != 0;
EventLogTags.writeDeviceIdleOffStart(
activeReason != null ? activeReason : "unknown");
mLocalPowerManager.setDeviceIdleMode(false);//取消idle状态
try {
mNetworkPolicyManager.setDeviceIdleMode(false);
mBatteryStats.noteDeviceIdleMode(false, activeReason, activeUid);
} catch (RemoteException e) {
}
if (needBroadcast) {
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
}
EventLogTags.writeDeviceIdleOffComplete();
} break;
在消息处理中取消了idle状态
继续看idle流程的下一个状态
case STATE_IDLE_PENDING:
mState = STATE_SENSING;
if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
EventLogTags.writeDeviceIdle(mState, "step");
scheduleSensingAlarmLocked(mConstants.SENSING_TIMEOUT);//设置了Alarm,有取消了
cancelSensingAlarmLocked();
cancelLocatingLocked();
mAnyMotionDetector.checkForAnyMotion();//开启是否移动检测
mNotMoving = false;
mLocated = false;
mLastGenericLocation = null;
mLastGpsLocation = null;
break;
看下是否移动检测的checkForAnyMotion函数
public void checkForAnyMotion() {
if (DEBUG) Slog.d(TAG, "checkForAnyMotion(). mState = " + mState);
if (mState != STATE_ACTIVE) {
mState = STATE_ACTIVE;
if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_ACTIVE.");
mCurrentGravityVector = null;
mPreviousGravityVector = null;
startOrientationMeasurement();
}
}
startOrientationMeasurement函数
private void startOrientationMeasurement() {
if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" +
mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null));
if (!mMeasurementInProgress && mAccelSensor != null) {
if (mSensorManager.registerListener(mListener, mAccelSensor,//注册sensor
SAMPLING_INTERVAL_MILLIS * 1000)) {
mWakeLock.acquire();
mMeasurementInProgress = true;
mRunningStats.reset();
}
Message msg = Message.obtain(mHandler, mMeasurementTimeout);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ACCELEROMETER_DATA_TIMEOUT_MILLIS);//延迟3秒发送
}
}
mMeasurementTimeout是一个Runnable
private final Runnable mMeasurementTimeout = new Runnable() {
@Override
public void run() {
int status = RESULT_UNKNOWN;
synchronized (mLock) {
if (DEBUG) Slog.i(TAG, "mMeasurementTimeout. Failed to collect sufficient accel " +
"data within " + ACCELEROMETER_DATA_TIMEOUT_MILLIS + " ms. Stopping " +
"orientation measurement.");
status = stopOrientationMeasurementLocked();//停止检测
}
if (status != RESULT_UNKNOWN) {
mCallback.onAnyMotionResult(status);//把结果返回到DeviceIdleController的回调
}
}
再看下注册的sensor的listener的mListener,也是类似的有sensor数据过来会不断的调用DeviceIdleController的回调。
private final SensorEventListener mListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
int status = RESULT_UNKNOWN;
synchronized (mLock) {
Vector3 accelDatum = new Vector3(SystemClock.elapsedRealtime(), event.values[0],
event.values[1], event.values[2]);
mRunningStats.accumulate(accelDatum);
// If we have enough samples, stop accelerometer data acquisition.
if (mRunningStats.getSampleCount() >= mNumSufficientSamples) {
status = stopOrientationMeasurementLocked();
}
}
if (status != RESULT_UNKNOWN) {
mCallback.onAnyMotionResult(status);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
每次检测是否运动检测3秒结束。
下面再来看DeviceIdleController的onAnyMotionResult函数
@Override
public void onAnyMotionResult(int result) {
if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")");
if (result == AnyMotionDetector.RESULT_MOVED) {//检测是运动的
if (DEBUG) Slog.d(TAG, "RESULT_MOVED received.");
synchronized (this) {
handleMotionDetectedLocked(mConstants.INACTIVE_TIMEOUT, "sense_motion");//这个函数上面分析过重置idle状态
}
} else if (result == AnyMotionDetector.RESULT_STATIONARY) {//是停止的
if (DEBUG) Slog.d(TAG, "RESULT_STATIONARY received.");
if (mState == STATE_SENSING) {
// If we are currently sensing, it is time to move to locating.
synchronized (this) {
mNotMoving = true;
stepIdleStateLocked();
}
} else if (mState == STATE_LOCATING) {
// If we are currently locating, note that we are not moving and step
// if we have located the position.
synchronized (this) {
mNotMoving = true;
if (mLocated) {//如果已经定位好了,那就走下一个流程
stepIdleStateLocked();
}
}
}
}
}
检测是运动的重置idle的状态,如果是禁止的继续stepIdleStateLocked函数流程。如果检测3秒没有移动的话,也就idle没有重置,继续流程最后就进入idle状态了。
case STATE_SENSING:
mState = STATE_LOCATING;
if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
EventLogTags.writeDeviceIdle(mState, "step");
cancelSensingAlarmLocked();
scheduleSensingAlarmLocked(mConstants.LOCATING_TIMEOUT);//设置一个Alarm
mLocating = true;
mLocationManager.requestLocationUpdates(mLocationRequest, mGenericLocationListener,
mHandler.getLooper());
if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
mHaveGps = true;
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
mGpsLocationListener, mHandler.getLooper());
} else {
mHaveGps = false;
}
break;
case STATE_LOCATING:// 如果上面定位好了,又检测到静止的,就直接到这状态。或者等下个Alarm。
cancelSensingAlarmLocked();
cancelLocatingLocked();
mAnyMotionDetector.stop();
最后就到这两个状态
case STATE_IDLE_MAINTENANCE:
scheduleAlarmLocked(mNextIdleDelay, true);//注意这个参数是true,设置Alarm的最后接口是setIdleUntil,后续分析
if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
" ms.");
mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
if (DEBUG) Slog.d(TAG, "Setting mNextIdleDelay = " + mNextIdleDelay);
mNextIdleDelay = Math.min(mNextIdleDelay, mConstants.MAX_IDLE_TIMEOUT);
mState = STATE_IDLE;
EventLogTags.writeDeviceIdle(mState, "step");
mHandler.sendEmptyMessage(MSG_REPORT_IDLE_ON);
break;
case STATE_IDLE:
// We have been idling long enough, now it is time to do some work.
scheduleAlarmLocked(mNextIdlePendingDelay, false);
if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
"Next alarm in " + mNextIdlePendingDelay + " ms.");
mNextIdlePendingDelay = Math.min(mConstants.MAX_IDLE_PENDING_TIMEOUT,
(long)(mNextIdlePendingDelay * mConstants.IDLE_PENDING_FACTOR));
mState = STATE_IDLE_MAINTENANCE;
EventLogTags.writeDeviceIdle(mState, "step");
mHandler.sendEmptyMessage(MSG_REPORT_IDLE_OFF);
break;
MSG_REPORT_IDLE_ON处理调用了setDeviceIdleMode(true)设置了设备的Idle状态。
case MSG_REPORT_IDLE_ON: {
EventLogTags.writeDeviceIdleOnStart();
mLocalPowerManager.setDeviceIdleMode(true);
try {
mNetworkPolicyManager.setDeviceIdleMode(true);//关闭网络
mBatteryStats.noteDeviceIdleMode(true, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
EventLogTags.writeDeviceIdleOnComplete();
} break;
而过了一段时间后,Alarm起来又到了STATE_IDLE: 最后发送了MSG_REPORT_IDLE_OFF消息
case MSG_REPORT_IDLE_OFF: {
EventLogTags.writeDeviceIdleOffStart("unknown");
mLocalPowerManager.setDeviceIdleMode(false);//取消了idle状态
try {
mNetworkPolicyManager.setDeviceIdleMode(false);//开启网络
mBatteryStats.noteDeviceIdleMode(false, null, Process.myUid());
} catch (RemoteException e) {
}
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
EventLogTags.writeDeviceIdleOffComplete();
} break;
在这个消息处理中又取消了设备的Idle状态。
这个功能是默认关闭着,mEnabled是false。如何想打开的话:
framework/base/core/res/values/config.xml:167: false
改成true,该功能就默认打开了。
这样DeviceIdelController的逻辑大致讲完了,比较细节的东西大家要自己跟了。后续还会讲下PowerManagerService中的白名单,和设置idle状态。以及AlarmManagerService的setIdleUntil函数。