陆陆续续接触Android已经一年有余了,记得最初开始接触的是Honeycomb版本,当时那种青涩啊,那种看到sp<>,看到aidl时的惶恐还记忆犹新。。
算了,快写成抒情文了
我喜欢在PC上跑Android(效果还不是一般的好),最近因为要调试一些网络的东西,所以需要联网
三种主流选择:
1是WIFI
2是mobile
3是Ethernet
Mobile当然没有了,没有选择WIFI是因为X86上需要WIFI设备,还需要热点于是想用Ethernet在网上搜了下Android ethernet的方案,都貌似是froyo上面的,以前的版本貌似还没有ethernet支持,大神们做了很多工作
在新的代码上搜了一遍,居然找到了EthernetDataTracker.java这个文件
(说明一下,笔者所用的代码都是谷歌的原生Android代码,版本为4.1)
http://source.android.com/source/downloading.html
#repo init -u https://android.googlesource.com/platform/manifest -b android-4.1.1_r4
#repo sync
回到正题
有这个文件至少说明谷歌是针对了以太网的,所以可能不需要移植什么的(到底是不是呢?惶恐啊)总得找个切入点
我用鼠标点了下桌面上的默认的google search
看了看后面的Logcat,看到了一个小清新类:GoogleSuggestClient
又发现这个类有个巨牛X的方法:isNetworkConnected()
再到ConnectivityManager.getActiveNetworkInfo()一看又是那套service模式了
getActiveNetworkInfo说明系统可能有很多网络连接,但只能使用一个(要么以太网要么手机网络要么wifi)
继续跟踪到service吧
ConnectivityService.java
public NetworkInfo getActiveNetworkInfo() {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
return getNetworkInfo(mActiveDefaultNetwork, uid);
}
private NetworkInfo getNetworkInfo(int networkType, int uid) {
NetworkInfo info = null;
if (isNetworkTypeValid(networkType)) {
final NetworkStateTracker tracker = mNetTrackers[networkType];
if (tracker != null) {
info = getFilteredNetworkInfo(tracker, uid);
}
}
return info;
}
这里有一组NetworkStateTracker,想想肯定是一组可用的连接了
还有一个mActiveDefaultNetwork,这一定是默认连接了
一开始打印了下返回去的NetworkInfo,居然是个Null,这也难怪,我一个PC上面WIFI,MOBILE网络都没有嘛
但是我的以太网是好的(用ubuntu可以上网),这说明上面的framework可能和下面没有接上。
想法设法证实这一点吧
入口点当然是这组NetworkStateTracker是在哪初始化的
第一个想到的当然是ConnectivityService的构造了
至于构造又是在哪调用的,应该是大名鼎鼎的SystemServer了
看看构造
ConnectivityService.java
String[] raStrings = context.getResources().getStringArray(
com.android.internal.R.array.radioAttributes);
for (String raString : raStrings) {
RadioAttributes r = new RadioAttributes(raString);
......
mRadioAttributes[r.mType] = r;
}
String[] naStrings = context.getResources().getStringArray(
com.android.internal.R.array.networkAttributes);
for (String naString : naStrings) {
try {
NetworkConfig n = new NetworkConfig(naString);
......
mNetConfigs[n.type] = n;
mNetworksDefined++;
} catch(Exception e) {
// ignore it - leave the entry null
}
}
for (int netType : mPriorityList) {
switch (mNetConfigs[netType].radio) {
case ConnectivityManager.TYPE_WIFI:
mNetTrackers[netType] = new WifiStateTracker(netType,
mNetConfigs[netType].name);
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
case ConnectivityManager.TYPE_MOBILE:
mNetTrackers[netType] = new MobileDataStateTracker(netType,
mNetConfigs[netType].name);
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
......
case ConnectivityManager.TYPE_ETHERNET:
mNetTrackers[netType] = EthernetDataTracker.getInstance();
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
default:
loge("Trying to create a DataStateTracker for an unknown radio type " +
mNetConfigs[netType].radio);
continue;
}
mCurrentLinkProperties[netType] = null;
if (mNetTrackers[netType] != null && mNetConfigs[netType].isDefault()) {
mNetTrackers[netType].reconnect();
}
}
这里先从xml读出来两个属性
com.android.internal.R.array.radioAttributes
com.android.internal.R.array.networkAttributes
分别保存到
mRadioAttributes和mNetConfigs两个数组里面
后面的初始化就靠这两个东西了
找到xml文件
/frameworks/base/core/res/res/values/config.xml
<string-array translatable="false" name="networkAttributes">
<item>"wifi,1,1,1,-1,true"</item>
<item>"mobile,0,0,0,-1,true"</item>
<item>"mobile_mms,2,0,2,60000,true"</item>
<item>"mobile_supl,3,0,2,60000,true"</item>
<item>"mobile_hipri,5,0,3,60000,true"</item>
<item>"mobile_fota,10,0,2,60000,true"</item>
<item>"mobile_ims,11,0,2,60000,true"</item>
<item>"mobile_cbs,12,0,2,60000,true"</item>
<item>"wifi_p2p,13,1,0,-1,true"</item>
</string-array>
<string-array translatable="false" name="radioAttributes">
<item>"1,1"</item>
<item>"0,1"</item>
</string-array>
看到上面那个没,貌似只有wifi和mobile的定义,简直无视了以太网
赶紧补上,
networkAttributes:
<item>"eth,9,9,4,60000,true"</item>
之所以这么补两个9是因为后面初始化的时候是这么弄的,后面的4是优先级,再后面两个参数就没这么管了,照着前面写
radioAttributes
<item>"9,1"</item>
看这个分支:
case ConnectivityManager.TYPE_ETHERNET:
mNetTrackers[netType] = EthernetDataTracker.getInstance();
mNetTrackers[netType].startMonitoring(context, mHandler);
break;
继续追踪到startMonitoring
EthernetDataTracker.java
public void startMonitoring(Context context, Handler target) {
mContext = context;
mCsHandler = target;
// register for notifications from NetworkManagement Service
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);
mInterfaceObserver = new InterfaceObserver(this);
sIfaceMatch = context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);