在公司一款产品上需要需要添加有线网口,所以系统需要做相应的支持,找到一个支持的有线网口的系统,将其中软件部分做简单分析:
首先:功能方面,要能够设置有线网络的IP地址,子网掩码,网关,DNS等信息,这些功能由 Etnernet 这个 APP实现;
系统方面,对于已经设置好的信息,断电重启之后不能丢失,还能继续保持有效,所以需要添加一个系统服务 EthernetService
其次,EthernetService的启动入口, \frameworks\base\services\java\com\android\server\ConnectivityService.java 其构造类
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
NetworkFactory netFactory)
。
。
for (int targetNetworkType : mPriorityList) {
final NetworkConfig config = mNetConfigs[targetNetworkType];
final NetworkStateTracker tracker;
try {
tracker = netFactory.createTracker(targetNetworkType, config);
mNetTrackers[targetNetworkType] = tracker;
if (targetNetworkType == ConnectivityManager.TYPE_ETHERNET) {
EthernetService ethernet = new EthernetService(context, (EthernetStateTracker)tracker);
ServiceManager.addService(Context.ETH_SERVICE, ethernet);
}
Slog.d(TAG, "*******targetNetworkType="+targetNetworkType);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)
+ " tracker: " + e);
continue;
}
tracker.startMonitoring(context, mTrackerHandler);
if (config.isDefault()) {
tracker.reconnect();
}
}
上面的黑体字代码是实现Ethernet 功能的核心,具体分析如下
1. tracker = netFactory.createTracker(targetNetworkType, config);
创建 网络状态追踪器
@Override
public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) {
switch (config.radio) {
case TYPE_WIFI:
return new WifiStateTracker(targetNetworkType, config.name);
case TYPE_MOBILE:
return new MobileDataStateTracker(targetNetworkType, config.name);
case TYPE_DUMMY:
return new DummyDataStateTracker(targetNetworkType, config.name);
case TYPE_BLUETOOTH:
return BluetoothTetheringDataTracker.getInstance();
case TYPE_WIMAX:
return makeWimaxStateTracker(mContext, mTrackerHandler);
case TYPE_ETHERNET:
//return EthernetDataTracker.getInstance();
return new EthernetStateTracker(targetNetworkType, config.name);
default:
throw new IllegalArgumentException(
"Trying to create a NetworkStateTracker for an unknown radio type: "
+ config.radio);
}
}
}
2. 创建并添加网络服务
EthernetService ethernet = new EthernetService(context, (EthernetStateTracker)tracker);
ServiceManager.addService(Context.ETH_SERVICE, ethernet);
\frameworks\base\services\java\com\android\server\EthernetService.java
private int mEthState= EthernetManager.ETH_STATE_UNKNOWN;
//public static final int ETH_STATE_UNKNOWN = 0;
public EthernetService(Context context, EthernetStateTracker Tracker){
mTracker = Tracker;
mContext = context;
isEthEnabled = getPersistedState();
Slog.v(TAG,"Ethernet dev enabled " + isEthEnabled );
getDeviceNameList();
setEthState(isEthEnabled);
//registerForBroadcasts();
Slog.v(TAG, "Trigger the ethernet monitor");
mTracker.StartPolling();
mDelayedHandler = new Handler();
isEthernetServiceInited = true;
}
其核心是 setEthState,即开关网络
3. tracker.startMonitoring(context, mTrackerHandler);
启动网络状态监控,核心是
frameworks\base\ethernet\java\android\net\ethernet\EthernetMonitor.java
class MonitorThread extends Thread {
public MonitorThread() {
super("EthMonitor");
}
public void run() {
int index;
int i;
//noinspection InfiniteLoopStatement
for (;;) {
if (DEBUG) Slog.i(TAG, "go poll events");
String eventName = EthernetNative.waitForEvent();
if (eventName == null) {
continue;
}
if (DEBUG) Slog.i(TAG, "got event " + eventName);
/*
* Map event name into event enum
*/
String [] events = eventName.split(":");
index = events.length;
if (index < 2)
continue;
i = 0;
while (index != 0 && i < index-1) {
int event = 0;
if (DEBUG) Slog.i(TAG,"dev: " + events[i] + " ev " + events[i+1]);
int cmd =Integer.parseInt(events[i+1]);
if ( cmd == DEL_LINK) {
event = DISCONNECTED;
handleEvent(events[i],event);
}
else if (cmd == ADD_ADDR ) {
event = CONNECTED;
handleEvent(events[i],event);
} else if (cmd == NEW_LINK) {
event = PHYUP;
handleEvent(events[i],event);
}
i = i + 2;
}
}
}
/**
* Handle all supplicant events except STATE-CHANGE
* @param event the event type
* @param remainder the rest of the string following the
* event name and " — "
*/
void handleEvent(String ifname,int event) {
switch (event) {
case DISCONNECTED:
mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.DISCONNECTED);
break;
case CONNECTED:
mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.CONNECTED);
break;
case PHYUP:
mTracker.notifyPhyConnected(ifname);
break;
default:
mTracker.notifyStateChange(ifname,NetworkInfo.DetailedState.FAILED);
}
}
监控程序启动一个线程,调用native方法 String eventName = EthernetNative.waitForEvent();
通过 handleEvent(events[i],event); 将不同的网络状态消息传到 mTracker ,mTracker对消息作出响应
4. 实现真正的网络设置,
tracker.reconnect(); 其核心是 EthernetStateTracker ->resetInterface,在调用本地方法,
system/core/libnetutils/ifc_utils.c
(libcutils---ifc_utils.c)int ifc_reset_connections(const char *ifname, const int reset_mask)
这个文件还包含一些网络接口,详见 另一篇博客
http://blog.youkuaiyun.com/liufuliang163/article/details/72729901
上面提到的相关代码:
http://download.youkuaiyun.com/detail/liufuliang163/9853456