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