systemui wifi 信号图标

android/base/packages/SystemUI/src/com/android/systemui/

android 8.0

statusbar/SignalClusterView.java

android 9.0

statusbar/StatusBarWifiView.java

一、 wifi 图片修改方式

public class WifiSignalController extends
SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
private final WifiManager mWifiManager;
    private final AsyncChannel mWifiChannel;
    private final boolean mHasMobileData;
    private final WifiStatusTracker mWifiTracker;


    public WifiSignalController(Context context, boolean hasMobileData,
       CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
        super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
           callbackHandler, networkController);

    // WiFi only has one state.
    // 从这里可以看出是定义在 wifiIcons中的图片
    mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
    "Wi-Fi Icons",
    WifiIcons.WIFI_SIGNAL_STRENGTH,
    WifiIcons.QS_WIFI_SIGNAL_STRENGTH,
    AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
    WifiIcons.WIFI_NO_NETWORK,
    WifiIcons.QS_WIFI_NO_NETWORK,
    WifiIcons.WIFI_NO_NETWORK,
    WifiIcons.QS_WIFI_NO_NETWORK,
    AccessibilityContentDescriptions.WIFI_NO_CONNECTION

   );

WIFI_SIGNAL_STRENGTH就是一个二维数组,这个数组里面就定义了不同状态栏下的wifi信号强度
,第一个数组就是带有"x"号或者"!"号的wifi icon,第二个数组就是正常显示的wifi icon
 

二、

wifi 流量的图标可在 SignalClusterView.java 或 StatusBarWifiView.java  中进行修改,位置和逻辑

 

三、 data 流程

wifi 信号的流程其实和  sim 信号的流程图标差不多

NetworkControllerImpl  和 WifiSignalControll

3.1  wifi的数据上下行流程

WifiSignalController.java

public class WifiSignalController extends
SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
private final WifiManager mWifiManager;
    private final AsyncChannel mWifiChannel;
    private final boolean mHasMobileData;
    private final WifiStatusTracker mWifiTracker;

    public WifiSignalController(Context context, boolean hasMobileData,
     CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
     super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
     callbackHandler, networkController);

     //===================================================================
     mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     mWifiTracker = new WifiStatusTracker(mWifiManager);
     mHasMobileData = hasMobileData;
     Handler handler = new WifiHandler(Looper.getMainLooper());
     //起到了类似代理类的作用
     mWifiChannel = new AsyncChannel();
     Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
     if (wifiMessenger != null) {
      //=======   通过 messager 进行跨进程通讯   AsyncChannel 在下面 ====================================
      mWifiChannel.connect(context, handler, wifiMessenger);
      }
     ...
     ...

    }

	/**
	 * Handler to receive the data activity on wifi.
	 */
	private class WifiHandler extends Handler {
	   WifiHandler(Looper looper) {
	    super(looper);
	   }

	  @Override
	  public void handleMessage(Message msg) {
	    switch (msg.what) {
	     case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
	       if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
	            mWifiChannel.sendMessage(Message.obtain(this,
	            AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
	         } else {
                 Log.e(mTag, "Failed to connect to wifi");
	        }
	        break;
		   
	     case WifiManager.DATA_ACTIVITY_NOTIFICATION:
		  //得到framework 层发来的消息
		  setActivity(msg.arg1);
		  break;
		  default:
	          // Ignore
	          break;
	      }
	    }
	}

        //通过这个方法才更新 activityIn activityOut 状态
	@VisibleForTesting
	void setActivity(int wifiActivity) {
	   mCurrentState.activityIn = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
	      || wifiActivity == WifiManager.DATA_ACTIVITY_IN;
	   mCurrentState.activityOut = wifiActivity == WifiManager.DATA_ACTIVITY_INOUT
	   || wifiActivity == WifiManager.DATA_ACTIVITY_OUT;
	   notifyListenersIfNecessary();
	  }
    }

3.2  AsyncChannel 起到了一个连接的作用,通过connect方法

  AsyncChannel.java
  public class AsyncChannel {
	 .....

	// 看注释便能理解,链接  
	srcHandler 与  dstMessenger
	public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
	if (DBG) log("connect srcHandler to the dstMessenger  E");

	// We are connected
	connected(srcContext, srcHandler, dstMessenger);

	// Tell source we are half connected
	replyHalfConnected(STATUS_SUCCESSFUL);
	    if (DBG) log("connect srcHandler to the dstMessenger X");
	}

	public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
	if (DBG) log("connected srcHandler to the dstMessenger  E");
	// Initialize source fields
	mSrcContext = srcContext;
	mSrcHandler = srcHandler;
	    //利用 messenegr 进行跨进成通信
	mSrcMessenger = new Messenger(mSrcHandler);
	// Initialize destination fields
	mDstMessenger = dstMessenger;

	    //从注释可以看出来是 在AsyncChannel 中, messenger 与  srcHandler 进行数据交互
	    if (DBG) log("connected srcHandler to the dstMessenger X");
	}

	/**
	 * Send a message to the destination handler.
	 * @param msg
	*/
	public void sendMessage(Message msg) {
	    msg.replyTo = mSrcMessenger;
	    try {
	    mDstMessenger.send(msg);
	} catch (RemoteException e) {
		replyDisconnected(STATUS_SEND_UNSUCCESSFUL);
	}
	}


	/**
	 * Reply to the src handler that we're half connected.
	 * see: CMD_CHANNEL_HALF_CONNECTED for message contents
	 * @param status to be stored in msg.arg1
	 */
	private void replyHalfConnected(int status) {
	    Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
	    msg.arg1 = status;
	    msg.obj = this;
	    msg.replyTo = mDstMessenger;
	     if (!linkToDeathMonitor()) {
	     // Override status to indicate failure
	     msg.arg1 = STATUS_BINDING_UNSUCCESSFUL;
	   }
	   mSrcHandler.sendMessage(msg);
	}
     }


 3.3 mWifiManager ->  WifiServiceImpl.java , connet 时将 Messenger 传给WifiTrafficPoller 中的clent列表

 


  public class WifiServiceImpl extends IWifiManager.Stub {

	/**
	 * Handles client connections
	 */
	private class ClientHandler extends WifiHandler {

	ClientHandler(String tag, Looper looper) {
	   super(tag, looper);
	}

	@Override
	public void handleMessage(Message msg) {
	       super.handleMessage(msg);
	       switch (msg.what) {
                //  在通过  AsyncChannel.java 中的 replyHalfConnected, add client( is )
	        case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
	        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
	           if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
	           // We track the clients by the Messenger
	           // since it is expected to be always available

		    //在这里add client
	            mTrafficPoller.addClient(msg.replyTo);
	   } else {
		Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
	   }
	        ......
		.......
	   }


       /**
	 * Get a reference to handler. This is used by a client to establish
	 * an AsyncChannel communication with WifiService
	 */
	// WifiSignalController 得到 messenger的对象,通过messager对象跨进程通讯
	@Override
	public Messenger getWifiServiceMessenger() {
	   enforceAccessPermission();
	   enforceChangePermission();
	   if (mVerboseLoggingEnabled) {
	      mLog.info("getWifiServiceMessenger uid=%").c(Binder.getCallingUid()).flush();
	   }
	   return new Messenger(mClientHandler);
	}

3.4  WifiSignalController 中的 handleMessage中接收的消息是从 wifiTrafficPoller.java //流量轮询器


   /frameworks/base/services/java/com/android/server/wifi/WifiTrafficPoller.java

   public class WifiTrafficPoller {

	WifiTrafficPoller(Context context, Looper looper, String iface) {
	mInterface = iface;
	mTrafficHandler = new TrafficHandler(looper);

	IntentFilter filter = new IntentFilter();
	filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
	filter.addAction(Intent.ACTION_SCREEN_OFF);
	filter.addAction(Intent.ACTION_SCREEN_ON);

	context.registerReceiver(
	    new BroadcastReceiver() {
	@Override
	public void onReceive(Context context, Intent intent) {
	  if (intent == null) {
	  return;
	  }
	  if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(
				    intent.getAction())) {
	  mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
					WifiManager.EXTRA_NETWORK_INFO);
	  } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
	  mScreenOn.set(false);
	  } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
	  mScreenOn.set(true);
	  }
	    //如果监听到广播,则处理
            evaluateTrafficStatsPolling();
	  }
	   }, filter);
	}


	private void evaluateTrafficStatsPolling() {
	    Message msg;
	    if (mNetworkInfo == null) return;
	    if (mNetworkInfo.getDetailedState() == CONNECTED && mScreenOn.get()) {
		msg = Message.obtain(mTrafficHandler,ENABLE_TRAFFIC_STATS_POLL, 1, 0);
	} else {
		msg = Message.obtain(mTrafficHandler, ENABLE_TRAFFIC_STATS_POLL, 0, 0);
	}
	   //发送handler消息,最终再调用 notifyOnDataActivity
	 msg.sendToTarget();
	}

	//根据流量的上行还是下行选择出图片并将消息发送出去
	private void notifyOnDataActivity() {
	long sent, received;

	//保存当前的上下行数据包的数量
	 long preTxPkts = mTxPkts, preRxPkts = mRxPkts;
	    int dataActivity = WifiManager.DATA_ACTIVITY_NONE;

	   //== 通过如下的方法获取当前的上下行的数据包的数量 ===
	   mTxPkts = TrafficStats.getTxPackets(mInterface);
	   mRxPkts = TrafficStats.getRxPackets(mInterface);

	    if (DBG) {
		Log.d(TAG, " packet count Tx="+ Long.toString(mTxPkts)
			+ " Rx="+ Long.toString(mRxPkts));
	    }

	    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;
	     }

	    if (dataActivity != mDataActivity && mScreenOn.get()) {
	    mDataActivity = dataActivity;
		    if (mVerboseLoggingEnabled) {
			Log.e(TAG, "notifying of data activity "
	    + Integer.toString(mDataActivity));
	    }
	   for (Messenger client : mClients) {
			Message msg = Message.obtain();
	   msg.what = WifiManager.DATA_ACTIVITY_NOTIFICATION;
	   msg.arg1 = mDataActivity;
	    try {
			//这里for循环将消息发给
			    client.send(msg);
	    } catch (RemoteException e) {
	      // Failed to reach, skip
			    // Client removal is handled in WifiService
	     }
		    }
		}
	    }
}

