在網(wǎng)上找的一篇好文章,分析的很詳細(xì),自己再加了些東西,圖片有點(diǎn)大,不能完全顯示,點(diǎn)擊圖像拖動(dòng)鼠標(biāo)直接查看圖像。 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管理庫。 hardware/libhardware_legary/wifi/ wifi用戶空間的程序和庫: external/wpa_supplicant/ 生成庫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 { 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 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 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; } } 。。。。。。。。。。。。。。。。。。。。。。 } 具體流程如下流程圖所示:
掃描查找熱點(diǎn)(AP) 當(dāng)wpa_supplicant 處理完SCAN 命令后,它會(huì)向控制通道發(fā)送事件通知掃描完成,從wifi_wait_for_event函數(shù)會(huì)接收到該事件,由此WifiMonitor 中的MonitorThread會(huì)被執(zhí)行來出來這個(gè)事件:
配置 AP 參數(shù)
Wifi連接
IP地址的配置 到此結(jié)束。 |
|