Google 发布的Android 源码在4.0之前是不包含对Ethernet的支持的,应用过程中都是各厂商或自己实现,或移植自android x86开源项目,多多少少会有问题.而在4.0中,终于见到了Ethernet的影子,好了闲话不表。



Google 发布的Android 源码在4.0之前是不包含对Ethernet的支持的。

一:Wifi模块的初始化

  • 在 SystemServer 启动的时候,会生成一个ConnectivityService 的实例,
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);
}

 

线程中启动WifiService

try {
                Slog.i(TAG, "Wi-Fi Service");
                wifi = new WifiService(context);
                ServiceManager.addService(Context.WIFI_SERVICE, wifi);
            } catch (Throwable e) {
                reportWtf("starting Wi-Fi Service", e);
            }
 
SystemServer定义在frameworks/base/services/java/com/android/server/SystemServer.java
ConnectivityService 定义在frameworks/base/services/java/com/android/server/ConnectivityService.java。
ConnectivityService 的构造函数会创建WifiStateTracker
switch (mNetConfigs[netType].radio) {
            case ConnectivityManager.TYPE_WIFI:
                mNetTrackers[netType] = new WifiStateTracker(netType,
                        mNetConfigs[netType].name);
                mNetTrackers[netType].startMonitoring(context, mHandler);

 

WifiStateTracker 定义在frameworks/base/wifi/java/android/net/wifi/。

WifiService定义在frameworks/base/services/java/com/android/server

  • WifiStateMachine 会创建WifiMonitor 接收来自底层的事件。WifiService 和WifiMonitor 是整个模块的核心。

WifiMonitor定义在frameworks/base/wifi/java/android/net/wifi/。

  • WifiStateMachine负责启动关闭wpa_supplicant(命令由wifimanager 的函数setWifiEnabled

下发CMD_START_SUPPLICANT)、启动关闭WifiMonitor 监视线程和把命令下发给wpa_supplicant(通过wifiNative);而WifiMonitor 则负责从wpa_supplicant 接收事件通知。

  • Wpa_supplicant和dhcp两个守护进程由init.rc中设置启动。

 

具体流程图如下:


二:Wifi模块的启动(使能 )

  WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮,

mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);

 

  当用户按下Wifi 按钮后,Android 会调用WifiEnabler 的onCheckedChanged,再由WifiEnabler调用WifiManager 的setWifiEnabled 接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService 调用WifiStateMachine的setWifiEnabled 接口函数,WifiStateMachine再向自己发送CMD_LOAD_DRIVER, CMD_START_SUPPLICANT在处理该消息的代码中做真正的使能工作:首先装载WIFI 内核模块,然后启动wpa_supplicant (配置文件为"/data/misc/wifi/wpa_supplicant.conf"),驱动加载正常,  wpa_supplicant启动正常后  mWifiMonitor.startMonitoring();启动WifiMonitor 中的监视线程。

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
          //Do nothing if called as a result of a state machine event
          if (mStateMachineEvent) {
              return;
          }
          // Show toast message if Wi-Fi is not allowed in airplane mode
          if (isChecked && !WirelessSettings.isRadioAllowed(mContext, Settings.System.RADIO_WIFI)) {
              Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
              // Reset switch to off. No infinite check/listenenr loop.
              buttonView.setChecked(false);
          }
  
          // Disable tethering if enabling Wifi
          int wifiApState = mWifiManager.getWifiApState();
          if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
                  (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
              mWifiManager.setWifiApEnabled(null, false);
          }
  
          if (mWifiManager.setWifiEnabled(isChecked)) {
              // Intent has been taken into account, disable until new state is active
              mSwitch.setEnabled(false);
                              log("ygg **** WifiEnabler disable button");
          } else {
              // Error
              Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
          }
      }
  WifiStateMachine
  public void setWifiEnabled(boolean enable) {
          mLastEnableUid.set(Binder.getCallingUid());
          if (enable) {
              /* Argument is the state that is entered prior to load */
              sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
              sendMessage(CMD_START_SUPPLICANT);
          } else {
              sendMessage(CMD_STOP_SUPPLICANT);
              /* Argument is the state that is entered upon success */
              sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
          }
      }

  当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。WifiSettings创建的时候就会向Android 注册接收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。

mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    mReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                  handleEvent(context, intent);
              }
          };
  
     private void handleEvent(Context context, Intent intent) {
          String action = intent.getAction();
          if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
              updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                      WifiManager.WIFI_STATE_UNKNOWN));
          } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||

                  具体流程如下流程图所示:

 

 

 


三:查找热点(AP)

上一节(Wifi开启)中讲到Wifi模块开启后会对外发送WIFI_STATE_CHANGED_ACTION。WifiSettings中注册了Action的Receiver. 

当WifiSettings收到此Action后,更新系统状态,如果已经使能(WIFI_STATE_ENABLED)开始scan的流程,具体如下:


当wpa_supplicant 处理完SCAN 命令后,它会向控制通道发送事件通知扫描完成,从wifi_wait_for_event 函数会接收到该事件,由此WifiMonitor 中的MonitorThread 会被执行来出来这个事件: