Android 4.0 Ethernet 和 wifi 的实现分析

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 会被执行来出来这个事件:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值