在 SystemServer启动的时候,会生成一个ConnectivityService的实例,
try {
Log.i(TAG,"Starting ConnectivityService.");
ServiceManager.addService(Context.CONNECTIVITY_SERVICE,new
ConnectivityService(context));
} catch (Throwable e){
Log.e(TAG, "Failure starting Connectivity Service",e);
}
ConnectivityService的构造函数会创建WifiService,
if (DBG) Log.v(TAG,"Starting Wifi Service.");
mWifiStateTracker = newWifiStateTracker(context, handler);
WifiService wifiService = newWifiService(context,mWifiStateTracker);
ServiceManager.addService(Context.WIFI_SERVICE,wifiService);
WifiStateTracker会创建WifiMonitor接收来自底层的事件,WifiService和WifiMonitor是整
个模块的核心。WifiService负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程
和把命令下发给wpa_supplicant,而WifiMonitor则负责从wpa_supplicant接收事件通知。
第三部分:Wifi模块的启动(使能)
WirelessSettings在初始化的时候配置了由WifiEnabler来处理Wifi按钮,
privatevoid initToggles() {
mWifiEnabler = newWifiEnabler(this,
(WifiManager)getSystemService(WIFI_SERVICE),
(CheckBoxPreference)findPreference(KEY_TOGGLE_WIFI));
当用户按下Wifi按钮后,Android会调用WifiEnabler的onPreferenceChange,再由WifiEnabler
调用WifiManager的setWifiEnabled接口函数,通过AIDL,实际调用的是WifiService的
setWifiEnabled函数,WifiService接着向自身发送一条MESSAGE_ENABLE_WIFI消息,在
处理该消息的代码中做真正的使能工作:首先装载WIFI内核模块(该模块的位置硬编码为
"/system/lib/modules/wlan.ko"), 然后启动wpa_supplicant(配置文件硬编码为
"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker来启动WifiMonitor中的监视
线程。
privateboolean setWifiEnabledBlocking(boolean enable) {
final inteventualWifiState = enable ? WIFI_STATE_ENABLED:WIFI_STATE_DISABLED;
updateWifiState(enable? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING);
if (enable){
if(!WifiNative.loadDriver()) {
Log.e(TAG,"Failed to load Wi-Fi driver.");
updateWifiState(WIFI_STATE_UNKNOWN);
returnfalse;
}
if(!WifiNative.startSupplicant()) {
WifiNative.unloadDriver();
Log.e(TAG,"Failed to start supplicant daemon.");
updateWifiState(WIFI_STATE_UNKNOWN);
returnfalse;
}
mWifiStateTracker.startEventLoop();
}
//Success!
persistWifiEnabled(enable);
updateWifiState(eventualWifiState);
returntrue;
}
当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION这个Intent通知外界WIFI
已经成功使能了。WifiEnabler创建的时候就会向Android注册接收
WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。
privatevoid handleWifiStateChanged(int wifiState) {
if (wifiState ==WIFI_STATE_ENABLED) {
loadConfiguredAccessPoints();
attemptScan();
}
上层通过wifinative.java定义的class
package android.net.wifi.WifiNative
public class WifiNative {
static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
public native static String getErrorString(int errorCode);
public native static boolean loadDriver();
public native static boolean unloadDriver();
public native static boolean startSupplicant();
public native static boolean stopSupplicant();
public native static boolean connectToSupplicant();
public native static void closeSupplicantConnection();
public native static boolean pingCommand();
public native static boolean scanCommand(boolean forceActive);
public native static boolean setScanModeCommand(boolean setActive);
public native static String listNetworksCommand();
public native static int addNetworkCommand();
public native static boolean setNetworkVariableCommand(int netId, String name, String value);
public native static String getNetworkVariableCommand(int netId, String name);
public native static boolean removeNetworkCommand(int netId);
public native static boolean enableNetworkCommand(int netId, boolean disableOthers);
public native static boolean disableNetworkCommand(int netId);
public native static boolean reconnectCommand();
public native static boolean reassociateCommand();
public native static boolean disconnectCommand();
public native static String statusCommand();
public native static int getRssiCommand();
public native static int getRssiApproxCommand();
public native static int getLinkSpeedCommand();
public native static String getMacAddressCommand();
public native static String scanResultsCommand();
public native static boolean startDriverCommand();
public native static boolean stopDriverCommand()
....................................
static JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
{ "stopSupplicant", "()Z", (void *)android_net_wifi_stopSupplicant },
{ "connectToSupplicant", "()Z", (void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnection", "()V", (void *)android_net_wifi_closeSupplicantConnection },
{ "listNetworksCommand", "()Ljava/lang/String;",
(void*) android_net_wifi_listNetworksCommand },
{ "addNetworkCommand", "()I", (void*) android_net_wifi_addNetworkCommand },
{ "setNetworkVariableCommand", "(ILjava/lang/String;Ljava/lang/String;)Z",
(void*) android_net_wifi_setNetworkVariableCommand },
{ "getNetworkVariableCommand", "(ILjava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_getNetworkVariableCommand },
{ "removeNetworkCommand", "(I)Z", (void*) android_net_wifi_removeNetworkCommand },
{ "enableNetworkCommand", "(IZ)Z", (void*) android_net_wifi_enableNetworkCommand },
{ "disableNetworkCommand", "(I)Z", (void*) android_net_wifi_disableNetworkCommand },
{ "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
{ "statusCommand", "()Ljava/lang/String;", (void*) android_net_wifi_statusCommand },
{ "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
{ "pingCommand", "()Z", (void *)android_net_wifi_pingCommand },
{ "disconnectCommand", "()Z", (void *)android_net_wifi_disconnectCommand },
{ "reconnectCommand", "()Z", (void *)android_net_wifi_reconnectCommand },
{ "reassociateCommand", "()Z", (void *)android_net_wifi_reassociateCommand },
{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
{ "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
{ "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
{ "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
{ "startPacketFiltering", "()Z", (void*) android_net_wifi_startPacketFiltering },
{ "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
{ "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
{ "getPowerModeCommand", "()I", (void*) android_net_wifi_getPowerModeCommand },
{ "setNumAllowedChannelsCommand", "(I)Z", (void*) android_net_wifi_setNumAllowedChannelsCommand },
{ "getNumAllowedChannelsCommand", "()I", (void*) android_net_wifi_getNumAllowedChannelsCommand },
{ "setBluetoothCoexistenceModeCommand", "(I)Z",
(void*) android_net_wifi_setBluetoothCoexistenceModeCommand },
{ "setBluetoothCoexistenceScanModeCommand", "(Z)Z",
(void*) android_net_wifi_setBluetoothCoexistenceScanModeCommand },
{ "getRssiCommand", "()I", (void*) android_net_wifi_getRssiCommand },
{ "getRssiApproxCommand", "()I",
(void*) android_net_wifi_getRssiApproxCommand},
{ "getLinkSpeedCommand", "()I", (void*) android_net_wifi_getLinkSpeedCommand },
{ "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
{ "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
{ "reloadConfigCommand", "()Z", (void*) android_net_wifi_reloadConfigCommand },
{ "setScanResultHandlingCommand", "(I)Z", (void*) android_net_wifi_setScanResultHandlingCommand },
{ "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
{ "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
{ "setSuspendOptimizationsCommand", "(Z)Z", (void*) android_net_wifi_setSuspendOptimizationsCommand},
{ "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
};
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
调用wifi.c中的函数,进行与底层链接:
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
static int doCommand(const char *cmd, char *replybuf, int replybuflen) { size_t reply_len = replybuflen - 1; if (::wifi_command(cmd, replybuf, &reply_len) != 0) return -1; else { // Strip off trailing newline if (reply_len > 0 && replybuf[reply_len-1] == '\n') replybuf[reply_len-1] = '\0'; else replybuf[reply_len] = '\0'; return 0; } } static jint doIntCommand(const char *cmd) { char reply[256]; if (doCommand(cmd, reply, sizeof(reply)) != 0) { return (jint)-1; } else { return (jint)atoi(reply); } } static jboolean doBooleanCommand(const char *cmd, const char *expect) { char reply[256]; if (doCommand(cmd, reply, sizeof(reply)) != 0) { return (jboolean)JNI_FALSE; } else { return (jboolean)(strcmp(reply, expect) == 0); } } // Send a command to the supplicant, and return the reply as a String static jstring doStringCommand(JNIEnv *env, const char *cmd) { char reply[4096]; if (doCommand(cmd, reply, sizeof(reply)) != 0) { return env->NewStringUTF(NULL); } else { String16 str((char *)reply); return env->NewString((const jchar *)str.string(), str.size()); } } static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_load_driver() == 0); } static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_unload_driver() == 0); }
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_load_driver() == 0); } static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_unload_driver() == 0); } static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_start_supplicant() == 0); } static jboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_stop_supplicant() == 0); } static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject clazz) { return (jboolean)(::wifi_connect_to_supplicant() == 0); } static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject clazz) { ::wifi_close_supplicant_connection(); } static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject clazz) { char buf[256]; int nread = ::wifi_wait_for_event(buf, sizeof buf); if (nread > 0) { return env->NewStringUTF(buf); } else { return env->NewStringUTF(NULL); } } static jstring android_net_wifi_listNetworksCommand(JNIEnv* env, jobject clazz) { return doStringCommand(env, "LIST_NETWORKS"); } static jint android_net_wifi_addNetworkCommand(JNIEnv* env, jobject clazz) { return doIntCommand("ADD_NETWORK"); }