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

一:Wifi模块的初始化

  • SystemServer启动的时候,会生成一个ConnectivityService的实例,

try{

Slog.i(TAG,"ConnectivityService");

connectivity=ConnectivityService.getInstance(context);

ServiceManager.addService(Context.CONNECTIVITY_SERVICE,connectivity);

}catch(Throwablee){

Slog.e(TAG,"FailurestartingConnectivityService",e);

}

线程中启动WifiService

try{

Slog.i(TAG,"Wi-FiService");

wifi=newWifiService(context);

ServiceManager.addService(Context.WIFI_SERVICE,wifi);

}catch(Throwablee){

reportWtf("startingWi-FiService",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){

caseConnectivityManager.TYPE_WIFI:

mNetTrackers[netType]=newWifiStateTracker(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接收来自底层的事件。WifiServiceWifiMonitor是整个模块的核心。

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

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

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

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

具体流程图如下:


二:Wifi模块的启动(使能

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

  mWifiEnabler=newWifiEnabler(activity,actionBarSwitch);

  

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

  

  publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){

  //Donothingifcalledasaresultofastatemachineevent

  if(mStateMachineEvent){

  return;

  }

  //ShowtoastmessageifWi-Fiisnotallowedinairplanemode

  if(isChecked&&!WirelessSettings.isRadioAllowed(mContext,Settings.System.RADIO_WIFI)){

  Toast.makeText(mContext,R.string.wifi_in_airplane_mode,Toast.LENGTH_SHORT).show();

  //Resetswitchtooff.Noinfinitecheck/listenenrloop.

  buttonView.setChecked(false);

  }

  

  //DisabletetheringifenablingWifi

  intwifiApState=mWifiManager.getWifiApState();

  if(isChecked&&((wifiApState==WifiManager.WIFI_AP_STATE_ENABLING)||

  (wifiApState==WifiManager.WIFI_AP_STATE_ENABLED))){

  mWifiManager.setWifiApEnabled(null,false);

  }

  

  if(mWifiManager.setWifiEnabled(isChecked)){

  //Intenthasbeentakenintoaccount,disableuntilnewstateisactive

  mSwitch.setEnabled(false);

  log("ygg****WifiEnablerdisablebutton");

  }else{

  //Error

  Toast.makeText(mContext,R.string.wifi_error,Toast.LENGTH_SHORT).show();

  }

  }

  WifiStateMachine

  publicvoidsetWifiEnabled(booleanenable){

  mLastEnableUid.set(Binder.getCallingUid());

  if(enable){

  /*Argumentisthestatethatisenteredpriortoload*/

  sendMessage(obtainMessage(CMD_LOAD_DRIVER,WIFI_STATE_ENABLING,0));

  sendMessage(CMD_START_SUPPLICANT);

  }else{

  sendMessage(CMD_STOP_SUPPLICANT);

  /*Argumentisthestatethatisentereduponsuccess*/

  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=newBroadcastReceiver(){

  @Override

  publicvoidonReceive(Contextcontext,Intentintent){

  handleEvent(context,intent);

  }

  };

  

  privatevoidhandleEvent(Contextcontext,Intentintent){

  Stringaction=intent.getAction();

  if(WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){

  updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

  WifiManager.WIFI_STATE_UNKNOWN));

  }elseif(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)||

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

三:查找热点(AP

上一节(Wifi开启)中讲到Wifi模块开启后会对外发送WIFI_STATE_CHANGED_ACTIONWifiSettings中注册了ActionReceiver.

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

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

#Android

更多相关文章

  1. Bugly全量更新快速集成(Android)
  2. android 访问WebService
  3. android 自定义核心服务
  4. Android(安卓)Jetpack-Room数据库简单使用
  5. android 自定义 3D View
  6. toolbar自定义右边的菜单注意
  7. 安卓WebView与JavaScript交互
  8. Android(安卓)Intent定义选择器打开相机和相册
  9. 在Android中访问WebService接口

随机推荐

  1. Android 资源加载机制剖析
  2. Android之获取手机UDID
  3. Android的升级策略
  4. Android adb常用指令使用指南
  5. Android Thread和AsyncTask的区别和联系
  6. 浅谈android中的目录结构
  7. Android用户界面 UI组件--TextView及其子
  8. 关于Android异步 RxJava和Handler
  9. Android关机重启重启至recovery应用开发
  10. Android中对象池的使用