WIFI框架主要涉及到以下几个对象:WifiService、WifiManager、WifiServiceImpl、WifiStateMachine等。下面来介绍这四个对象的内在联系。
WIFI服务的初始化分为两个部分,WifiService的初始化和WifiManager的初始化,下面分别介绍。
@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); //创建WifiServiceImpl对象 mImpl = new WifiServiceImpl(context); } @Override public void onStart() { //将WifiServiceImpl注册到ServiceManager publishBinderService(Context.WIFI_SERVICE, mImpl); } @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { mImpl.checkAndStartWifi(); } } }以上是WifiService的全部内容,其实该Service只完成了两个任务:
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); //创建wifi状态机 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; //创建NetworkInfo对象 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。
4、在WifiStateMachine初始化过程中创建各种状态机并启动他们;
@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); }});从这里可以知道两个信息:
@WifiManager.java public WifiManager(Context context, IWifiManager service) { mContext = context; //这里的mService就是创建WifiManager时传递进来的WifiServiceImpl对象 mService = service; init(); } private void init() { synchronized (sThreadRefLock) { if (++sThreadRefCount == 1) { //获取WifiServiceImpl中的Messenger对象 Messenger messenger = getWifiServiceMessenger(); if (messenger == null) { sAsyncChannel = null; return; } //创建AsyncChannel通道 sHandlerThread = new HandlerThread("WifiManager"); sAsyncChannel = new AsyncChannel(); sConnected = new CountDownLatch(1); sHandlerThread.start(); Handler handler = new ServiceHandler(sHandlerThread.getLooper()); //与WifiServiceImpl申请建立单向AsyncChannel sAsyncChannel.connect(mContext, handler, messenger); try { sConnected.await(); } catch (InterruptedException e) { Log.e(TAG, "interrupted wait at init"); } } } }从上面WifiManager的初始化过程中我们看到,其初始化的过程中完成了以下两个任务:
//获取所有网络连接 public List<WifiConfiguration> getConfiguredNetworks() {} //添加网络连接 public int addNetwork(WifiConfiguration config) {} //更新网络连接 public int updateNetwork(WifiConfiguration config) {} //是否支持5Ghz public boolean is5GHzBandSupported() {} //是否支持WIFI热点 public boolean isPortableHotspotSupported() {} //打开关闭WIFI public boolean setWifiEnabled(boolean enabled) {} //连接某个WIFI public void connect(int networkId, ActionListener listener) {} //断开当前连接 public boolean disconnect() {} //添加黑名单 public boolean addToBlacklist(String bssid) {} //清除黑名单 public boolean clearBlacklist() {}我们挑选两个比较典型的方法进行跟踪,分别是:控制WIFI开关的setWifiEnabled()和连接某个WIFI的connect()方法。
为什么要挑选这两个方法呢?是因为这两个方法分别使用两种方式与WifiService进行通讯。
@WifiManager.java public boolean setWifiEnabled(boolean enabled) { try { //直接调用mService的setWifiEnabled方法 return mService.setWifiEnabled(enabled); } catch (RemoteException e) { return false; } }
@WifiManager.java public void connect(int networkId, ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); validateChannel(); //通过AsyncChannel与WifiServiceImpl传递信息 sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); }
我们可以这样理解WifiManager:他是WIFI模块向外部应用透漏出来的接口,其他所有应用都可以通过WifiManager操作WIFI各项功能,但是WifiManager本身并不具备处理请求的能力,而是把所有请求转发给WifiServiceImpl对象,而发送请求的方式就是直接调用或者通过AsyncChannel。
@WifiServiceImpl.java public synchronized boolean setWifiEnabled(boolean enable) { //权限检查 enforceChangePermission(); //权限检查 long ident = Binder.clearCallingIdentity(); try { if (! mSettingsStore.handleWifiToggled(enable)) { return true; } } finally { Binder.restoreCallingIdentity(ident); } //向WifiController发送请求 mWifiController.sendMessage(CMD_WIFI_TOGGLED); return true; }在这里我们看到,WifiServiceImpl将请求转交给WifiController来处理。
@WifiServiceImpl.java public Messenger getWifiServiceMessenger() { //权限检查 enforceAccessPermission(); enforceChangePermission(); //这里的Messenger的Handler是mClientHandler 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) { //配置config if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) { config.creatorUid = Binder.getCallingUid(); } else { config.lastUpdateUid = Binder.getCallingUid(); } } } if (config != null && config.isValid()) { //将请求发送给WifiStateMachine 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来处理。