http://blog.csdn.net/new_abc/article/details/38437595

做Box,以太网就比较常用了,我们看下 以太网的打开流程:


通过Setting里面的选项,我们勾选以太网时,不管是dhcp获取ip,还是静态配置的ip,都会启动以太网并获取ip,启动以太网通过setEnabled来启动,这里会调用到EthernetManager,EthernetManager调用EthernetService的setState

[cpp]  view plain  copy  print ?
  1. public synchronized void setState(int state) {  
  2.   
  3.     if (mEthState != state) {  
  4.         mEthState = state;  
  5.         if (state == EthernetManager.ETHERNET_STATE_DISABLED) {  
  6.             if(DBG) Slog.d(TAG, "setState: disable ethernet.");  
  7.             persistEnabled(false);  
  8.             mTracker.teardown();  
  9.         } else if (state == EthernetManager.ETHERNET_STATE_ENABLED) {  
  10.             if(DBG) Slog.d(TAG, "setState: enable ethernet.");  
  11.             persistEnabled(true);  
  12.             mTracker.reconnect();  
  13.         }  
  14.     }  
  15. }  

对于enable,调用mTracker.reconnect()

[cpp]  view plain  copy  print ?
  1.   public boolean reconnect() {  
  2.       mTeardownRequested.set(false);  
  3. ConnectNetwork(true);  
  4.       return true;  
  5.   }  

继续调用ConnectNetwork

[cpp]  view plain  copy  print ?
  1. public void ConnectNetwork(boolean up) {  
  2.     if(DBG) Slog.d(TAG, "ConnectNetwork: Up is " + up + ", mLinkUp is " + mLinkUp +  
  3.                 ", On is " + mEthManage.isOn() + ", mIface " + mIface);  
  4.     if(!mEthManage.isConfigured()) {  
  5.         if(mIface != null)  
  6.             Log.d(TAG, "no configuration for " + mIface);  
  7.         return;  
  8.     }  
  9.        /* connect */  
  10.     if(up && mEthManage.isOn()) {  
  11.         EthernetDevInfo ifaceInfo = mEthManage.getSavedConfig();  
  12.         if(ifaceInfo == null) {  
  13.                Log.e(TAG, "get configuration failed.");  
  14.             return;  
  15.         }  
  16.         synchronized(mIface) {  
  17.             if(!mIface.equals(ifaceInfo.getIfName())) {  
  18.                 if(!mIface.isEmpty()) {  
  19.                     NetworkUtils.stopDhcp("eth_" + mIface);  
  20.                     NetworkUtils.disableInterface(mIface);  
  21.                 }  
  22.                 mIface = ifaceInfo.getIfName();  
  23.             }  
  24.         }  
  25.         NetworkUtils.enableInterface(mIface);  
  26.   
  27.         if(mLinkUp == false)  
  28.             return;  
  29.              
  30.            /* dhcp way */  
  31.         if(mEthManage.isDhcp()) {  
  32.             /* make sure iface to 0.0.0.0 */  
  33.             try{  
  34.                 mNMService.clearInterfaceAddresses(mIface);  
  35.                 NetworkUtils.resetConnections(mIface, 0);  
  36.             } catch (RemoteException e) {  
  37.                 Log.e(TAG, "ERROR: " + e);  
  38.             }  
  39.             /* stop dhcp if already running */  
  40.             if(SystemProperties.get("dhcp." + mIface + ".result").equals("ok")) {  
  41.                 NetworkUtils.stopDhcp("eth_" + mIface);  
  42.                 sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_FAILED);  
  43.             }  
  44.             if(DBG) Slog.d(TAG, "connecting and running dhcp.");  
  45.             runDhcp();  
  46.         } else {  
  47.             /* static ip way */  
  48.             NetworkUtils.stopDhcp("eth_" + mIface);  
  49.   
  50.             /* read configuration from usr setting */  
  51.             DhcpInfoInternal dhcpInfoInternal = getIpConfigure(ifaceInfo);  
  52.                mLinkProperties = dhcpInfoInternal.makeLinkProperties();  
  53.                mLinkProperties.setInterfaceName(mIface);  
  54.   
  55.                InterfaceConfiguration ifcg = new InterfaceConfiguration();  
  56.             ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());  
  57.             ifcg.setInterfaceUp();  
  58.             try{  
  59.                 mNMService.setInterfaceConfig(mIface, ifcg);  
  60.             } catch (Exception e) {  
  61.                 Log.e(TAG, "ERROR: " + e);  
  62.                 sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_FAILED);  
  63.                 return;  
  64.             }  
  65.                if(DBG) Slog.d(TAG, "connecting and confgure static ip address.");  
  66.                mNetworkInfo.setIsAvailable(true);  
  67.                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);  
  68.                Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
  69.                msg.sendToTarget();  
  70.             sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_SUCCEEDED);  
  71.         }  
  72.     } else if(isTeardownRequested()) {  
  73.          /* disconnect */  
  74.         Slog.d(TAG, "teardown network.");  
  75.         NetworkUtils.stopDhcp("eth_" + mIface);  
  76.         mLinkProperties.clear();  
  77.         NetworkUtils.disableInterface(mIface);  
  78.         mNetworkInfo.setIsAvailable(false);  
  79.         mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);  
  80.         Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
  81.         msg.sendToTarget();  
  82.         sendStateBroadcast(EthernetManager.EVENT_DISCONNECTED);  
  83.     }  
  84. }  
