wifi相關(guān)的文件位置:
WIFI Settings應(yīng)用程序位于
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管理庫(kù)。
hardware/libhardware_legary/wifi/
wifi用戶空間的程序和庫(kù):
external/wpa_supplicant/
生成庫(kù)libwpaclient.so和守護(hù)進(jìn)程wpa_supplicant占调。
調(diào)用流程:
wifi模塊的初始化:
(frameworks/base/services/java/com/android/server/SystemServer.Java)
在 SystemServer 啟動(dòng)的時(shí)候,會(huì)生成一個(gè)ConnectivityService 的實(shí)例,
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); 對(duì)應(yīng)于(frameworks/base/services/java/com/android/server/ ConnectivityService.Java)ConnectivityService.Java慈格。
下面看下ConnectivityService.Java中的
public static ConnectivityServicegetInstance(Context context) {
return** ConnectivityThread.getServiceInstance**(context);
}函數(shù), 繼續(xù)往下看:
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;
}
}
繼續(xù)往下跟:
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;
}
}
繼續(xù)**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();//啟動(dòng)wifiservice**
mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
**wst.startMonitoring();//啟動(dòng)Monitoring**
break; 。墙贱。热芹。。惨撇。
}//endfor
伊脓。。魁衙。报腔。。剖淀。纯蛾。。祷蝌。茅撞。。巨朦。米丘。。糊啡。拄查。。棚蓄。堕扶。。梭依。稍算。。役拴。糊探。。
}
到這里模塊初始化的工作完成,具體流程圖如下:
WifiStateTracker 會(huì)創(chuàng)建 WifiMonitor 接收來自底層的事件, WifiService 和 WifiMonitor 是整個(gè)模塊的核心科平。WifiService 負(fù)責(zé)啟動(dòng)關(guān)閉 wpa_supplicant褥紫、啟動(dòng)關(guān)閉 WifiMonitor 監(jiān)視線程和把命令下發(fā)給 wpa_supplicant,而 WifiMonitor 則負(fù)責(zé)從 wpa_supplicant 接收事件通知。
也就是說WifiService負(fù)責(zé)wifi整個(gè)流程的控制瞪慧,而WifiMonitor負(fù)責(zé)監(jiān)視底層的事件髓考。
此時(shí)WifiService starting up withWi-Fi disabled,
Wifi模塊的啟動(dòng)(Enable):
(packages/apps/Settings/src/com/android/settings/wifi/ WirelessSettings.java)
WirelessSettings 在初始化的時(shí)候配置了由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());
}
然后調(diào)用:**(**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);
}
。狭吼。层坠。。刁笙。破花。。疲吸。座每。。磅氨。尺栖。。烦租。延赌。。叉橱。挫以。。窃祝。掐松。。
}
。大磺。抡句。。杠愧。待榔。。流济。锐锣。。绳瘟。雕憔。。糖声。斤彼。。蘸泻。畅卓。。蟋恬。。
}
調(diào)用:
**(**packages/apps/Settings/src/com/android/settings/wifi/ **WifiManager.java)**
public boolean setWifiEnabled(booleanenabled) {
try {
returnmService.**setWifiEnabled**(enabled);
} catch(RemoteException e) {
returnfalse;
}
}
當(dāng)用戶按下 Wifi 按鈕后, Android 會(huì)調(diào)用 WifiEnabler 的onPreferenceChange, 再由 WifiEnabler調(diào)用 WifiManager 的 **setWifiEnabled** 接口函數(shù),通過 AIDL,實(shí)際調(diào)用的是 WifiService 的**setWifiEnabled** 函數(shù),WifiService 接著向自身發(fā)送一條 MESSAGE_ENABLE_WIFI 消息,在處理該消息的代碼中做真正的使能工作:首先裝載 WIFI 內(nèi)核模塊(該模塊的位置硬編碼為"/system/lib/modules/wlan.ko" ), 然 后 啟 動(dòng) wpa_supplicant ( 配 置 文 件 硬 編 碼 為"/data/misc/wifi/wpa_supplicant.conf")再通過 WifiStateTracker 來啟動(dòng) WifiMonitor 中的監(jiān)視線程趁冈。
WifiService(WifiService.java) 收到MESSAGE_ENABLE_WIFI 消息后的操作如下:
AIDL:
Android Interface Definition Language,即Android接口描述語言歼争。Android系統(tǒng)中的進(jìn)程之間不能共享內(nèi)存,因此渗勘,需要提供一些機(jī)制在不同進(jìn)程之間進(jìn)行數(shù)據(jù)通信沐绒。
為了使其他的應(yīng)用程序也可以訪問本應(yīng)用程序提供的服務(wù),Android系統(tǒng)采用了遠(yuǎn)程過程調(diào)用(Remote Procedure Call旺坠,RPC)方式來實(shí)現(xiàn)乔遮。與很多其他的基于RPC的解決方案一樣,Android使用一種接口定義語言(InterfaceDefinition Language取刃,IDL)來公開服務(wù)的接口蹋肮。因此,可以將這種可以跨進(jìn)程訪問的服務(wù)稱為AIDL(Android Interface Definition Language)服務(wù)璧疗。
接下來繼續(xù)道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;
}
繼續(xù)往下:
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會(huì)收到消息:
private class **WifiHandler**extends 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;
** }**
}
树姨。摩桶。。娃弓。典格。。台丛。耍缴。。挽霉。防嗡。。侠坎。蚁趁。。实胸。他嫡。。庐完。钢属。。门躯。
}
具體流程如下流程圖所示:
掃描查找熱點(diǎn)(AP)
上一節(jié)中講到Wifi模塊開啟后會(huì)對(duì)外發(fā)送WIFI_STATE_CHANGED_ACTION淆党。WifiLayer中注冊(cè)了Action的Receiver。
當(dāng)WifiLayer收到此Action后開始scan的流程讶凉,具體如下:
當(dāng)wpa_supplicant 處理完SCAN 命令后染乌,它會(huì)向控制通道發(fā)送事件通知掃描完成,從wifi_wait_for_event函數(shù)會(huì)接收到該事件懂讯,由此WifiMonitor 中的MonitorThread會(huì)被執(zhí)行來出來這個(gè)事件:
配置 AP 參數(shù)
當(dāng)用戶在WifiSettings 界面上選擇了一個(gè)AP 后荷憋,會(huì)顯示配置AP 參數(shù)的一個(gè)對(duì)話框:
Wifi連接
具體流程參見以下流程圖:
IP地址的配置
流程如圖:
到此結(jié)束。