Android&4.0&WIFI初始化与启动流程
这几天闲着没事,我就随便拿起Android源码看看。以下要讲的是在ICS中wifi初始化的一些流程。 涉及的文件有: SystemServer.java WifiSettings.java WifiEnabler.java WifiManager.java WifiService.java WifiStateMachine.java android_net_wifi_wifi.cpp wifi.c 首先从SystemServer.java开始,它做了3个动作: 1.添加注册ConnectivityService连接服务,它跟所有手机的无线通信都有联系,包括wifi,蓝牙,2g网络,3g网络等 connectivity = new ConnectivityService(&&&&&&&&&&&&&&&&&&&&&&& context, networkManagement, networkStats, networkPolicy);ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); 2.管理开机wifi开启与否的问题 wifi.checkAndStartWifi(); &&& public void checkAndStartWifi() {&&&&&&& mAirplaneModeOn.set(isAirplaneModeOn());&&&&&&& mPersistWifiState.set(getPersistedWifiState());&&&&&&& boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();&&&&&&& setWifiEnabled(wifiEnabled);&&&&&&& mWifiWatchdogStateMachine = WifiWatchdogStateMachine.&&&&&&&&&&&&&& makeWifiWatchdogStateMachine(mContext);&&& } 3.添加注册wifi的核心服务wifiservice &wifi = new WifiService(context);&ServiceManager.addService(Context.WIFI_SERVICE, wifi); 好了,机器启动的时候动作就这些。要开启wifi,还需要人在设置界面进行开启。· 下面将一步步介绍wifi是怎样开启起来的 进入wifi设置界面,相关文件WifiSettings.java 开启Wifi的组件是一个CompoundButton,跟它关联起来的是一个WifiEnabler.java类,它是在WifiSettings里面初始化的 &&& public void onActivityCreated(Bundle savedInstanceState) {&&&&&&&&&&&&&&& mWifiEnabler = new WifiEnabler(activity, actionBarSwitch); &&& } 当用户点击wifi的开启按钮时候,会触发WifiEnabler里面的onCheckedChanged函数 &&& public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {&&&&&&& if (mWifiManager.setWifiEnabled(isChecked)) {&&&&&&&&&&& mSwitch.setEnabled(false);&&&&&& & } else {&&& &&&&&&&&&&& Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();&&& }在onCheckedChanged函数里面,调用了WifiManager的setWifiEnabled方法 &&& public boolean setWifiEnabled(boolean enabled) {&&&&&&& try {&&&&&&&&&&& return mService.setWifiEnabled(enabled);&&&&&&& } catch (RemoteException e) {&&&&&&&&&&&&&&&&&& }&&& } 它返回的是mService.setWifiEnabled(enabled),这里的mService是WifiService的代理,所以它实际调用的是wifiService里面的setWifiEnabled函数 public class WifiService extends IWifiManager.Stub ,我们可以看到WifiService继承一个接口IWifiManager.Stub,凡是继承了像这种形式写法的接口服务,都可以进行远程调用,这就是Android内部的aidl通信。接下来进入wifiservice &&& public synchronized boolean setWifiEnabled(boolean enable) {&&&&&&& mWifiStateMachine.setWifiEnabled(enable);&&& } 可以看到,又进入WifiStateMachine的setWifiEnabled方法,mWifiStateMachine是在Wifiservice的构造函数完成初始化 的 &&& WifiService(Context context) {&&&&&&& mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);&&& } 先介绍一下WifiStateMachine这个类,光看名字就知道wifi状态机,它里面记录了wifi的各种状态,driverUnloadedstate、mDriverUnloadingState、mDriverLoadingState、mDriverLoadedState、mSupplicantStartingState,每种状态都有enter()、exit()、processMessage()3个函数,分别处理进入该状态,退出该状态的动作,以及消息处理。在WifiStateMachine构造函数里面,它把所有状态都添加进状态机去,形成一个状态树,并在结尾出启动这个状态机工作。 &&& public WifiStateMachine(Context context, String wlanInterface) {&&&&&&& addState(mDefaultState);&&&&&&&&&&& addState(mInitialState, mDefaultState);&&&&&&&&&&& addState(mDriverUnloadingState, mDefaultState);&&&&&&&&&&& addState(mDriverUnloadedState, mDefaultState);&&&&&&&&&&&&&&& addState(mDriverFailedState, mDriverUnloadedState);&&&&&&&&&&& addState(mDriverLoadingState, mDefaultState);&&&&&&&&&&& addState(mDriverLoadedState, mDefaultState);&&&&&&&&&&& addState(mSupplicantStartingState, mDefaultState);&&&&&&&&&&& addState(mSupplicantStartedState, mDefaultState);&&&&&&&&&&&&&&& addState(mDriverStartingState, mSupplicantStartedState);&&&&&&&&&&&&&&& addState(mDriverStartedState, mSupplicantStartedState);&&&&&&&&&&&&&&&&&&& addState(mScanModeState, mDriverStartedState);&&&&&&&&&&&&&&&&&&& addState(mConnectModeState, mDriverStartedState);&&&&&&&&&&&&&&&&&&&&&&& addState(mConnectingState, mConnectModeState);&&&&&&&&&&&&&&&&&&&&&&& addState(mConnectedState, mConnectModeState);&&&&&&&&&&&&&&&&&&&&&&& addState(mDisconnectingState, mConnectModeState);&&&&&&&&&&&&&&&&&&&&&&& addState(mDisconnectedState, mConnectModeState);&&&&&&&&&&&&&&&&&&&&&&& addState(mWaitForWpsCompletionState, mConnectModeState);&&&&&&&&&&&&&&& addState(mDriverStoppingState, mSupplicantStartedState);&&&&&&&&&&&&&&& addState(mDriverStoppedState, mSupplicantStartedState);&&&&&&&&&&& addState(mSupplicantStoppingState, mDefaultState);&&&&&&&&&&& addState(mSoftApStartingState, mDefaultState);&&&&&&&&&&& addState(mSoftApStartedState, mDefaultState);&&&&&&&&&&&&&&& addState(mTetheringState, mSoftApStartedState);&&&&&&&&&&&&&&& addState(mTetheredState, mSoftApStartedState);&&&&&&&&&&& addState(mSoftApStoppingState, mDefaultState);&&&&&&&&&&& addState(mWaitForP2pDisableState, mDefaultState);&&& 。。。。。。。。。。 &&&&&&&& start(); &&& } 具体状态机是如何工作的,这篇文章有很详细的介绍,我就不累赘了。/a/2424626/ 我们再回到mWifiStateMachine.setWifiEnabled(enable)函数;&&& public void setWifiEnabled(boolean enable) { &&&&&&& mLastEnableUid.set(Binder.getCallingUid()); &&&&&&& if (enable) { &&&&&&&&&&& &&&&&&&&&&& sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0)); &&&&&&&&&&& sendMessage(CMD_START_SUPPLICANT); &&&&&&& } else { &&&&&&&&&&& sendMessage(CMD_STOP_SUPPLICANT); &&&&&&&&&&& &&&&&&&&&&& sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0)); &&&&&&& } &&& } 它做了两个动作,向状态机发送了2个消息sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));加载驱动 sendMessage(CMD_START_SUPPLICANT);开启supplicant 它在哪里处理的呢? 状态机构造函数初始化时候,设置有个一个初始状态 &&&&&&& setInitialState(mInitialState); 我们进入mInitialState状态看看 &&&&&&& public void enter() {&&&&&&&&&&& if (WifiNative.isDriverLoaded()) {&&&&&&&&&&&&&&& transitionTo(mDriverLoadedState);&&&&&&&&&&& }&&&&&&&&&&& else {&&&&&&&&&&&&&&& transitionTo(mDriverUnloadedState);&&&&&&&&&&& }因为最开始驱动都是没有加载的,所以进入transitionTo(mDriverUnloadedState); transitionTo函数是状态切换的函数。 继续mDriverUnloadedState &&& class DriverUnloadedState extends State {&&&&&&&& @Override&&&&&&& public boolean processMessage(Message message) {&& &&&&&&&&&&& switch (message.what) {&&&&&&&&&&&&&&& case CMD_LOAD_DRIVER:&&&&&&&&&&&&&&&&&&& mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);&&&&&&&&&&&&&&&&&&& transitionTo(mWaitForP2pDisableState);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& case WifiP2pService.P2P_ENABLE_PENDING:&&&&&&&&&&&&&&&&&&& mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& default:&&&&&&&&&&&&&&&&&&& return NOT_HANDLED;&&&&&&&&&&& }&&&&&&&&&&& EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);&&&&&&&&&&& return HANDLED;&&&&&&& }&&& } 这里会处理刚才的CMD_LOAD_DRIVER这个消息,继续切换到mWaitForP2pDisableState &&& class WaitForP2pDisableState extends State {&&&&&&& @Override&&&&&&& public boolean processMessage(Message message) {&&&&&&&&&&& if (DBG) log(getName() + message.toString() + "n");&&&&&&&&&&& switch(message.what) {&&&&&&&&&&&&&&& case WifiP2pService.WIFI_ENABLE_PROCEED:&&&&&&&&&&&&&&&&&&& //restore argument from original message (CMD_LOAD_DRIVER)&&&&&&&&&&&&&&&&&&& message.arg1 = mSavedA&&&&&&&&&&&&&&&&&&& transitionTo(mDriverLoadingState); &&&&&&&&&&&&&&&&&&& &&& } 状态继续切换到mDriverLoadingState &&& class DriverLoadingState extends State {&&&&&&& @Override&&&&&&& public void enter() {&&&&&&&&&&&& new Thread(new Runnable() {&&&&&&&&&&&&&&& public void run() {&&&&&&&&&&&&&&&&&&& mWakeLock.acquire();&&&&&&&&&&&&&&&&&&& //enabling state&&&&&&&&&&&&&&&&&&& switch(message.arg1) {&&&&&&&&&&&&&&&&&&&&&&& case WIFI_STATE_ENABLING:&&&&&&&&&&&&&&&&&&&&&&&&&&& setWifiState(WIFI_STATE_ENABLING);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& case WIFI_AP_STATE_ENABLING:&&&&&&&&&&&&&&&&&&&&&&&&&&& setWifiApState(WIFI_AP_STATE_ENABLING);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&& if(WifiNative.loadDriver()) {&&&&&&&&&&&&&&&&&&&&&&& if (DBG) log("Driver load successful");&&&&&&&&&&&&&&&&&&&&&&& sendMessage(CMD_LOAD_DRIVER_SUCCESS);&&&&&&&&&&&&&&&&&&& } else {&&&&&&&&&&&&&&&&&&&&&&& loge("Failed to load driver!");&&&&&&&&&&&&&&&&&&&&&&& switch(message.arg1) {&&&&&&&&&&&&&&&&&&&&&&&&&&& case WIFI_STATE_ENABLING:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& setWifiState(WIFI_STATE_UNKNOWN);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& case WIFI_AP_STATE_ENABLING:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& setWifiApState(WIFI_AP_STATE_FAILED);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&&&& sendMessage(CMD_LOAD_DRIVER_FAILURE);&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&& mWakeLock.release();&&&&&&&&&&&&&&& }&&&&&&&&&&& }).start();&&&&&&& }这里回调用WifiNative.loadDriver()加载驱动,成功后发送消息CMD_LOAD_DRIVER_SUCCESS,否则CMD_LOAD_DRIVER_FAILURE,进入JNI static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject){&&& return (jboolean)(::wifi_load_driver() == 0);} 会继续到wifi.c处理 int wifi_load_driver(){#ifdef WIFI_DRIVER_MODULE_PATH&&& char driver_status[PROPERTY_VALUE_MAX];&&& int count = 100;&&& int status = -1;&&& if (is_wifi_driver_loaded()) {&&&&&&& return 0;&&& }&&&&&& if (ensure_wlan_driver_config_file_exists()) {&&&&&&& return -1;&&& }&&& property_set(DRIVER_PROP_NAME, "loading");&&& if(system(SDIO_POLLING_ON))&&&&&&& LOGW("Couldn't turn on SDIO polling: %s", SDIO_POLLING_ON);&&& if ('