一、Android WIFI模块初始化

上文Android讲到在SystemServer中实例化了ConnectivityService,接着的便是WIFI初始化:
frameworks/base/services/java/com/android/server/ConnectivityService.java
ConnectivityService 的构造函数会创建WifiService,

if (DBG) Log.v(TAG, "Starting Wifi Service.");      WifiStateTracker wst = new WifiStateTracker(context, mHandler);      WifiService wifiService = new WifiService(context, wst);      ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

WifiStateTracker 会创建WifiMonitor 接收来自底层的事件,WifiService 和WifiMonitor 是整个模块的核心。WifiService 负责启动关闭wpa_supplicant、启动关闭WifiMonitor 监视线程和把命令下发给wpa_supplicant,而WifiMonitor 则负责从wpa_supplicant 接收事件通知。
具体流程图如下:

Android WIFI 框架分析_第1张图片

二、WIFI模块启动

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

Packages\apps\settings\src\com\android\settings\WirelessSettings.javaprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addPreferencesFromResource(R.xml.wireless_settings);        initToggles();        mAirplaneModePreference = (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE);    }private void initToggles() {    …………    mWifiEnabler = new WifiEnabler(                this, (WifiManager) getSystemService(WIFI_SERVICE),                (CheckBoxPreference) wifiPreference);…………}


Android WIFI 框架分析_第2张图片

当用户按下Wifi 按钮后,Android 会调用WifiEnabler 的onPreferenceChange,再由WifiEnabler调用WifiManager 的setWifiEnabled 接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService 接着向自身发送一条MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:
首先装载WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/libertas_sdio.ko" ),
然后启动wpa_supplicant ( 配置文件硬编码为"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker 来启动WifiMonitor 中的监视线程。
WifiEnabler.java

public boolean onPreferenceChange(Preference preference, Object value) {        // Turn on/off Wi-Fi        setWifiEnabled((Boolean) value);            }private void setWifiEnabled(final boolean enable) {        if (!mWifiManager.setWifiEnabled(enable)) {        }    }  WifiManager.java public boolean setWifiEnabled(boolean enabled) {            return mService.setWifiEnabled(enabled);    } IWifiManager mService; interface IWifiManager{    …………    boolean startScan(boolean forceActive);    boolean setWifiEnabled(boolean enable); ………… }


IWifiManger.aidl编译后生成了IWifiManger.java,并生成IWifiManger.Stub(服务器端抽象类)和IWifiManger.Stub.Proxy(客户端代理实现类)。WifiService通过继承IWifiManger.Stub实现,而客户端通过getService()函数获取IWifiManger.Stub.Proxy(即Service的代理类),将其作为参数传递给WifiManger,供其与WifiService通信时使用。
WifiService.java

public boolean setWifiEnabled(boolean enable) {
…………
sendEnableMessage(enable, true, Binder.getCallingUid());
…………
}
private void sendEnableMessage(boolean enable, boolean persist, int uid) {
Message msg = Message.obtain(mWifiHandler,
(enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
(persist ? 1 : 0), uid);
msg.sendToTarget();
}
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE_WIFI:
setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
case MESSAGE_START_WIFI:
mWifiStateTracker.restart();
case MESSAGE_DISABLE_WIFI:
setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);
case MESSAGE_STOP_WIFI:
mWifiStateTracker.disconnectAndStop();
break;
}
}
}
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
if (enable) {
if (!WifiNative.loadDriver()) {
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
}
if (!WifiNative.startSupplicant()) {
WifiNative.unloadDriver();
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
}
registerForBroadcasts();
mWifiStateTracker.startEventLoop();
} else {
………………
}
// Success!
setWifiEnabledState(eventualWifiState, uid);
}
private void setWifiEnabledState(int wifiState, int uid) {
// Broadcast
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
JNI android_net_wifi_wifi.cpp
// ----------------------------------------------------------------------------

public boolean setWifiEnabled(boolean enable) {…………sendEnableMessage(enable, true, Binder.getCallingUid());    …………}private void sendEnableMessage(boolean enable, boolean persist, int uid) {        Message msg = Message.obtain(mWifiHandler,                                     (enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),                                     (persist ? 1 : 0), uid);        msg.sendToTarget();    }public void handleMessage(Message msg) {            switch (msg.what) {                case MESSAGE_ENABLE_WIFI:                    setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);                case MESSAGE_START_WIFI:                                      mWifiStateTracker.restart();                case MESSAGE_DISABLE_WIFI:                                     setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);                              case MESSAGE_STOP_WIFI:                    mWifiStateTracker.disconnectAndStop();                    break;            }        }    }private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {if (enable) {            if (!WifiNative.loadDriver()) {                               setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);            }            if (!WifiNative.startSupplicant()) {                WifiNative.unloadDriver();                             setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);            }            registerForBroadcasts();            mWifiStateTracker.startEventLoop();        } else {  ………………  }    // Success!               setWifiEnabledState(eventualWifiState, uid);}private void setWifiEnabledState(int wifiState, int uid) { // Broadcast        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);} JNI android_net_wifi_wifi.cpp// ----------------------------------------------------------------------------/** JNI registration.*/static JNINativeMethod gWifiMethods[] = {    /* name, signature, funcPtr */    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },       { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },       { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },          { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },      { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },}