5.5. frameworks/base/core/java/android/net/TrafficStats.java

 WifiTrafficPoller 中的获取当前上下行 数据包的方法

public class TrafficStats {
/**
     * The return value to indicate that the device does not support the statistic.
     */
public final static int UNSUPPORTED = -1;

/** @hide */
public static final long KB_IN_BYTES = 1024;
/** @hide */
public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
/** @hide */
public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
/** @hide */
public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
/** @hide */
public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;


    //调用 native方法得到数据,
   /** {@hide} */
    public static long getTxPackets(String iface) {
        return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);
   }
}

5.6. //全局搜索  nativeGetIfaceStat ,找到 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)

}

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

 const char* c_str() const {

     //utf_chars_的值为wlan0

     return utf_chars_;

  } **/


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");
if (fp == NULL) {
return -1;
}

char buffer[384];
char cur_iface[32];
bool foundTcp = false;
uint64_t rxBytes, rxPackets, txBytes, txPackets, tcpRxPackets, tcpTxPackets;

while (fgets(buffer, sizeof(buffer), fp) != NULL) {
int matched = sscanf(buffer, "%31s %" SCNu64 " %" SCNu64 " %" SCNu64
" %" SCNu64 " " "%*u %" SCNu64 " %*u %*u %*u %*u "
                "%*u %" SCNu64 " %*u %*u %*u %*u", cur_iface, &rxBytes,
&rxPackets, &txBytes, &txPackets, &tcpRxPackets, &tcpTxPackets);
if (matched >= 5) {
if (matched == 7) {
                foundTcp = true;
}
if (!iface || !strcmp(iface, cur_iface)) {
                stats->rxBytes += rxBytes;
stats->rxPackets += rxPackets;
stats->txBytes += txBytes;
stats->txPackets += txPackets;
if (matched == 7) {
                    stats->tcpRxPackets += tcpRxPackets;
stats->tcpTxPackets += tcpTxPackets;
     }
            }
        }
    }

if (!foundTcp) {
        stats->tcpRxPackets = UNKNOWN;
        stats->tcpTxPackets = UNKNOWN;
   }
if (fclose(fp) != 0) {
return -1;
}
return 0;
}

5.7、全局搜索 iface_stat_fmt, 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 = proc_create_data(iface_stat_fmt_procfilename,
   proc_iface_perms,
   parent_procdir,&proc_iface_stat_fmt_fops, (void *)2 /* fmt2 */);

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值