赞
踩
本文只做为个人分析留档。
NetworkStatsManager statsManager = (NetworkStatsManager) getSystemService(Context.NETWORK_STATS_SERVICE);
tatsManager.querySummary(ConnectivityManager.TYPE_MOBILE, "", startTime, endTime);
statsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, null, startTime, endTime);
NetworkStatsAccess.java
@NetworkStatsAccess.Level int checkAccessLevel
这类生成查询的等级,按顺序来。
1.如果是系统签名,后面直接放行,可以查询全部。NetworkStatsAccess.Level.DEVICE;
2.如果是isDeviceOwner ,system uid同上。NetworkStatsAccess.Level.DEVICE;
3.如果拥有上述权限,level是:NetworkStatsAccess.Level.DEVICESUMMARY;
4.如果是isProfileOwner,level是:NetworkStatsAccess.Level.USER;
5.啥都没有就是默认:NetworkStatsAccess.Level.DEFAULT;
查询之前检测level
public static boolean isAccessibleToUser(int uid, int callerUid, @NetworkStatsAccess.Level int accessLevel) { switch (accessLevel) { case NetworkStatsAccess.Level.DEVICE: // Device-level access - can access usage for any uid. return true; case NetworkStatsAccess.Level.DEVICESUMMARY: // Can access usage for any app running in the same user, along // with some special uids (system, removed, or tethering) and // anonymized uids return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED || uid == UID_TETHERING || uid == UID_ALL || UserHandle.getUserId(uid) == UserHandle.getUserId(callerUid); case NetworkStatsAccess.Level.USER: // User-level access - can access usage for any app running in the same user, along // with some special uids (system, removed, or tethering). return uid == android.os.Process.SYSTEM_UID || uid == UID_REMOVED || uid == UID_TETHERING || UserHandle.getUserId(uid) == UserHandle.getUserId(callerUid); case NetworkStatsAccess.Level.DEFAULT: default: // Default access level - can only access one's own usage. return uid == callerUid; } }
NetworkStatsAccess.Level.USER 和NetworkStatsAccess.Level.DEVICESUMMARY基本类似,就是多了一个uid == UID_ALL。
NetworkStatsAccess.Level.DEVICESUMMARY这里面根据系统不一样有点区别。如果系统不支持多用户,那么就能查询全部,跟NetworkStatsAccess.Level.DEVICE一样,否则看注释。
这个类是核心类,所有的查询都是从这里开始。
1.构造
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
getDefaultSystemDir(), getDefaultBaseDir());
构造里面传入的路径是/data/system/netstats.记住这个路径。
2.systemReady
这个方法有几个重要的方法:
mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
//对应上面路径下面的四个文件
bootstrapStatsLocked()//这个里面多了一个路径。
初次检查,上述路径没有数据,那么统计数据哪里来的?
bootstrapStatsLocked()搞定了。
这个部分回到Android之前的统计了。
public NetworkStatsFactory(File procRoot, boolean useBpfStats) {
mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
mUseBpfStats = useBpfStats;
}
以上所有的文件解析出来,就是Android所有记录的流量使用情况。
其中/data/system/netstats 里面保存了uid ,pkg,subscriberId。似乎卸载的app的包名也记录了,这部分没有仔细去看。大概是因为文件是生成的时候app还没卸载。但是因为有部分流量是使用之前的流量统计逻辑,这部分不会记录包名,如果生成文件是已经卸载似乎就不会记录。
查询之前,生成:
private static NetworkTemplate createTemplate(int networkType, String subscriberId) { final NetworkTemplate template; switch (networkType) { case ConnectivityManager.TYPE_MOBILE: template = subscriberId == null ? NetworkTemplate.buildTemplateMobileWildcard() : NetworkTemplate.buildTemplateMobileAll(subscriberId); break; case ConnectivityManager.TYPE_WIFI: template = NetworkTemplate.buildTemplateWifiWildcard(); break; default: throw new IllegalArgumentException("Cannot create template for network type " + networkType + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + "'."); } return template; }
生成的template与上述NetworkStatsService读取的数据做匹配。
具体规则区间,可以去看NetworkStatsCollection。
说明一个,移动网络查询之前subscriberId,在Android9还是10以后,传入null,就是查询时间段类的所有卡信息,即使卡不存在。即生成的template是NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null);
然后正常查询,系统会去掉uid_tag文件的信息。这个部分暂时没细看是做什么的。后续有时间补充。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。