http://blog.csdn.net/u010961631/article/details/48291095
本文簡要介紹WIFI服務的主要框架以及運作機制。
WIFI框架主要涉及到以下幾個對象:WifiService、WifiManager、WifiServiceImpl、WifiStateMachine等。下面來介紹這四個對象的內在聯繫。
一、WIFI服務的初始化
WIFI服務的初始化分爲兩個部分,WifiService的初始化和WifiManager的初始化,下面分別介紹。
1.1、WifiService的初始化流程
WifiService的初始化流程是在SystemService中被啓動的:
-
@SystemServer.java
-
private static final String WIFI_SERVICE_CLASS = "com.android.server.wifi.WifiService";
-
private void startOtherServices() {
-
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
-
}
在這裏通過SystemServiceManager將WIFI的主服務(WifiService)啓動,然後來看該Service的啓動過程:
-
@WifiService.java
-
public final class WifiService extends SystemService {
-
private static final String TAG = "WifiService";
-
final WifiServiceImpl mImpl;
-
public WifiService(Context context) {
-
super(context);
-
-
mImpl = new WifiServiceImpl(context);
-
}
-
@Override
-
public void onStart() {
-
-
publishBinderService(Context.WIFI_SERVICE, mImpl);
-
}
-
-
-
@Override
-
public void onBootPhase(int phase) {
-
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
-
mImpl.checkAndStartWifi();
-
}
-
}
-
}
以上是WifiService的全部內容,其實該Service只完成了兩個任務:
1、在初始化時,也就是構造方法中,創建WifiServiceImpl對象。
2、在onStart時,將WifiServiceImpl對象註冊到ServiceManager中。
這裏創建的WifiServiceImpl是整個WIFI服務的管理者,他負責將客戶端對WIFI的請求分類,然後派發給不同的處理中心。
下面先來看WifiServiceImpl的屬性:
-
public final class WifiServiceImpl extends IWifiManager.Stub {}
這說明該類是一個服務的實現類。
然後來看該對象的初始化過程,也就是構造方法:
-
@WifiServiceImpl.java
-
public WifiServiceImpl(Context context) {
-
mContext = context;
-
mInterfaceName = SystemProperties.get("wifi.interface", "wlan0");
-
mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
-
-
mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);
-
mWifiStateMachine.enableRssiPolling(true);
-
-
mBatteryStats = BatteryStatsService.getService();
-
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
-
mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
-
mSettingsStore = new WifiSettingsStore(mContext);
-
HandlerThread wifiThread = new HandlerThread("WifiService");
-
wifiThread.start();
-
mClientHandler = new ClientHandler(wifiThread.getLooper());
-
mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
-
mWifiController = new WifiController(mContext, this, wifiThread.getLooper());
-
mBatchedScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_batched_scan_supported);
-
}
在這裏初始化各種與WIFI管理有關的輔助類,其中包含最重要的一個就是WIFI的狀態機WifiStateMachine,他是整個WIFI機制的核心。下面來看該狀態機的初始化流程:
-
@WifiStateMachine.java
-
public WifiStateMachine(Context context, String wlanInterface, WifiTrafficPoller trafficPoller){
-
super("WifiStateMachine");
-
mContext = context;
-
mInterfaceName = wlanInterface;
-
-
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
-
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService( BatteryStats.SERVICE_NAME));
-
-
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-
mNwService = INetworkManagementService.Stub.asInterface(b);
-
mP2pSupported = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_DIRECT);
-
mWifiNative = new WifiNative(mInterfaceName);
-
mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
-
mWifiAutoJoinController = new WifiAutoJoinController(context, this, mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);
-
mWifiMonitor = new WifiMonitor(this, mWifiNative);
-
mWifiInfo = new WifiInfo();
-
......
-
-
addState(mDefaultState);
-
addState(mInitialState, mDefaultState);
-
addState(mSupplicantStartingState, mDefaultState);
-
addState(mSupplicantStartedState, mDefaultState);
-
addState(mDriverStartingState, mSupplicantStartedState);
-
addState(mDriverStartedState, mSupplicantStartedState);
-
addState(mScanModeState, mDriverStartedState);
-
addState(mConnectModeState, mDriverStartedState);
-
addState(mL2ConnectedState, mConnectModeState);
-
addState(mObtainingIpState, mL2ConnectedState);
-
addState(mVerifyingLinkState, mL2ConnectedState);
-
addState(mConnectedState, mL2ConnectedState);
-
addState(mRoamingState, mL2ConnectedState);
-
addState(mDisconnectingState, mConnectModeState);
-
addState(mDisconnectedState, mConnectModeState);
-
addState(mWpsRunningState, mConnectModeState);
-
addState(mWaitForP2pDisableState, mSupplicantStartedState);
-
addState(mDriverStoppingState, mSupplicantStartedState);
-
addState(mDriverStoppedState, mSupplicantStartedState);
-
addState(mSupplicantStoppingState, mDefaultState);
-
addState(mSoftApStartingState, mDefaultState);
-
addState(mSoftApStartedState, mDefaultState);
-
addState(mTetheringState, mSoftApStartedState);
-
addState(mTetheredState, mSoftApStartedState);
-
addState(mUntetheringState, mSoftApStartedState);
-
-
setInitialState(mInitialState);
-
-
start();
-
......
-
}
我們看到,在WifiStateMachine的初始化過程中創建了大量的輔助類,其中就包括NetworkInfo,他的作用就是標記當前網絡的各項屬性,比如當前網絡的類型、是否可用、是否處於漫遊等,然後還創建了許多WIFI的狀態機,標識當前WIFI所處的狀態,最後將狀態機初始狀態設置爲mInitialState,並將狀態機start。
以上就是WifiService的全部初始化過程,其主要過程分爲以下四個部分:
1、在SystemServer中啓動WifiService;
2、在WifiService啓動過程中創建並初始化WifiServiceImpl;
3、在WifiServiceImpl初始化過程中創建並初始化WifiStateMachine對象;
4、在WifiStateMachine初始化過程中創建各種狀態機並啓動他們;
1.2、WifiManager的初始化流程
WIFI框架還有另外一個初始化流程實在ContextImpl中進行的。
當系統初始化時,會在Context對象的實現類ContextImpl中註冊一些常用的服務,這樣就可以在應用內部通過Context對象的getSystemService()方法來獲取相應的服務。而WIFI在ContextImpl中註冊了WifiManager用於向一般應用提供WIFI的服務:
-
@ContextImpl.java
-
registerService(WIFI_SERVICE, new ServiceFetcher() {
-
public Object createService(ContextImpl ctx) {
-
IBinder b = ServiceManager.getService(WIFI_SERVICE);
-
IWifiManager service = IWifiManager.Stub.asInterface(b);
-
return new WifiManager(ctx.getOuterContext(), service);
-
}});
從這裏可以知道兩個信息:
1、應用可以通過Context對象的getSystemService(Context.WIFI_SERVICE)的方法獲取到一個WifiManager的對象用於控制WIFI;
2、WifiManager的創建需要使用ServiceManager的WIFI_SERVICE服務,而這個WIFI_SERVICE就是在WifiService中註冊的WifiServiceImpl對象;
下面來看WifiManager的創建過程:
-
@WifiManager.java
-
public WifiManager(Context context, IWifiManager service) {
-
mContext = context;
-
-
mService = service;
-
init();
-
}
-
private void init() {
-
synchronized (sThreadRefLock) {
-
if (++sThreadRefCount == 1) {
-
-
Messenger messenger = getWifiServiceMessenger();
-
if (messenger == null) {
-
sAsyncChannel = null;
-
return;
-
}
-
-
sHandlerThread = new HandlerThread("WifiManager");
-
sAsyncChannel = new AsyncChannel();
-
sConnected = new CountDownLatch(1);
-
sHandlerThread.start();
-
Handler handler = new ServiceHandler(sHandlerThread.getLooper());
-
-
sAsyncChannel.connect(mContext, handler, messenger);
-
try {
-
sConnected.await();
-
} catch (InterruptedException e) {
-
Log.e(TAG, "interrupted wait at init");
-
}
-
}
-
}
-
}
從上面WifiManager的初始化過程中我們看到,其初始化的過程中完成了以下兩個任務:
1、用WifiServiceImpl初始化mService對象;
2、向WifiServiceImpl申請單向的AsyncChannel(想要連接AsyncChannel請點擊這裏);
至此,WIFI框架就完成了所有需要初始化的動作,我們用一張流程圖來標識該過程:
二、WIFI服務的運作機制
由於應用操作WIFI是通過WifiManager進行的,那麼我們可以從WifiManager開始來查找消息在WIFI內部的傳遞機制。
以下是WifiManager提供的幾個比較重要的對外接口:
-
-
public List<WifiConfiguration> getConfiguredNetworks() {}
-
-
public int addNetwork(WifiConfiguration config) {}
-
-
public int updateNetwork(WifiConfiguration config) {}
-
-
public boolean is5GHzBandSupported() {}
-
-
public boolean isPortableHotspotSupported() {}
-
-
public boolean setWifiEnabled(boolean enabled) {}
-
-
public void connect(int networkId, ActionListener listener) {}
-
-
public boolean disconnect() {}
-
-
public boolean addToBlacklist(String bssid) {}
-
-
public boolean clearBlacklist() {}
我們挑選兩個比較典型的方法進行跟蹤,分別是:控制WIFI開關的setWifiEnabled()和連接某個WIFI的connect()方法。
爲什麼要挑選這兩個方法呢?是因爲這兩個方法分別使用兩種方式與WifiService進行通訊。
2.1、setWifiEnabled方式
在該方式中,WifiManager通過直接調用的方式與WifiServiceImpl進行通訊。
-
@WifiManager.java
-
public boolean setWifiEnabled(boolean enabled) {
-
try {
-
-
return mService.setWifiEnabled(enabled);
-
} catch (RemoteException e) {
-
return false;
-
}
-
}
2.2、connect方式
與setWifiEnabled不同,在該方式中,WifiManager利用與WifiServiceImpl之間的AsyncChannel來交換信息:
-
@WifiManager.java
-
public void connect(int networkId, ActionListener listener) {
-
if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
-
validateChannel();
-
-
sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
-
}
2.3、WifiManager小結
在上面兩節中分別介紹了兩種WifiManager與WifiServiceImpl通訊的方式,其實不僅是以上兩個方法,WifiManager中所有的對外公開的public方法,最終都是通過這兩種方式與WifiServiceImpl進行溝通。
我們可以這樣理解WifiManager:他是WIFI模塊向外部應用透漏出來的接口,其他所有應用都可以通過WifiManager操作WIFI各項功能,但是WifiManager本身並不具備處理請求的能力,而是把所有請求轉發給WifiServiceImpl對象,而發送請求的方式就是直接調用或者通過AsyncChannel。
2.4、WifiServiceImpl中對請求的處理
無論採用何種溝通方式,WifiManager最終都會把應用的請求轉交給WifiServiceImpl來處理。那麼接下來的流程是怎樣的呢?WifiServiceImpl將會如何處理WifiManager轉發過來的請求呢?
我們繼續跟蹤上面兩個方法的調用流程來查看WifiServiceImpl的處理過程。
先來看setWifiEnabled()方法,該方法是直接由WifiManager調用到WifiServiceImpl中的,其實現如下:
-
@WifiServiceImpl.java
-
public synchronized boolean setWifiEnabled(boolean enable) {
-
-
enforceChangePermission();
-
-
-
-
long ident = Binder.clearCallingIdentity();
-
try {
-
if (! mSettingsStore.handleWifiToggled(enable)) {
-
return true;
-
}
-
} finally {
-
Binder.restoreCallingIdentity(ident);
-
}
-
-
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
-
return true;
-
}
在這裏我們看到,WifiServiceImpl將請求轉交給WifiController來處理。
下面來看WifiManager中connect()方法的處理,當初WifiManager收到該請求後,通過AsyncChannel的方式向WifiServiceImpl發送CONNECT_NETWORK的請求,那麼WifiServiceImpl的接下來就需要在自己的Messenger中處理,而這個Messenger是從getWifiServiceMessenger()中傳遞給WifiManager的,我們來看是哪個Messenger來處理該請求:
-
@WifiServiceImpl.java
-
public Messenger getWifiServiceMessenger() {
-
-
enforceAccessPermission();
-
enforceChangePermission();
-
-
return new Messenger(mClientHandler);
-
}
從這裏看到,WifiManager拿到的Messenger中的Handler其實就是mClientHandler,他是在WifiServiceImpl初始化時被創建的:
-
@WifiServiceImpl.java
-
public WifiServiceImpl(Context context) {
-
......
-
HandlerThread wifiThread = new HandlerThread("WifiService");
-
wifiThread.start();
-
mClientHandler = new ClientHandler(wifiThread.getLooper());
-
}
也就是說WifiManager通過AsyncChannel發送的消息都會在ClientHandler中接收到:
-
private class ClientHandler extends Handler {
-
ClientHandler(android.os.Looper looper) {
-
super(looper);
-
}
-
@Override
-
public void handleMessage(Message msg) {
-
switch (msg.what) {
-
case WifiManager.CONNECT_NETWORK:
-
case WifiManager.SAVE_NETWORK: {
-
WifiConfiguration config = (WifiConfiguration) msg.obj;
-
int networkId = msg.arg1;
-
if (msg.what == WifiManager.SAVE_NETWORK) {
-
}
-
if (msg.what == WifiManager.CONNECT_NETWORK) {
-
if (config != null) {
-
-
if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) {
-
config.creatorUid = Binder.getCallingUid();
-
} else {
-
config.lastUpdateUid = Binder.getCallingUid();
-
}
-
}
-
}
-
if (config != null && config.isValid()) {
-
-
mWifiStateMachine.sendMessage(Message.obtain(msg));
-
} else if (config == null && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
-
mWifiStateMachine.sendMessage(Message.obtain(msg));
-
} else {
-
if (msg.what == WifiManager.CONNECT_NETWORK) {
-
replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED, WifiManager.INVALID_ARGS);
-
} else {
-
replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED, WifiManager.INVALID_ARGS);
-
}
-
}
-
break;
-
}
-
}
-
}
-
}
從上面這個處理來看,WifiServiceImpl將請求轉交給WifiStateMachine來處理。
其實WifiServiceImpl對請求的處理與WifiManager類似,他本身並不具備處理事物的能力,只是將請求分類後交由不同的處理者去處理。
以上就是整個WIFI框架的初始化以及內部消息處理機制,下面用一張圖來標識WIFI內部的消息流: