Android Wifi框架流程分析
16lz
2021-01-23
//在 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显示列表.
更多相关文章
- 火爆新东西,仿QQ版本的ResideMenuItem框架(最新QQ版本的)
- 每天学习一个Android中的常用框架——0.目录
- 【Android-Third】Android三方框架相关
- (Android下使用)Google Test C++单元测试框架(二)
- Android Activity的onCreate()函数
- recovery代码流程
- Android5.0以太网流程源码情景分析
- Android RectF类的构造函数参数说明