android中wifi原理及流程分析
来源:互联网 发布:微信小程序 php服务端 编辑:程序博客网 时间:2024/05/21 17:10
wifi相关的文件位置:
WIFI Settings应用程序位于
packages/apps/Settings/src/com/android/settings/wifi/
JAVA部分:
frameworks/base/services/java/com/android/server/
frameworks/base/wifi/java/android/net/wifi/
JNI部分:
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
wifi管理库。
hardware/libhardware_legary/wifi/
wifi用户空间的程序和库:
external/wpa_supplicant/
生成库libwpaclient.so和守护进程wpa_supplicant。
调用流程:
wifi模块的初始化:
(frameworks/base/services/java/com/android/server/SystemServer.Java)
在 SystemServer 启动的时候,会生成一个ConnectivityService 的实例,
classServerThread extends Thread {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
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); }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。}
其中 ,ConnectivityService.getInstance(context); 对应于(frameworks/base/services/java/com/android/server/ConnectivityService.Java)ConnectivityService.Java。
下面看下ConnectivityService.Java中的
public static ConnectivityServicegetInstance(Context context) { return ConnectivityThread.getServiceInstance(context); }函数, 继续往下看: public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = newConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait until sServiceInstance has beeninitialized. thread.wait(); } catch (InterruptedExceptionignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }
继续往下跟:
private static class ConnectivityThread extends Thread { private Context mContext; private ConnectivityThread(Context context) { super("ConnectivityThread"); mContext = context; } @Override public void run() { Looper.prepare(); synchronized (this) { sServiceInstance = newConnectivityService(mContext); notifyAll(); } Looper.loop(); } public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = new ConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait untilsServiceInstance has been initialized. thread.wait(); } catch(InterruptedException ignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }
继续newConnectivityService(mContext)
private ConnectivityService(Context context) {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 for(int netType : mPriorityList) { switch (mNetAttributes[netType].mRadio) { case ConnectivityManager.TYPE_WIFI: Slog.v(TAG, "Starting Wifi Service."); WifiStateTracker wst = newWifiStateTracker(context, mHandler); WifiService wifiService = newWifiService(context, wst); ServiceManager.addService(Context.WIFI_SERVICE,wifiService); wifiService.startWifi();//启动wifiservice mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst; wst.startMonitoring();//启动Monitoring break; 。。。。。 }//endfor。。。。。。。。。。。。。。。。。。。。。。。。。。}
到这里模块初始化的工作完成,具体流程图如下:
WifiStateTracker 会创建 WifiMonitor 接收来自底层的事件, WifiService 和 WifiMonitor 是整个模块的核心。WifiService 负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor 监视线程和把命令下发给 wpa_supplicant,而 WifiMonitor 则负责从 wpa_supplicant 接收事件通知。
也就是说WifiService负责wifi整个流程的控制,而WifiMonitor负责监视底层的事件。
此时WifiService starting up withWi-Fi disabled,
Wifi模块的启动(Enable):
(packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java)
WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮,
protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); if (getIntent().getBooleanExtra("only_access_points",false)) { addPreferencesFromResource(R.xml.wifi_access_points); } else { addPreferencesFromResource(R.xml.wifi_settings); mWifiEnabler = new WifiEnabler(this, (CheckBoxPreference)findPreference("enable_wifi")); mNotifyOpenNetworks = (CheckBoxPreference)findPreference("notify_open_networks"); mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(), Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1); } mAccessPoints = (ProgressCategory)findPreference("access_points"); mAccessPoints.setOrderingAsAdded(false); mAddNetwork =findPreference("add_network"); registerForContextMenu(getListView()); }
然后调用:(packages/apps/Settings/src/com/android/settings/wifi/ WifiEnabler.java)
2012-03-26 jemeen 摘自 csdn博客 阅 4092 转 39转藏到我的图书馆微信分享:在网上找的一篇好文章,分析的很详细,自己再加了些东西,图片有点大,不能完全显示,点击图像拖动鼠标直接查看图像。wifi相关的文件位置:WIFI Settings应用程序位于 packages/apps/Settings/src/com/android/settings/wifi/JAVA部分: frameworks/base/services/java/com/android/server/ frameworks/base/wifi/java/android/net/wifi/JNI部分: frameworks/base/core/jni/android_net_wifi_Wifi.cppwifi管理库。 hardware/libhardware_legary/wifi/ wifi用户空间的程序和库: external/wpa_supplicant/ 生成库libwpaclient.so和守护进程wpa_supplicant。 调用流程:wifi模块的初始化:(frameworks/base/services/java/com/android/server/SystemServer.Java)在 SystemServer 启动的时候,会生成一个ConnectivityService 的实例,classServerThread extends Thread {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 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); }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。} 其中 ,ConnectivityService.getInstance(context); 对应于(frameworks/base/services/java/com/android/server/ ConnectivityService.Java)ConnectivityService.Java。下面看下ConnectivityService.Java中的 public static ConnectivityServicegetInstance(Context context) { return ConnectivityThread.getServiceInstance(context); }函数, 继续往下看: public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = newConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait until sServiceInstance has beeninitialized. thread.wait(); } catch (InterruptedExceptionignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }继续往下跟:private static class ConnectivityThread extends Thread { private Context mContext; private ConnectivityThread(Context context) { super("ConnectivityThread"); mContext = context; } @Override public void run() { Looper.prepare(); synchronized (this) { sServiceInstance = newConnectivityService(mContext); notifyAll(); } Looper.loop(); } public static ConnectivityService getServiceInstance(Context context) { ConnectivityThread thread = new ConnectivityThread(context); thread.start(); synchronized (thread) { while (sServiceInstance == null) { try { // Wait untilsServiceInstance has been initialized. thread.wait(); } catch(InterruptedException ignore) { Slog.e(TAG, "UnexpectedInterruptedException while waiting"+ " forConnectivityService thread"); } } } return sServiceInstance; } }继续newConnectivityService(mContext)private ConnectivityService(Context context) {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 for(int netType : mPriorityList) { switch (mNetAttributes[netType].mRadio) { case ConnectivityManager.TYPE_WIFI: Slog.v(TAG, "Starting Wifi Service."); WifiStateTracker wst = newWifiStateTracker(context, mHandler); WifiService wifiService = newWifiService(context, wst); ServiceManager.addService(Context.WIFI_SERVICE,wifiService); wifiService.startWifi();//启动wifiservice mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst; wst.startMonitoring();//启动Monitoring break; 。。。。。 }//endfor。。。。。。。。。。。。。。。。。。。。。。。。。。}到这里模块初始化的工作完成,具体流程图如下: WifiStateTracker 会创建 WifiMonitor 接收来自底层的事件, WifiService 和 WifiMonitor 是整个模块的核心。WifiService 负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor 监视线程和把命令下发给 wpa_supplicant,而 WifiMonitor 则负责从 wpa_supplicant 接收事件通知。也就是说WifiService负责wifi整个流程的控制,而WifiMonitor负责监视底层的事件。此时WifiService starting up withWi-Fi disabled, Wifi模块的启动(Enable): (packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java)WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮, protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); if (getIntent().getBooleanExtra("only_access_points",false)) { addPreferencesFromResource(R.xml.wifi_access_points); } else { addPreferencesFromResource(R.xml.wifi_settings); mWifiEnabler = new WifiEnabler(this, (CheckBoxPreference)findPreference("enable_wifi")); mNotifyOpenNetworks = (CheckBoxPreference)findPreference("notify_open_networks"); mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(), Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,0) == 1); } mAccessPoints = (ProgressCategory)findPreference("access_points"); mAccessPoints.setOrderingAsAdded(false); mAddNetwork =findPreference("add_network"); registerForContextMenu(getListView()); } 然后调用:(packages/apps/Settings/src/com/android/settings/wifi/ WifiEnabler.java)publicclass WifiEnabler implements Preference.OnPreferenceChangeListener {。。。。。。。。。。。。。。。。。。。。。。 public boolean onPreferenceChange(Preferencepreference, Object value) {。。。。。。。。。。。。。。。。。。。。。。。。。。。 if (mWifiManager.setWifiEnabled(enable)){ mCheckBox.setEnabled(false); } else { mCheckBox.setSummary(R.string.wifi_error); }。。。。。。。。。。。。。。。。。。。。。。 }。。。。。。。。。。。。。。。。。。。。。}
调用:
(packages/apps/Settings/src/com/android/settings/wifi/WifiManager.java)
public boolean setWifiEnabled(booleanenabled) { try { returnmService.setWifiEnabled(enabled); } catch(RemoteException e) { returnfalse; } }
当用户按下 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 中的监视线程。
WifiService(WifiService.java) 收到MESSAGE_ENABLE_WIFI 消息后的操作如下:
AIDL:
Android Interface Definition Language,即Android接口描述语言。Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(InterfaceDefinition Language,IDL)来公开服务的接口。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
接下来继续道wifiService.Java
(frameworks/base/services/java/com/android/server/ wifiService.Java)
public boolean setWifiEnabled(boolean enable) { enforceChangePermission(); if (mWifiHandler == null) return false; synchronized (mWifiHandler) { // caller may not have WAKE_LOCKpermission - it's not required here long ident =Binder.clearCallingIdentity(); sWakeLock.acquire(); Binder.restoreCallingIdentity(ident); mLastEnableUid =Binder.getCallingUid(); // set a flag if the user isenabling Wifi while in airplane mode mAirplaneModeOverwridden = (enable&& isAirplaneModeOn() && isAirplaneToggleable()); sendEnableMessage(enable, true,Binder.getCallingUid()); // here send a mesage to himself } return true; }继续往下: 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(); }WifiHandler会收到消息:private class WifiHandlerextends Handler {。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。public voidhandleMessage(Message msg) { switch (msg.what) { case MESSAGE_ENABLE_WIFI: setWifiEnabledBlocking(true, msg.arg1 == 1,msg.arg2); if (mWifiWatchdogService ==null) { mWifiWatchdogService = newWifiWatchdogService(mContext, mWifiStateTracker); } sWakeLock.release(); break;。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 }。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。}privateboolean setWifiEnabledBlocking(booleanenable, boolean persist, int uid) {。。。。。。。。。。。。 setWifiEnabledState(enable ?WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid); if (enable) { if (!mWifiStateTracker.loadDriver()){ Slog.e(TAG, "Failed toload Wi-Fi driver."); setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); return false; } if (!mWifiStateTracker.startSupplicant()){ mWifiStateTracker.unloadDriver(); Slog.e(TAG, "Failed tostart supplicant daemon."); setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); return false; } registerForBroadcasts(); mWifiStateTracker.startEventLoop(); } else { mContext.unregisterReceiver(mReceiver); // Remove notification (it willno-op if it isn't visible) mWifiStateTracker.setNotificationVisible(false,0, false, 0); booleanfailedToStopSupplicantOrUnloadDriver = false; if (!mWifiStateTracker.stopSupplicant()){ Slog.e(TAG, "Failed tostop supplicant daemon."); setWifiEnabledState(WIFI_STATE_UNKNOWN,uid); failedToStopSupplicantOrUnloadDriver = true; } /** * Reset connections and disableinterface * before we unload the driver */ mWifiStateTracker.resetConnections(true); if (!mWifiStateTracker.unloadDriver()){ Slog.e(TAG, "Failed tounload Wi-Fi driver."); if(!failedToStopSupplicantOrUnloadDriver) { setWifiEnabledState(WIFI_STATE_UNKNOWN, uid); failedToStopSupplicantOrUnloadDriver = true; } } if(failedToStopSupplicantOrUnloadDriver) { return false; } }。。。。。。。。。。。。。。。。。。。。。。}
扫描查找热点(AP)
上一节中讲到Wifi模块开启后会对外发送WIFI_STATE_CHANGED_ACTION。WifiLayer中注册了Action的Receiver。
当WifiLayer收到此Action后开始scan的流程,具体如下:
当wpa_supplicant 处理完SCAN 命令后,它会向控制通道发送事件通知扫描完成,从wifi_wait_for_event函数会接收到该事件,由此WifiMonitor 中的MonitorThread会被执行来出来这个事件:
配置 AP 参数
当用户在WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:
Wifi连接
具体流程参见以下流程图:
IP地址的配置
流程如图:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- Android中WiFi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- android中wifi原理及流程分析(很经典)
- nodejs npm install全局安装和本地安装的区别
- Android开机启动APP
- 【Android】AndroidStudio空指针解决之:listview与adapter的使用报空 java.lang.NullPointerException
- 由Monkey测试引发的跨多个进程的Android系统死锁问题分析
- android程序改为用系统签名
- android中wifi原理及流程分析
- IM推送Android客户端之重连策略
- python 在不同层级目录import 模块的方法
- [Spring]web.xml中配置ContextLoaderListener监听器的作用
- 三范式
- HTML第四章 上机5
- 进程空间-徐明伟
- Sublime Text 格式化代码
- Android DIY之路 (一) 指定区域多图片合成 放大 缩小 镜像 旋转 等