android Ethernet移植小记

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~

你可能感兴趣的:(android,流程,移植,ethernet)