Android(安卓)Wifi框架流程分析
16lz
2022-06-19
//在 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(安卓)Audio代码分析17 - setvolume函数
- Android积木之图片的生成和保存
- android实现退出时关闭所有activity
- Delphi XE5 Android(安卓)调用手机震动
- Android(安卓)requestFeature() must be called before adding c
- android 调用系统相机程序,存放文件夹创建不了(miui 2.3.9系统)
- Android(安卓)System.gc()与Runtime.getRuntime().runFinalizati
- 箭头函数的基础使用