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<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();.//从这个函数中读取哪个系统应用允许在idle状态下 for (int i=0; i<allowPowerExceptIdle.size(); i++) { String pkg = allowPowerExceptIdle.valueAt(i); try { ApplicationInfo ai = pm.getApplicationInfo(pkg, 0); if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { int appid = UserHandle.getAppId(ai.uid); mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); } } catch (PackageManager.NameNotFoundException e) { } } ArraySet<String> allowPower = sysConfig.getAllowInPowerSave(); for (int i=0; i<allowPower.size(); i++) { String pkg = allowPower.valueAt(i); try { ApplicationInfo ai = pm.getApplicationInfo(pkg, 0); if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { int appid = UserHandle.getAppId(ai.uid); // These apps are on both the whitelist-except-idle as well // as the full whitelist, so they apply in all cases. mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid); mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true); mPowerSaveWhitelistApps.put(ai.packageName, appid); mPowerSaveWhitelistSystemAppIds.put(appid, true); } } catch (PackageManager.NameNotFoundException e) { } } mConstants = new Constants(mHandler, getContext().getContentResolver()); readConfigFileLocked();//读取deviceidle.xml把用户应用存入内存 updateWhitelistAppIdsLocked();//把所有的白名单的app发给PowerManagerService mScreenOn = true; // Start out assuming we are charging. If we aren't, we will at least get // a battery update the next time the level drops. mCharging = true; mState = STATE_ACTIVE; mInactiveTimeout = mConstants.INACTIVE_TIMEOUT; } publishBinderService(Context.DEVICE_IDLE_CONTROLLER, new BinderService()); publishLocalService(LocalService.class, new LocalService()); }
我们再来看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 <config>: " + 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: <bool name="config_enableAutoPowerModes">false</bool>改成true,该功能就默认打开了。
这样DeviceIdelController的逻辑大致讲完了,比较细节的东西大家要自己跟了。后续还会讲下PowerManagerService中的白名单,和设置idle状态。以及AlarmManagerService的setIdleUntil函数。