android以太网服务,android Ethernet移植小记

在 ConnectivityManager.java 中定义的有如下类型:

public static final int TYPE_MOBILE = 0;

public static final int TYPE_WIFI = 1;

public static final int TYPE_MOBILE_MMS = 2;

public static final int TYPE_MOBILE_SUPL = 3;

public static final int TYPE_MOBILE_DUN = 4;

public static final int TYPE_MOBILE_HIPRI = 5;

public static final int TYPE_WIMAX = 6;

/* 这是在机顶盒上为android系统添加的网络类型 */

public static final int TYPE_PPPOE = 7;

public static final int TYPE_ETHERNET = 8;

public static final int TYPE_CABLEMODEM = 9;

2.系统对网络的判断大多都是在 ConnectivityService.java中处理的,用户操作的类是 ConnectivityManager.java 通过aidl访问

ConnectivityService.java提供的服务。而启动在SystemServer.java中:

try {

Slog.i(TAG, "Connectivity Service");

connectivity = ConnectivityService.getInstance(context);

ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

} catch (Throwable e) {

Slog.e(TAG, "Failure starting Connectivity Service", e);

}

3.启动之后再ConnectivityService构造函数里会判断是哪种类型:

注:这里我就用Ethernet网线接口分析,cable猫的流程类似网线和wifi的。

...

case ConnectivityManager.TYPE_ETHERNET:

if (DBG) Slog.v(TAG, "Starting Ethernet Service.");

EthernetStateTracker est = new EthernetStateTracker(context, mHandler);

EthernetService ethService = new EthernetService(context, est);

ServiceManager.addService(Context.ETHERNET_SERVICE, ethService);

ethService.startEthernet();

mNetTrackers[ConnectivityManager.TYPE_ETHERNET] = est;

est.startMonitoring();

break;

...

4.new EthernetStateTracker对象时会初始化一个对应的监听线程和消息handler等:

mMonitor = new EthernetMonitor(this);

mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(), this);

new EthernetService(context, est)会启动刚开始那个监听线程,不停的向android_net_ethernet.cpp获取

String eventName = EthernetNative.waitForEvent();

然后处理,发送对应的消息handleEvent(String ifname,int event)

...

ethService.startEthernet();//这里会跟着设置网络获取模式有dhcp方式和手动设置的静态方式

---> setEthernetEnabled(2);//方法在EthernetService.java

--->mTracker.startDhcpMode();//startDhcpMode这个方法EthernetStateTracker.java

...

est.startMonitoring();//真正启动,reset下

--->resetInterface();

--->mInterfaceName = info.getIfName();//得到设备名字如:eth0

如果之前的有地址,这发送消息remove掉

mDhcpTarget.removeMessages(EVENT_DHCP_START);

之后重新配置:

configureInterface(info);

这个接口里有2种方式:

if (info.getConnectMode().equals(EthernetDevInfo.ETHERNET_CONN_MODE_DHCP)) {

Slog.i(TAG, "trigger dhcp for device " + info.getIfName());

mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);

} else {

//手动配置

}

配置完了之后发送一个消息

this.sendEmptyMessage(event);

这个消息处理在handleMessage里。注意这里下面还有一个DhcpHandler内部类也是消息处理,区分时看前面的调用对象

5.此时,java部分配置已大部分完成,而那个Monitor监听线程在不停的获取

EthernetNative.waitForEvent();

到C++层

android_net_ethernet_waitForEvent中得到,返回形式如:eth0:20:

20表示connected,然后发送成功消息:

case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:

Slog.i(TAG, "received configured succeeded, stack=" + mStackConnected + " HW=" + mHWConnected);

/**send enabled*/

final Intent succIntent = new Intent(EthernetManager.ETHERNET_STATE_CHANGED_ACTION);

succIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

succIntent.putExtra(EthernetManager.EXTRA_ETHERNET_STATE, EthernetManager.ETHERNET_STATE_ENABLED);

mContext.sendStickyBroadcast(succIntent);

mStackConnected = true;

if (mHWConnected)

setEthState(true, msg.what);

如果mHWConnected这个值为true的话:

private void setEthState(boolean state, int event) {

Slog.d(TAG,"mNetworkInfo.isConnected() = "+mNetworkInfo.isConnected() +"state = "+state);

if (mNetworkInfo.isConnected() != state) {

if (state) {

setDetailedState(DetailedState.CONNECTED);

//mTarget.sendEmptyMessage(EVENT_CONFIGURATION_CHANGED);

Message msg = mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);

msg.sendToTarget();

} else {

setDetailedState(DetailedState.DISCONNECTED);

stopInterface(true);

}

mNetworkInfo.setIsAvailable(state);

postNotification(event);

}

}

6.之后回到ConnectivityService.java中,会发送一个消息为NetworkStateTracker.EVENT_STATE_CHANGED调用

else if (state == NetworkInfo.State.CONNECTED) {

handleConnect(info);

}

................

大致就这样,如果cable modem或wifi获取的应该差不多

O(∩_∩)O~

你可能感兴趣的:(android以太网服务)