android网络代码主要都在/framewrok/base下面,其中网络的配置在frameworks\base\core\res\res\values\config.xml中。
1.
在 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~