u最近在研究android 中的 ethernet 部分,主要集中在上层JAVA service 和java api。
整个 android 系统的mobile, wifi,wimax 和 bluetooth 都是通过ConnectivitySerivice 来提供服务的。
android本身不自带ethernet服务,需要新加 android-x86 里拿的ics-ethernet patch。
接下来分析 ConnectivityService 是怎么提供 ethernet 服务的。
1. 最开始,ConnectivityService 中会创建 EthernetStateTracker 和 EthernetService。
frameworks/base/services/java/com/android/server/ConnectivityService.java:
case ConnectivityManager.TYPE_ETHERNET: //mNetTrackers[netType] = EthernetDataTracker.getInstance(); //mNetTrackers[netType].startMonitoring(context, mHandler); if(DBG) log("Starting Ethernet Service."); //创建 EthernetStateTracker EthernetStateTracker est=new EthernetStateTracker(context, mHandler); //创建EthernetService EthernetService ethService=new EthernetService(context, est);
//向ServiceManager 中添加 ETHERNET_SERVICE 服务 ServiceManager.addService(Context.ETHERNET_SERVICE, ethService); mNetTrackers[ConnectivityManager.TYPE_ETHERNET]= est; //赋值EthernetStateTracker. //调用EthernetStateTracker 的startMonitoring est.startMonitoring(context, mHandler); break;
a. mNetTrackers 定义:
/** * Sometimes we want to refer to the individual network state * trackers separately, and sometimes we just want to treat them * abstractly. */ private NetworkStateTracker mNetTrackers[]; //网络状态跟踪,no_connected, connecting, connected ,三种状态
b. EthernetStateTracker.startMonitoring():
public void startMonitoring(Context context, Handler target) { if (localLOGV) Slog.v(TAG,"start to monitor the ethernet devices"); if (mServiceStarted) { //获得systemService 中 ethernet_service的上下文 mEM = (EthernetManager)context.getSystemService(Context.ETHERNET_SERVICE); mContext = context; mCsHandler = target; int state = mEM.getState(); if (state != mEM.ETHERNET_STATE_DISABLED) { if (state == mEM.ETHERNET_STATE_UNKNOWN) { // maybe this is the first time we run, so set it to enabled mEM.setEnabled(mEM.getDeviceNameList() != null); //set mEM to enabled. } else { try { //if it's not the first time we run, reset the interface. resetInterface(); } catch (UnknownHostException e) { Slog.e(TAG, "Wrong ethernet configuration"); } } } } }
2. 创建 EthernetStateTracker :
frameworks/base/ethernet/java/android/net/ethernet/EthernetStateTracker.java
3. 创建 EthernetService:public EthernetStateTracker(Context context, Handler target){ //创建 NetworkInfo,可以用来查看网络状况 mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0,"ETH",""); mLinkProperties = new LinkProperties(); //网络链接属性 if (localLOGV) Slog.v(TAG,"Starts..."); //EthernetNative 通过 JNI 调用到 libnetutil.so 中去了。 if (EthernetNative.initEthernetNative()!= 0){ Slog.e(TAG,"Can not init ethernet device layers"); return; } if (localLOGV) Slog.v(TAG,"Successed"); mServiceStarted = true; //创建 DHCP 线程 HandlerThread dhcpThread = new HandlerThread("DHCP Handler Thread"); dhcpThread.start(); mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(),this); mMonitor = new EthernetMonitor(this); //创建 EthernetMonitor mDhcpInfo = new DhcpInfoInternal(); //创建 DhcpInfoInternal, 用来描述DHCP IP配置 mDhcpInfo1 = new DhcpInfo(); //创建DhcpInfo, 用来描述static ip 配置 }
a. DhcpHandler(): 这个类不知道干啥的。。
private class DhcpHandler extends Handler { public DhcpHandler(Looper looper, Handler target) { super(looper); mTrackerTarget = target; //赋值mTrackerTarget. }
b. EthernetMonitor(): 这个会单独介绍
c. DhcpInfoInternal(): 这个应该是DhcpInfo的新一代。
frameworks/base/core/java/android/net/DhcpInfoInternal.java
/** * A simple object for retrieving the results of a DHCP request. * Replaces (internally) the IPv4-only DhcpInfo class. * @hide */ public class DhcpInfoInternal { private final static String TAG = "DhcpInfoInternal"; public String ipAddress; public int prefixLength; public String dns1; public String dns2; public String serverAddress; public int leaseDuration; private Collection<RouteInfo> mRoutes;
d. DhcpInfo 类内容明显 和 DhcpInfoInternal 不同:
frameworks/base/core/java/android/net/DhcpInfo.java
/** * A simple object for retrieving the results of a DHCP request. */ public class DhcpInfo implements Parcelable { public int ipAddress; public int gateway; public int netmask; public int dns1; public int dns2; public int serverAddress; public int leaseDuration;
frameworks/base/services/java/com/android/server/EthernetService.java
public EthernetService(Context context, EthernetStateTracker Tracker){ mTracker = Tracker; mContext = context; isEnabled = getPersistedState(); if (localLOGV==true) Slog.i(TAG,"Ethernet dev enabled "+ isEnabled); getDeviceNameList(); //从驱动获得设备表 setState(isEnabled); //设置 enabled 状态 Slog.d(TAG,"xxha: ---------------------- StartPolling()"); mTracker.StartPolling(); //开始监听驱动层的事件信号 }
a. getDeviceNameList() :
/** * get all the ethernet device names * @return interface name list on success, {@code null} on failure */ public String[] getDeviceNameList() { return (scanDevice() > 0) ? DevName : null; //扫描设备 }
private int scanDevice() { int i, j; if ((i = EthernetNative.getInterfaceCnt()) == 0) return 0; DevName = new String[i]; for (j = 0; j < i; j++) { DevName[j] = EthernetNative.getInterfaceName(j); //获取设备名eth0,sit0 if (DevName[j] == null) break; if (localLOGV) Slog.v(TAG, "device " + j + " name " + DevName[j]); } return i; }
b. mTracker.StartPolling()
public void StartPolling() { mMonitor.startMonitoring(); //这个也会调到EthernetMonitor 中的 startMonitoring() 去。 }