这里会调用getSavedConfig或去以太网的一些信息,如地址掩码,网关等,接着调用NetworkUtils.enableInterface使能网卡设备,这个时候mLinkUp为false,函数就返回了,但是NetworkUtils.enableInterface使能网卡设备的时候会和下层的netd通信,并通过notifyInterfaceLinkStateChanged回调到EthernetDataTracker的interfaceLinkStateChanged

[cpp]  view plain  copy  print ?
  1. private void interfaceLinkStateChanged(String iface, boolean up) {  
  2.     int tmpStatus = 0;  
  3.     int i=0;  
  4.     if (mIface.matches(iface)) {  
  5.         for(i = 0; i < 3; i++) {  
  6.             try {  
  7.                 Thread.sleep(100);  
  8.             } catch(Exception e){ }  
  9.             tmpStatus = mEthManage.checkLink(iface);  
  10.             if(tmpStatus == 0 && mFirstLinkUp == true) {  
  11.                 Slog.d(TAG, "link entry exist,but no any value,bring up.");  
  12.                 NetworkUtils.enableInterface(iface);  
  13.                 mFirstLinkUp = false;  
  14.             }  
  15.         }  
  16.         Slog.d(TAG, "interfaceLinkStateChanged: ["+ iface + "], up [" + up + "]");  
  17.         if(tmpStatus == -1) {  
  18.             //checkLink return -1 means no entry  
  19.             Slog.d(TAG, "checkLink return -1 means no entry.");  
  20.             return;  
  21.         }  
  22.         up = (tmpStatus == 1) ? true : false;  
  23.         if(mLinkUp == up)  
  24.             return;  
  25.   
  26.         mLinkUp = up;  
  27.         if (up) {  
  28.             reconnect();  
  29.             /* modified by chenjd, 2013-08-01, 
  30.             * when the broadcast send before boot complete, it will throw exception, this will make 
  31.             * the ethernet can't update its state when its interface link state changes.To fix it, 
  32.             * the broadcast intent must add flag FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT */  
  33.             Intent upIntent = new Intent(EthernetManager.ETHERNET_LINKED_ACTION);  
  34.             upIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);  
  35.             mContext.sendBroadcast(upIntent);  
  36.         } else {  
  37.             if(DBG) Slog.d(TAG, "interfaceLinkStateChanged: teardown network.");  
  38.             NetworkUtils.stopDhcp("eth_" + mIface);  
  39.             mLinkProperties.clear();  
  40.             mNetworkInfo.setIsAvailable(false);  
  41.             mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);  
  42.             Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
  43.             msg.sendToTarget();  
  44.             sendStateBroadcast(EthernetManager.EVENT_DISCONNECTED);  
  45.             /* modified by chenjd, 2013-08-01, 
  46.             * when the broadcast send before boot complete, it will throw exception, this will make 
  47.             * the ethernet can't update its state when its interface link state changes.To fix it, 
  48.             * the broadcast intent must add flag FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT */  
  49.             Intent downIntent = new Intent(EthernetManager.ETHERNET_DISLINKED_ACTION);  
  50.             downIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);  
  51.             mContext.sendBroadcast(downIntent);  
  52.                pppoe_ok = false;  
  53.         }  
  54.     }  
  55. }  
