Android(安卓)4.0 wifi 和 Ethernet 的实现分析
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接收来自底层的事件。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=newWifiEnabler(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中的监视线程。
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_ACTION。WifiSettings中注册了Action的Receiver.
当WifiSettings收到此Action后,更新系统状态,如果已经使能(WIFI_STATE_ENABLED)开始scan的流程,具体如下:
当wpa_supplicant处理完SCAN命令后,它会向控制通道发送事件通知扫描完成,从wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件:
#Android更多相关文章
- Bugly全量更新快速集成(Android)
- android 访问WebService
- android 自定义核心服务
- Android(安卓)Jetpack-Room数据库简单使用
- android 自定义 3D View
- toolbar自定义右边的菜单注意
- 安卓WebView与JavaScript交互
- Android(安卓)Intent定义选择器打开相机和相册
- 在Android中访问WebService接口