Android6.0 DeviceIdle服务分析

Android6.0以后引入了Doze和Standby省电模式,看了下源码,主要体现在DeviceIdle服务中。

DeviceIdle采用了定时器驱动的状态机方式来推进不同状态之间的变化。状态变化如下图:


Android6.0 DeviceIdle服务分析_第1张图片
状态变化

下面对照图详细展开来说。

先看一下nexus6p实际dumpsys的结果:

# dumpsys deviceidle
  Settings:
    inactive_to=+30m0s0ms
    sensing_to=+60s0ms
    locating_to=+15s0ms
    location_accuracy=20.0m
    motion_inactive_to=+10m0s0ms
    idle_after_inactive_to=+30m0s0ms
    idle_pending_to=+5m0s0ms
    max_idle_pending_to=+10m0s0ms
    idle_pending_factor=2.0
    idle_to=+60m0s0ms
    max_idle_to=+6h0m0s0ms
    idle_factor=2.0
    min_time_to_alarm=+60m0s0ms
    max_temp_app_whitelist_duration=+5m0s0ms
    mms_temp_app_whitelist_duration=+60s0ms
    sms_temp_app_whitelist_duration=+20s0ms
  Whitelist (except idle) system apps:
    com.android.providers.downloads
  Whitelist (except idle) all app ids:
    10006
  mEnabled=false
  mForceIdle=false
  mSigMotionSensor={Sensor name="Significant motion", vendor="Google", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.0, minDelay=-1}
  mCurDisplay=Display id 0: DisplayInfo{"内置屏幕", uniqueId "local:0", app 1440 x 2392, real 1440 x 2560, largest app 2392 x 2308, smallest app 1440 x 1356, mode 1, defaultMode 1, modes [{id=1, width=1440, height=2560, fps=60.0}], colorTransformId 1, defaultColorTransformId 1, supportedColorTransforms [{id=1, colorTransform=-22}], rotation 0, density 560 (515.154 x 516.063) dpi, layerStack 0, appVsyncOff 0, presDeadline 17666667, type BUILT_IN, state ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}, DisplayMetrics{density=3.5, width=1440, height=2392, scaledDensity=3.5, xdpi=515.154, ydpi=516.063}, isValid=true
  mScreenOn=true
  mCharging=true
  mSigMotionActive=false
  mSensing=false mNotMoving=false
  mLocating=false mHaveGps=false mLocated=false
  mState=ACTIVE
  mInactiveTimeout=+30m0s0ms

结果中输出了很多定时器的时间,这些时间也体现在上图中。

状态切换

  1. Active
    DeviceIdle中注册了电源和显示器的监听器,当处于充电或者点亮屏幕时,就激活此状态,另外此状态还会被Monition Listener激活,这个后面会说。

  2. InActive
    当处于未充电且熄灭屏幕时,立刻进入此状态。此状态会持续一段时间,之后超时进入下一个状态。超时时间inactive_timeout在6p上面是30分钟。

  3. Idle pending
    InActive超时后进入此状态,此状态会持续一段时间,之后超时进入下一个状态。超时时间idle_after_inactive_timetout在6p上面是30分钟。
    期间会启动对significant monition的监听,这个监听在后面的状态中一直存在。
    significant monition监听器检测到设备移动后,会立刻先进入Active状态,再检测电源状态和屏幕状态,如果满足InActive条件,立即进入InActive状态。

  4. Sensing
    Idle pending超时后进入此状态,此状态会持续一段时间,之后超时进入下一个状态。超时时间sensing_timeout在6p上是60秒。
    期间会启动Any monition Detector,如果检测到有移动,同样会进入Active状态,和上面描述一致。

  5. Locating
    Sensing超时进入此状态,此状态会持续一段时间,之后超时进入下一个状态。超时时间locating_timeout在6p上是15秒。
    期间会发起generic location和gps location(结果优先),同时会停止上一步启动的any moniton detector。如果location返回结果表明没有移动,则不等待locating_timeout超时直接进入下一个状态。
    Locating在最后阶段会结束前面发起的generic location 和gps location。

  6. Idle
    先由Locating进入,代码中对应的case分支没有break,所以会执行到下一个case中。图中单独画了一个“time point”,其实是Locating状态下最后时间段做的事情。
    idle会和idle maintenance形成循环切换,从而形成交替打开的执行窗口。
    Idle状态会禁止应用的网络访问等,idle maintenance则是临时打开的活动窗口,应用可以进行网络访问。Idle的持续时间在6p上最初是60分钟,之后会逐渐变长,计算公式为:min(6小时,idleDelay*factor)。 其中factor为2,idleDelay为上一次持续时间。

  7. Idle maintenance
    和Idle形成执行窗口。持续时间在6p上最初是5分钟,之后会逐渐变长,计算公式为:min(10分钟,idlePendingDelay*factor)。其中factor为2,idlePendingDelay为上一次持续时间。

总结

最核心的状态就是Idle和Idle maintenance,在这个两个状态发生切换时,会通知其他服务,比如powerManager, networkManger,进行相应的服务限制或者放行。

Android6.0 DeviceIdle服务分析_第2张图片

你可能感兴趣的:(Android6.0 DeviceIdle服务分析)