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

一、背景介绍

打开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);

三、流程图


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值