//在 SystemServer 启动的时候,启动WifiService调用关系如下:public static void main(String[] args) {        new SystemServer().run();    }private void run() {……startOtherServices();……}startOtherServices(){......               mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);                mSystemServiceManager.startService(WIFI_SERVICE_CLASS);                mSystemServiceManager.startService(                            "com.android.server.wifi.WifiScanningService");                mSystemServiceManager.startService("com.android.server.wifi.RttService");……}

当用户按下 Wifi 按钮后, 在设置里调用 WifiEnabler 的 onSwitchChanged()方法, 在这个方法里又 调用 WifiManager 的 setWifiEnabled 接口函数,通过 AIDL,实际调用的是 WifiService (即WifiServiceImpl)的 setWifiEnabled 函数:

//setWifiEnabled 函数:// WifiServiceImpl.javapublic synchronized boolean setWifiEnabled(boolean enable) {    ……    mWifiController.obtainMessage(CMD_WIFI_TOGGLED, mWifiIpoOff ? 1 : 0)    ……}// WifiController.java//其构造函数如下:WifiController(Context context, WifiServiceImpl service, Looper looper) {        super(TAG, looper);         ……         addState(mDefaultState);            addState(mApStaDisabledState, mDefaultState);            addState(mStaEnabledState, mDefaultState);                addState(mDeviceActiveState, mStaEnabledState);……if (isScanningAlwaysAvailable) {            setInitialState(mStaDisabledWithScanState);        } else {            setInitialState(mApStaDisabledState);        }……}

然后看类:class ApStaDisabledState extends State {
……

public boolean processMessage(Message msg) {            SXlog.d(TAG, getName() + msg.toString() + "\n");            switch (msg.what) {                case CMD_WIFI_TOGGLED:                case CMD_AIRPLANE_TOGGLED:    ……     if (mSettingsStore.isWifiToggleEnabled()) {                        if (doDeferEnable(msg)) {                            if (mHaveDeferredEnable) {                                //  have 2 toggles now, inc serial number an ignore both                                mDeferredEnableSerialNumber++;                            }                            mHaveDeferredEnable = !mHaveDeferredEnable;                            break;                        }                        if (mDeviceIdle == false) {                            transitionTo(mDeviceActiveState);                        } else {                            checkLocksAndTransitionWhenDeviceIdle();                        }                    ///M: check scan always avaliable only when ipo change from ipo on to off or airplane   //mode with no  ipo off                    }    ……class StaEnabledState extends State {        @Override        public void enter() {            if (DBG) log(getName() + "\n");            mWifiStateMachine.setSupplicantRunning(true);        }       ……}class DeviceActiveState extends State {        @Override        public void enter() {            if (DBG) log(getName() + "\n");            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);            mWifiStateMachine.setDriverStart(true);            mWifiStateMachine.setHighPerfModeEnabled(false);        }        ……}// WifiStateMachine.javapublic void setSupplicantRunning(boolean enable) {        if (enable) {            sendMessage(CMD_START_SUPPLICANT);        } else {            sendMessage(CMD_STOP_SUPPLICANT);        }    }public void setDriverStart(boolean enable) {        if (enable) {            sendMessage(CMD_START_DRIVER);        } else {            sendMessage(CMD_STOP_DRIVER);        }    }这样一来又要看WifiStateMachine里的状态InitialStatepublic boolean processMessage(Message message) {            logStateAndMessage(message, getClass().getSimpleName());            switch (message.what) {                case CMD_START_SUPPLICANT:                    if (mWifiNative.loadDriver()) {                        ……                       /* Stop a running supplicant after a runtime restart                        * Avoids issues with drivers that do not handle interface down                        * on a running supplicant properly.                        */                        mWifiMonitor.killSupplicant(mP2pSupported);                        if(mWifiNative.startSupplicant(mP2pSupported)) {                            setWifiState(WIFI_STATE_ENABLING);                            if (DBG) log("Supplicant start successful");                            mWifiMonitor.startMonitoring();                            transitionTo(mSupplicantStartingState);                        } ……}

首先装载 WIFI 内核模块(该模块的位置硬编码为 “/system/lib/modules/wlan.ko” ), 然 后 启 动 wpa_supplicant ( 配 置 文 件 硬 编 码 为 “/data/misc/wifi/wpa_supplicant.conf”) 启动 WifiMonitor 中的监视线程。

当使能成功后,会广播发送 WIFI_STATE_CHANGED_ACTION 这个 Intent 通知外界 WIFI已 经 成 功 使 能 了 。 WifiSettings 创 建 的 时 候 就 会 向 Android 注 册 接 收WIFI_STATE_CHANGED_ACTION,因此它会收到该 Intent,从而开始扫描。          if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,                    WifiManager.WIFI_STATE_UNKNOWN));        } private void updateWifiState(int state) {        Activity activity = getActivity();        if (activity != null) {            activity.invalidateOptionsMenu();        }        switch (state) {            case WifiManager.WIFI_STATE_ENABLED:                mScanner.resume();……void resume() {            if (!hasMessages(0)) {                sendEmptyMessage(0);            }        }public void handleMessage(Message message) {            if (mWifiSettings.mWifiManager.startScan()) {                mRetry = 0;            }……//最后就是往 wpa_supplicant 发送 SCAN 命令.

当 wpa_supplicant 处理完 SCAN 命令后,它会向控制通道发送事件通知扫描完成,从而wifi_wait_for_event 函数会接收到该事件,由此 WifiMonitor 中的 MonitorThread 会被运行,处理事件: void handleEvent(int event, String remainder) { case SCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
最后就是在WifiStateMachine中发送广播:SCAN_RESULTS_AVAILABLE_ACTION.
WifiSettings注册了此广播, 收到后会更新UI显示列表.

更多相关文章

  1. 火爆新东西,仿QQ版本的ResideMenuItem框架(最新QQ版本的)
  2. Android(安卓)Audio代码分析17 - setvolume函数
  3. Android积木之图片的生成和保存
  4. android实现退出时关闭所有activity
  5. Delphi XE5 Android(安卓)调用手机震动
  6. Android(安卓)requestFeature() must be called before adding c
  7. android 调用系统相机程序,存放文件夹创建不了(miui 2.3.9系统)
  8. Android(安卓)System.gc()与Runtime.getRuntime().runFinalizati
  9. 箭头函数的基础使用

随机推荐

  1. Activity的横竖屏切换问题
  2. 第五章 Android加载PDF文件的使用
  3. Android(安卓)MediaScanner:(四)MediaScanne
  4. ArcGIS Android(安卓)10.1.1 API开发资源
  5. 利用FRIDA攻击Android应用程序(三)
  6. [置顶] Android驱动开发-底层驱动开发
  7. 下载和编译Android源码问题集(持续更新)
  8. Android混合开发之------ AndroidStudio
  9. 【项目架构】Android(安卓)MVP 和MVVM框
  10. Android(安卓)SDK Tutorials系列 - Hello