看看写写 之 Android上Ethernet和netd那点事

陆陆续续接触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);
   
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值