该函数设置mLinkUp,并调用reconnect重新连接网络,这里就会到了ConnectNetwork的如下代码出

[cpp]  view plain  copy  print ?
  1. {  
  2.             EthernetDevInfo ifaceInfo = mEthManage.getSavedConfig();  
  3.             if(ifaceInfo == null) {  
  4.                 Log.e(TAG, "get configuration failed.");  
  5.                 return;  
  6.             }  
  7.             synchronized(mIface) {  
  8.                 if(!mIface.equals(ifaceInfo.getIfName())) {  
  9.                     if(!mIface.isEmpty()) {  
  10.                         NetworkUtils.stopDhcp("eth_" + mIface);  
  11.                         NetworkUtils.disableInterface(mIface);  
  12.                     }  
  13.                     mIface = ifaceInfo.getIfName();  
  14.                 }  
  15.             }  
  16.             NetworkUtils.enableInterface(mIface);  
  17.   
  18.             if(mLinkUp == false)  
  19.                 return;  
  20.               
  21.             /* dhcp way */  
  22.             if(mEthManage.isDhcp()) {  
  23.                 /* make sure iface to 0.0.0.0 */  
  24.                 try{  
  25.                     mNMService.clearInterfaceAddresses(mIface);  
  26.                     NetworkUtils.resetConnections(mIface, 0);  
  27.                 } catch (RemoteException e) {  
  28.                     Log.e(TAG, "ERROR: " + e);  
  29.                 }  
  30.                 /* stop dhcp if already running */  
  31.                 if(SystemProperties.get("dhcp." + mIface + ".result").equals("ok")) {  
  32.                     NetworkUtils.stopDhcp("eth_" + mIface);  
  33.                     sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_FAILED);  
  34.                 }  
  35.                 if(DBG) Slog.d(TAG, "connecting and running dhcp.");  
  36.                 runDhcp();  
  37.             } else {  
  38.                 /* static ip way */  
  39.                 NetworkUtils.stopDhcp("eth_" + mIface);  
  40.   
  41.                 /* read configuration from usr setting */  
  42.                 DhcpInfoInternal dhcpInfoInternal = getIpConfigure(ifaceInfo);  
  43.                 mLinkProperties = dhcpInfoInternal.makeLinkProperties();  
  44.                 mLinkProperties.setInterfaceName(mIface);  
  45.   
  46.                 InterfaceConfiguration ifcg = new InterfaceConfiguration();  
  47.                 ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());  
  48.                 ifcg.setInterfaceUp();  
  49.                 try{  
  50.                     mNMService.setInterfaceConfig(mIface, ifcg);  
  51.                 } catch (Exception e) {  
  52.                     Log.e(TAG, "ERROR: " + e);  
  53.                     sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_FAILED);  
  54.                     return;  
  55.                 }  
  56.                 if(DBG) Slog.d(TAG, "connecting and confgure static ip address.");  
  57.                 mNetworkInfo.setIsAvailable(true);  
  58.                 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);  
  59.                 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);  
  60.                 msg.sendToTarget();  
  61.                 sendStateBroadcast(EthernetManager.EVENT_CONFIGURATION_SUCCEEDED);  
  62.             }  
  63.         }  
区分dhcp还是静态设置,我们这里看静态设置ip,首先停止dhcp,最后调用NetworkManagementService的setInterfaceConfig设置静态ip,setInterfaceConfig最终也是通过cmd的方式与netd通信,传送命令setcfg,这里还会发送一个EVENT_STATE_CHANGED广播,他的处理在NetworkStateTrackerHandler中,对于NetworkInfo.State.CONNECTED消息,会调用handleConnect

