Android Wi-Fi StatusBar(状态栏)流量上下行图标显示流程

来源:互联网 发布:自制名片软件下载 编辑:程序博客网 时间:2024/05/15 13:59

一、背景介绍

打开wifi连接上ap在状态栏里面期望图标显示如下:



以下图片所在的目录为:LINUX/android/base/packages/SystemUI/res/drawable-xhdpi



二、流程跟踪

1、LINUX/android/base/packages/SystemUI/src/com/android/systemui/

statusbar/SignalClusterView.java文件中

调用如下代码实现上下行流量的图标:

public void setWifiIndicators(booleanvisible, int strengthIcon, int activityIcon, String contentDescription) {      mMobileActivityId = activityIcon;          apply();}

private void apply() {     //显示图标    mMobileActivity.setImageResource(mMobileActivityId); }                

具体显示哪一个要根据 mMobileActivityId的值来确定;那么mMobileActivityId是怎么确定出来的呢?解释:2;

 

2、LINUX/android/framework/base/packages/SystemUI/src/com/android/

systemui/statusbar/policy/NetworkController.java

 

首先接收了一个消息并对消息进行了处理:

class WifiHandler extends Handler {     public void handleMessage(Message msg) {                         //获取消息里面的内容                        mWifiActivity = msg.arg1;                         //调用方法刷新显示                        refreshViews();     }} void refreshViews() {                                //根据 mWifiActivity的值具体选择需要显示哪张图片                switch (mWifiActivity) {                                        caseWifiManager.DATA_ACTIVITY_IN:                        mWifiActivityIconId =R.drawable.stat_sys_wifi_in;                        break;                     …..省略代码....                }                 //调用如下方法传递参数给1去刷新图标                refreshSignalCluster(cluster);} public voidrefreshSignalCluster(SignalCluster cluster) {             cluster.setWifiIndicators(mWifiEnabled && (mWifiConnected ||            !mHasMobileDataFeature || mAppOpsStrictEnabled), mWifiIconId,            mWifiActivityIconId, mContentDescriptionWifi);}

到此处就可以实现上下行图标的刷新显示;那么 handleMessage中接收的消息又是哪里发出的呢?解释:3;


3、LINUX/android/frameworks/base/services/java/com/android/server/wifi/

WifiTrafficPoller.java

//根据流量的上行还是下行选择出图片并将消息发送出去

private void notifyOnDataActivity() {       //保存当前的上下行数据包的数量       long preTxPkts = mTxPkts, preRxPkts = mRxPkts;              //通过如下的方法获取当前的上下行的数据包的数量       mTxPkts = TrafficStats.getTxPackets(mInterface);       mRxPkts = TrafficStats.getRxPackets(mInterface);        if (preTxPkts > 0 || preRxPkts > 0) {           sent = mTxPkts - preTxPkts;           received = mRxPkts – preRxPkts;                      //如果是发送数据           if (sent > 0) {                dataActivity |= WifiManager.DATA_ACTIVITY_OUT;           }            //接受数据           if (received > 0) {                dataActivity |=WifiManager.DATA_ACTIVITY_IN;           }                  …...省略代码......                //将消息发送出去        msg.what = WifiManager.DATA_ACTIVITY_NOTIFICATION;        msg.arg1 = mDataActivity;              client.send(msg);       }}

其中mInterface是在LINUX/android/frameworks/base//services/java/com

/android/server/wifi/WifiService.java中如下的代码实现了接口获取:

mInterfaceName =  SystemProperties.get("wifi.interface","wlan0"); mTrafficPoller = newWifiTrafficPoller(mContext, mInterfaceName);

那么TrafficStats.getTxPackets具体是怎么获取流量包数据的呢?解释:(4);

 

4、LINUX/android/frameworks/base/core/java/android/net/TrafficStats.java文件中

   //getTxPackets的具体实现是通过nativeGetIfaceStat实现   public static long getTxPackets(String iface) {       return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);    }

LINUX/android/frameworks/base/core/jni/android_net_TrafficStats.cpp文件中

// nativeGetIfaceStat是通过 getIfaceStat实现static JNINativeMethod gMethods[] = {    {"nativeGetIfaceStat", "(Ljava/lang/String;I)J",(void*) getIfaceStat}} static jlong getIfaceStat(JNIEnv* env,jclass clazz, jstring iface, jint type) {    ScopedUtfChars iface8(env, iface);    if (parseIfaceStats(iface8.c_str(), &stats) == 0)}

LINUX/android/libnativehelper/include/nativehelper/ScopedUtfChars.h中

 const char* c_str() const {   //utf_chars_的值为wlan0   return utf_chars_;  }

LINUX/android/frameworks/base/core/jni/android_net_TrafficStats.cpp文件中

QTAGUID_IFACE_STATS ="/proc/net/xt_qtaguid/iface_stat_fmt"; static int parseIfaceStats(const char*iface, struct Stats* stats) {   FILE *fp = fopen(QTAGUID_IFACE_STATS, "r");    剩下的就是对fp进行操作代码省略}

那么iface_stat_fmt又是如何创建的呢?解释:5

 

5、LINUX/android/kernel/net/netfilter/xt_qtaguid.c中

通过如下的方法创建 iface_stat_fmt

static const char*iface_stat_fmt_procfilename = "iface_stat_fmt"; iface_stat_fmt_procfile =create_proc_entry(iface_stat_fmt_procfilename,                                       proc_iface_perms,                                       parent_procdir);

三、流程图


原创粉丝点击