/*
* JNI registration.
*/
static JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
{ "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
{ "reconnectCommand", "()Z", (void *)android_net_wifi_reconnectCommand },
{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
}
1)static jboolean
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz){    return (jboolean)(::wifi_load_driver() == 0);}

android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
{
return (jboolean)(:: wifi_load_driver() == 0);
}
2)static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz){    return (jboolean)(::wifi_start_supplicant() == 0);}


{
return (jboolean)(:: wifi_start_supplicant() == 0);
}
3)
WifiStateTracker.javamWifiStateTracker.startEventLoop();public void startEventLoop() {        mWifiMonitor.startMonitoring();    }//WifiMonitor.javapublic void startMonitoring() {        new MonitorThread().start();    }

WifiStateTracker.java
mWifiStateTracker.startEventLoop();
public void startEventLoop() {
mWifiMonitor. startMonitoring();
}
//WifiMonitor.java
public void startMonitoring() {
new MonitorThread().start();
}

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。// Success!后广播的。


上文讲到WIFI的启动流程,当然接着便扫描热点(AP),然后显示扫描到的AP、配置AP(填写IP地址等信息)、连接AP、获取IP地址、最后就是想要的上网咯!

一、扫描热点(AP)

上文启动WIFI成功后:// Success!

        setWifiEnabledState(eventualWifiState, uid);private void setWifiEnabledState(int wifiState, int uid) { // Broadcast        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);}

setWifiEnabledState(eventualWifiState, uid);
private void setWifiEnabledState(int wifiState, int uid) {
// Broadcast
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。WifiLayer 创建的时候就会向Android 注册接收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。

WifiSetting.java:

protected void onCreate(Bundle savedInstanceState) {    mWifiLayer.onCreate();}-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------WifiLayer.java:public void onCreate() {        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);               mIntentFilter = new IntentFilter();        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);            }public void onResume() {        mContext.registerReceiver(mReceiver, mIntentFilter);               if (isWifiEnabled()) {            // Kick start the continual scan            queueContinuousScan();        }    }

protected void onCreate(Bundle savedInstanceState) {
mWifiLayer.onCreate();
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WifiLayer.java:
public void onCreate() {
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);

mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
public void onResume() {
mContext.registerReceiver(mReceiver, mIntentFilter);
if (isWifiEnabled()) {
// Kick start the continual scan
queueContinuousScan();
}
}

以上就是WifiLayer.java注册接收的部分事件。接收部分事件处理有:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {        public void onReceive(Context context, Intent intent) {            final String action = intent.getAction();            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {                handleNetworkStateChanged(                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),                        intent.getStringExtra(WifiManager.EXTRA_BSSID));            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {                handleScanResultsAvailable();            } ……           else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,                        WifiManager.WIFI_STATE_UNKNOWN));            }                   }    };


private BroadcastReceiver mReceiver = new BroadcastReceiver() {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
handleNetworkStateChanged(
(NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
intent.getStringExtra(WifiManager.EXTRA_BSSID));
} else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
handleScanResultsAvailable();
} ……

else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));
}
}
};

从可接受的事件看,当WIFI_STATE_CHANGED_ACTION时,对应的处理函数有:

handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,                        WifiManager.WIFI_STATE_UNKNOWN));private void handleWifiStateChanged(int wifiState) {   attemptScan();   ………… }public void attemptScan() {  if (!mWifiManager.startScanActive()) {            postAttemptScan();        }}WifiManager.java:public boolean startScanActive() { return mService.startScan(true);}-------AIDL-------------------------------------------------------------------------------------------------------------------------------------------------------------------------WifiService.java:public boolean startScan(boolean forceActive) { ………… return WifiNative.scanCommand(forceActive);}---------JNI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------android_net_wifi_wifi.cpp:{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive){ ………… result = doBooleanCommand("SCAN", "OK");}static jboolean doBooleanCommand(const char *cmd, const char *expect){ if (doCommand(cmd, reply, sizeof(reply)) != 0) {        return (jboolean)JNI_FALSE;    }}static int doCommand(const char *cmd, char *replybuf, int replybuflen){ if (::wifi_command(cmd, replybuf, &reply_len) != 0)        return -1; …………}

-------HAL------------------------------------------------------------------------------------------------------------------------------------------------------------------------

wifi.c:int wifi_command(const char *command, char *reply, size_t *reply_len){ return wifi_send_command(ctrl_conn, command, reply, reply_len);}int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len){ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);…………}

