美文网首页Android安全-源码分析
Android6.0 DeviceIdle服务分析

Android6.0 DeviceIdle服务分析

作者: difcareer | 来源:发表于2016-06-27 23:42 被阅读671次

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

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


    状态变化

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

    先看一下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服务分析

        本文链接:https://www.haomeiwen.com/subject/zqftjttx.html