Android batterystats服务源码解读—Wifi流量来源

  • Post author:
  • Post category:其他


本文最初是想查看bugreport源码,分析bugreport中的Wifi流量数据。对于bugreport源码查看,已经有比较详细,并且特别好的文档,见

调试系列1:bugreport源码篇

。从bugreport源码中可以查看到,bugreport实际执行的是android dumpstate命令,dumpstate命令的输出主要为显示/proc中的内容和dumpsys服务的内容等。其中我们关注的电量以及流量问题即是dumpsys batterystats获得。故需要查看batterystats服务的源码。

以下主要根据统计每个app消耗流量的思路进行展开,以Uid为u0a3994的应用进行描述。

涉及到的文件

  • BatteryStats.java:BatteryStats类,提供访问电源相关数据的接口,主要包括wakelocks,processes,packages和serivces的信息。BatteryStats还有一个内部类Uid,主要提供与特定uid(在Android中,每个app都有一个唯一的uid,uid即是app id)相关的数据。



    目录:android-6.0.0_r1/frameworks/base/core/java/android/os/BatteryStats.java

  • BatteryStatsImpl.java:BatteryStats和Uid均为抽象类,BatteryStatsImpl是其对应的实现类。



    目录:android-6.0.0_r1/frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java

  • NetworkStatsFactory.java:NetworkStatsFactory类,获取流量数据的接口。获取流量也主要是通过读取/proc/net/xt_qtaguid目录中的文件来获得。



    目录:android-6.0.0_r1/frameworks/base/core/java/com/android/internal/net/NetworkStatsFactory.java

  • NetworkStats.java:NetworkStats类,存储网络数据的类。



    目录:android-6.0.0_r1/frameworks/base/core/java/android/net/NetworkStats.java

  • Android源码下载:

    Android 系统全套源代码分享 (更新到 7.1.1_r1)

在执行dumpsys batterystats命令时输出的部分内容如下:

  Estimated power use (mAh):
    Capacity: 3010, Computed drain: 28.5, actual drain: 0
    Uid u0a3994: 8.22 ( cpu=0.0926 wifi=8.06 gps=0.0722 )
    Wifi: 4.93 ( cpu=0.0479 wifi=4.88 )
    Cell standby: 3.66 ( radio=3.66 )
    Uid 1000: 3.48 ( cpu=3.42 wifi=0.00000030 sensor=0.0545 )
    Idle: 3.41
    Uid 0: 2.10 ( cpu=2.10 wifi=0.000211 )
    Uid u0a81: 0.476 ( cpu=0.134 sensor=0.342 )
    Screen: 0.390
    Uid u0a32: 0.329 ( cpu=0.0302 wifi=0.299 )
    Uid 1001: 0.218 ( cpu=0.218 )
    Uid u0a19: 0.139 ( cpu=0.139 wifi=0.0000218 )
    Uid 1021: 0.0902 ( cpu=0.0902 )
    Uid u0a38: 0.0781 ( cpu=0.0781 wifi=0.00000440 )
    ......(次数省略部分内容)
  u0a3994:
    Wi-Fi network: 13.13KB received, 13.10KB sent (packets 85 received, 123 sent)
    Wifi Running: 0ms (0.0%)
    Full Wifi Lock: 0ms (0.0%)
    Wifi Scan: 2m 11s 885ms (3.0%) 51x
    Wake lock *alarm*: 8ms partial (4 times) realtime
    Wake lock *job*/com.dianping.v1/com.dianping.base.push.pushservice.PushWakeUpJob: 258ms partial (38 times) realtime
    TOTAL wake: 266ms partial realtime
    Job com.dianping.v1/com.dianping.base.push.pushservice.PushWakeUpJob: 1s 409ms realtime (38 times)
    Sensor GPS: 1s 528ms realtime (3 times)
    Foreground for: 1h 13m 12s 523ms
    Total cpu time: u=1s 200ms s=2s 300ms p=0mAh
    Proc com.dianping.v1:dppushservice:
      CPU: 1s 210ms usr + 2s 240ms krn ; 0ms fg
    Apk com.dianping.v1:
      Wakeup alarm *walarm*:com.dianping.push.START: 1 times
      Wakeup alarm *walarm*:com.dianping.push.KEEP_ALIVE: 18 times
      Service com.dianping.base.push.pushservice.PushWakeUpJob:
        Created for: 0ms uptime
        Starts: 0, launches: 38

从输出内容可得电池容量为3010mAh,u0a3994应用耗电8.22mAh,括号内为对应的组件耗电。注意省略号之后的内容,本文即从查找u0a3994应用的Wifi上下行流量数据来源进行展开。

BatteryStats.java

根据上文输出信息,可确定内容是调用BatteryStats.java中的public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)函数进行输出的,故可以此函数为入口,深入查找流量数据来源。该文件中有两个dumpLocked函数,注意根据函数签名区分。

在dumpLocked()函数中找到以下代码段:

       for (int iu=0; iu<NU; iu++) {
            final int uid = uidStats.keyAt(iu);
            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
                continue;
            }

            final Uid u = uidStats.valueAt(iu);

            pw.print(prefix);
            pw.print("  ");
            UserHandle.formatUid(pw, uid);
            pw.println(":");
           



版权声明:本文为u012160436原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。