wpa_ctrl.c:int wpa_ctrl_request()在wpa_ctrl.c中其实就是执行SCAN命令。

二、显示扫描的AP

当扫描成后,WifiMonitor 中的MonitorThread 会被执行来出来这个事件:

  void handleEvent(int event, String remainder) {            switch (event) {                   case SCAN_RESULTS:                    mWifiStateTracker.notifyScanResultsAvailable();->sendEmptyMessage(EVENT_SCAN_RESULTS_AVAILABLE);    break;}

WifiStateTracker.java

public void handleMessage(Message msg) {                switch (msg.what) {               case EVENT_SCAN_RESULTS_AVAILABLE:                        if (ActivityManagerNative.isSystemReady()) {                                mContext.sendBroadcast(new   Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));                            }}


WifiLayer注册接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) { else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))       {                          handleScanResultsAvailable();          } handleScanResultsAvailable();       -> list = mWifiManager.getScanResults();        -> mCallback.onAccessPointSetChanged(ap, true);

handleScanResultsAvailable()中首先会去拿到SCAN的结果(最终是往wpa_supplicant中发送SCAN_RESULT命令并读取返回值来实现的),对每一个扫描返回的AP,WifiLayer会回调WifiSetting的onAccessPointSetChanged函数,从而最终把该AP加到GUI显示列表中。

三、配置AP

当用户在 WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:

public boolean onPreferenceTreeClick()          ->showAccessPointDialog(state, AccessPointDialog.MODE_INFO);                    ->AccessPointDialog dialog   =                                            new AccessPointDialog(this,    mWifiLayer);                                     showDialog(dialog);


当用户在AccessPointDialog中选择好加密方式和输入密钥之后,再点击连接按钮,Android就会去连接这个AP。

四、连接AP

在AccessPointDialog.java中点击连接后会执行:

public void onClick(DialogInterface dialog, int which) {           handleConnect();   -> mWifiLayer.connectToNetwork(mState);    ->  // Need WifiConfiguration for the AP                               WifiConfiguration config = findConfiguredNetwork(state);                                config = addConfiguration(state, 0);                                managerEnableNetwork(state, false)          ->mWifiManager.enableNetwork()                                         ->mService.enalbeNetwork()                     ->WifiNative.enableNetworkCommand()  


接下去就JNI { "enableNetworkCommand", "(IZ)Z", (void*)android_net_wifi_enableNetworkCommand},最终就是向wpa_supplicant发送连接命令
五、获取IP地址

当wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP了,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件:

void handleEvent(int event, String remainder) {       switch (event) {                 case CONNECTED:                  handleNetworkStateChange();                  -> mWifiStateTracker.notifyStateChange(newState, BSSID, networkId);  ->msg.sendToTarget();                  break;}


WifiStateTracker.java

public void handleMessage(Message msg) {           switch (msg.what) {                          case EVENT_NETWORK_STATE_CHANGED:                       sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());                           }}


WifiStateTracker中注册的对Wifi相关数据库的观察者if(changed) 则启动:
 private void configureInterface()   ->  mDhcpTarget.sendEmptyMessage(); private class DhcpHandler extends Handler          handleMessage()              ->switch (msg.what) {                      case EVENT_DHCP_START:                              Target.sendEmptyMessage(event);


DhcpHandler会发送EVENT_DHCP_START消息启动DHCP去获取IP地址,当DHCP拿到IP地址之后,会发送EVENT_INTERFACE_CONFIGURATION_SUCCEEDED的消息,然后WifiStateTacker中的handleMessage会处理这样的消息

case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:     sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());            ->  Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);            -> mContext.sendStickyBroadcast(intent);


这次带上完整的IP地址信息。WifiLayer中注册了此Intent的接受者,会调用handleNetworkStateChanged进行处理。最后就可以自由的上网了
   

更多相关文章

  1. C语言函数以及函数的使用
  2. android收货地址整理
  3. Android Hook学习之ptrace函数的使用
  4. Android SDK Android NDK 官方下载地址
  5. Android onTouch事件
  6. Android坐标系、视图坐标系与触控事件(MotionEvent)
  7. 深入透析Android事件分发机制
  8. Android 漫游之路------Android电话拨号器(点击事件的几种写法)、A
  9. Android中回调函数的理解---本人Android纯新手

随机推荐

  1. Android DrawerLayout实现左右侧滑
  2. 【Android】常见面试题(一)
  3. Android中shape属性详解
  4. Android搜索框:SearchView用法详解
  5. Android事件分发机制和一些疑问
  6. Android View坐标getLeft, getRight, get
  7. 安卓入门.RelativeLayout相对布局1
  8. android 开发中判断网络是否连接的代码
  9. android EditText 设置弹出数字输入法键
  10. android设置横屏代码