http://blog.csdn.net/jingxia2008/article/details/26591005
背景
Android kitkat 默认已经支持 Ethernet 有线网络,只要稍微配置,便可以直接使用,测试结果,网络浏览器和下载都没有没有问题,而且系统可以做到与 wifi 共存,互相不影响功能,这里简单介绍如何使能 Ethernet,并简要分析其代码和流程。
Linux 配置部分
Linux 需要能够支持有线网络,生成 eth 网络设备节点。
Android 配置
overlay
主要是 overlay 里面添加 Ethernet 网络类型支持: frameworks/base/core/res/res/values/config.xml
- <string-array translatable="false" name="radioAttributes">
- <item>"1,1"</item>
- <item>"7,1"</item>
- <item>"9,1"</item>
- </string-array>
其中 9 对应 Ethernet 的网络类型,其定义在 ConnectivityManager.java 中
- /**
- * The Ethernet data connection. When active, all data traffic
- * will use this network type's interface by default
- * (it has a default route).
- */
- public static final int TYPE_ETHERNET = 9;
init.<board>.rc
init 里面需要添加 dhcp 和 ip renew 服务
- # DHCPCD
- # # eth0
- service dhcpcd_eth0 /system/bin/dhcpcd -ABKL
- class main
- disabled
- oneshot
- # IP Renew
- # # eth0
- service iprenew_eth0 /system/bin/dhcpcd -n
- class main
- disabled
- oneshot
流程分析
ConnectivityService
ConnectivityService 的构造函数里面将会读取 radioAttributes 里面的网络配置
- public ConnectivityService(Context context, INetworkManagementService netManager,
- INetworkStatsService statsService, INetworkPolicyManager policyManager,
- NetworkFactory netFactory) {
- if (DBG) log("ConnectivityService starting up");
- // Load device network attributes from resources
- String[] raStrings = context.getResources().getStringArray(
- com.android.internal.R.array.radioAttributes);
- for (String raString : raStrings) {
- RadioAttributes r = new RadioAttributes(raString);
- if (VDBG) log("raString=" + raString + " r=" + r);
- if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
- loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
- continue;
- }
- if (mRadioAttributes[r.mType] != null) {
- loge("Error in radioAttributes - ignoring attempt to redefine type " +
- r.mType);
- continue;
- }
- mRadioAttributes[r.mType] = r;
- }
根据网络配置数据,将会创建 EthernetDataTracker , 并开始监听 startMonitoring
- // Create and start trackers for hard-coded networks
- for (int targetNetworkType : mPriorityList) {
- final NetworkConfig config = mNetConfigs[targetNetworkType];
- final NetworkStateTracker tracker;
- try {
- tracker = netFactory.createTracker(targetNetworkType, config);
- mNetTrackers[targetNetworkType] = tracker;
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)
- + " tracker: " + e);
- continue;
- }
- tracker.startMonitoring(context, mTrackerHandler);
- if (config.isDefault()) {
- tracker.reconnect();
- }
- }
EthernetDataTracker
- <!-- Regex of wired ethernet ifaces -->
- <string translatable="false" name="config_ethernet_iface_regex">eth\d</string>
- sIfaceMatch = context.getResources().getString(
- com.android.internal.R.string.config_ethernet_iface_regex);
- try {
- final String[] ifaces = mNMService.listInterfaces();
- for (String iface : ifaces) {
- if (iface.matches(sIfaceMatch)) {
- mNMService.setInterfaceUp(iface);
- InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
- if (getEthernetCarrierState(iface) == 1) {
- mIface = iface;
- mLinkUp = true;
- mNetworkInfo.setIsAvailable(true);
- if (config != null && mHwAddr == null) {
- mHwAddr = config.getHardwareAddress();
- if (mHwAddr != null) {
- mNetworkInfo.setExtraInfo(mHwAddr);
- }
- }
- }
- // if a DHCP client had previously been started for this interface, then stop it
- NetworkUtils.stopDhcp(iface);
- }
- }
- reconnect();
- } catch (RemoteException e) {
- Log.e(TAG, "Could not get list of interfaces " + e);
- }
- mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
- Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
- msg.sendToTarget();
如果有多个网口呢,这个 EthernetDataTracker 显然不能满足要求,必须对其进行扩展。