[cpp]  view plain  copy  print ?
  1. private void handleConnect(NetworkInfo info) {  
  2.     final int newNetType = info.getType();  
  3.   
  4.     setupDataActivityTracking(newNetType);  
  5.   
  6.     // snapshot isFailover, because sendConnectedBroadcast() resets it  
  7.     boolean isFailover = info.isFailover();  
  8.     final NetworkStateTracker thisNet = mNetTrackers[newNetType];  
  9.     final String thisIface = thisNet.getLinkProperties().getInterfaceName();  
  10.   
  11.     // if this is a default net and other default is running  
  12.     // kill the one not preferred  
  13.     if (mNetConfigs[newNetType].isDefault()) {  
  14.         if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) {  
  15.             if (isNewNetTypePreferredOverCurrentNetType(newNetType)) {  
  16.                 // tear down the other  
  17.                 NetworkStateTracker otherNet =  
  18.                         mNetTrackers[mActiveDefaultNetwork];  
  19.                 if (DBG) {  
  20.                     log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +  
  21.                         " teardown");  
  22.                 }  
  23.                 if (!teardown(otherNet)) {  
  24.                     loge("Network declined teardown request");  
  25.                     teardown(thisNet);  
  26.                     return;  
  27.                 }  
  28.             } else {  
  29.                    // don't accept this one  
  30.                     if (VDBG) {  
  31.                         log("Not broadcasting CONNECT_ACTION " +  
  32.                             "to torn down network " + info.getTypeName());  
  33.                     }  
  34.                     teardown(thisNet);  
  35.                     return;  
  36.             }  
  37.         }  
  38.         synchronized (ConnectivityService.this) {  
  39.             // have a new default network, release the transition wakelock in a second  
  40.             // if it's held.  The second pause is to allow apps to reconnect over the  
  41.             // new network  
  42.             if (mNetTransitionWakeLock.isHeld()) {  
  43.                 mHandler.sendMessageDelayed(mHandler.obtainMessage(  
  44.                         EVENT_CLEAR_NET_TRANSITION_WAKELOCK,  
  45.                         mNetTransitionWakeLockSerialNumber, 0),  
  46.                         1000);  
  47.             }  
  48.         }  
  49.         mActiveDefaultNetwork = newNetType;  
  50.         // this will cause us to come up initially as unconnected and switching  
  51.         // to connected after our normal pause unless somebody reports us as reall  
  52.         // disconnected  
  53.         mDefaultInetConditionPublished = 0;  
  54.         mDefaultConnectionSequence++;  
  55.         mInetConditionChangeInFlight = false;  
  56.         // Don't do this - if we never sign in stay, grey  
  57.         //reportNetworkCondition(mActiveDefaultNetwork, 100);  
  58.     }  
  59.     thisNet.setTeardownRequested(false);  
  60.     updateNetworkSettings(thisNet);  
  61.     handleConnectivityChange(newNetType, false);  
  62.     sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());  
  63.   
  64.     // notify battery stats service about this network  
  65.     if (thisIface != null) {  
  66.         try {  
  67.             BatteryStatsService.getService().noteNetworkInterfaceType(thisIface, newNetType);  
  68.         } catch (RemoteException e) {  
  69.             // ignored; service lives in system_server  
  70.         }  
  71.     }  
  72. }  


    handleConnect会对网络的优先级进行判断,如果网络的优先级小于现有网络,则断开该网络,否则断开以前的网络。

一下是一个以太网跟wifi并存的方案补丁包:

http://download.csdn.net/detail/new_abc/7730099


更多相关文章

  1. [Android]ActivityUnitTestCase解释
  2. android静态广播添加权限
  3. android wifiservice enable流程
  4. android面试总结加强再加强版
  5. 关于Android中Java与Javascript之间的传值研究
  6. android usb挂载分析---MountService启动
  7. Android学习笔记十五.使用ContentProvider实现数据共享(一)
  8. Android(安卓)Retrofit源码解析
  9. android looper和handler

随机推荐

  1. 【Android布局】在程序中设置android:gra
  2. Mono for Android(安卓)实现高效的导航
  3. Android中的Shape使用总结
  4. Android应用程序进程启动过程(后篇)
  5. 【Android布局】在程序中设置android:gra
  6. Android(安卓)引用library project
  7. Android中数据存储的5种方法
  8. Android(安卓)动态加载(六) - 360开源框架D
  9. Android(安卓)面试题总结之Android(安卓)
  10. android文字阴影效果