1、AP扫描结果上传setting流程(此处为从上往下调流程)(可参考2、节中的3.节以配合理解分析!)
WifiSettings.java->onWifiStateChanged(int state) updateAccessPointPreferences();(Called when the state of Wifi has changed)
WifiSettings.java->updateAccessPointPreferences <final List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();>
WifiTracker.java->getAccessPoints <return new ArrayList<>(mInternalAccessPoints);>
用到并更新mInternalAccessPoints的地方:
WifiTracker.java->updateAccessPoints <mInternalAccessPoints.addAll(accessPoints);>
调用到updateAccessPoints的地方:
WifiTracker.java->fetchScansAndConfigsAndUpdateAccessPoints <updateAccessPoints(filteredScanResults, configs);>
在执行updateAccessPoints(filteredScanResults, configs);之前进行了如下操作:
WifiTracker.java->fetchScansAndConfigsAndUpdateAccessPoints <List<ScanResult> newScanResults = mWifiManager.getScanResults();>
调用fetchScansAndConfigsAndUpdateAccessPoints的地方:
WifiTracker.java->final BroadcastReceiver mReceiver
WifiTracker.java->newScanResults = mWifiManager.getScanResults();!!!
BaseWifiService.java->getScanResults(...)
WifiServiceImpl.java->getScanResults(...) <mScanRequestProxy.getScanResults()>
ScanRequestProxy.java->getScanResults() <return mLastScanResults;>
(即最终是从ScanRequestProxy.java中获取扫描结果,具体是如何获取的???)
2、AP扫描流程(android P-亮屏setting下-wifi成功开启后,流程基本适用于android Q,每10秒扫描结果上传一次!见本节2.节)
(实抓日志:
12-04 14:48:40.506 862 1409 D WificondControl: get 21 scan results from wificond
12-04 14:48:50.287 862 1409 D WificondControl: get 21 scan results from wificond
)
补充:android P-亮屏setting下-连接已扫描到的热点后,也会继续扫描wifi,即
WifiSettings.java->onSubmit(...)->submit(...)->mWifiTracker.resumeScanning();->mScanner.resume();->...(后续可参考如下
详细流程)
1.WiFi成功开启以后,ClientModeStateMachine由CMD_START转换到StartedState。StartedState 状态机,在更新wifiState时,发送广播
WifiManager.WIFI_STATE_CHANGED_ACTION , 通知WifiTracker开始进行Scan,即:
ClientModeManager.java-> private class StartedState extends State->onUpChanged <updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLED);>
->updateWifiState <final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);>
2.WifiTracker 广播监听到WifiManager.WIFI_STATE_CHANGED_ACTION ,执行updateWifiState
WifiTracker.java->final BroadcastReceiver mReceiver = new BroadcastReceiver() <updateWifiState(...)> -> <mScanner.resume();>
-> <sendEmptyMessage(MSG_SCAN);>
handleMessage(...)->mWifiManager.startScan()
sendEmptyMessageDelayed(MSG_SCAN, WIFI_RESCAN_INTERVAL_MS);(WIFI_RESCAN_INTERVAL_MS=10*1000,即谷歌原生默认在亮屏settings界面下,
扫描周期为10s,此处相当于延时10s,10s之后再将消息发送出去,而后再触发WifiTracker.java->handleMessage(...),执行
mWifiManager.startScan(),如此往复循环而已!)
WifiManager.java startScan(null) <mService.startScan(packageName);>
WifiServiceImpl.java->startScan <mScanRequestProxy.startScan(callingUid, packageName);>
ScanRequestProxy.java->startScan(...) <mWifiScanner.startScan(...);>
WifiScanner.java->startScan(...) <mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);>
WifiScanningServiceImpl.java->class DriverStartedState extends State->processMessage(...) <tryToStartNewScan();
->mScannerImpl.startSingleScan(...)>
WifiScannerImpl.java->public abstract boolean startSingleScan(...) (注意:此类为抽象类)
WificondScannerImpl.java(WificondScannerImpl extends WifiScannerImpl)->startSingleScan mWifiNative.scan(...)
WifiNative.java->scan <mWificondControl.scan(...)>
WificondControl.java->scan <IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);>
<return scannerImpl.scan(settings);>
scanner_impl.cpp->ScannerImpl::scan(...) <scan_utils_->Scan()>
scan_utils.cpp->bool ScanUtils::Scan(...) ->trigger_scan(...,NL80211_CMD_TRIGGER_SCAN,...)
注意:scan_utils (通过netlink,此处不能误解!!!此文件会包含<linux/netlink.h>和"
wificond/net/netlink_manager.h") 将 NL80211_CMD_TRIGGER_SCAN直接传递给内核wlan驱动
(而不是wpa_supplicant!!!此处实现传递的具体流程还需要验证!!!(已验证!))
(具体流程:(/system/connectivity/wificond/scanning/scan_utils.cpp)
NL80211Packet trigger_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_TRIGGER_SCAN,
netlink_manager_->GetSequenceNumber(),
getpid());
...
netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,error_code)
(注意:此处只返回ERROR/ACK,而不是具体的扫描结果!!!)
)
(driver_nl80211_event.c)
(扫描结束后先后上传如下日志:(可参考3.节进行分析!)
wpa_supplicant: nl80211: Drv Event 34 (NL80211_CMD_NEW_SCAN_RESULTS) received for wlan0
(此处34并不表示扫描结果数量)
HAL:event received NL80211_CMD_NEW_SCAN_RESULTS)
3.扫描结果回传(PNO扫描结果的回传流程类似)
wlan driver扫描结束后会发出NL80211_CMD_NEW_SCAN_RESULTS的广播命令(具体广播位置与流程待深究!!!),
此处前面处理分析过程为wificond部分:(wpas部分有待深究?!!)
netlink_manager.cpp->NetlinkManager::BroadcastHandler(...)会对其进行处理:<OnScanResultsReady(std::move(packet));>
netlink_manager.cpp->NetlinkManager::OnScanResultsReady(...) 此处具体下操作三步操作:
<1>向wlan driver发送NL80211_ATTR_SCAN_SSIDS以获取WiFi名称SSID
<GetAttribute(NL80211_ATTR_SCAN_SSIDS, &ssids_attr);ssids_attr.GetListOfAttributeValues(&ssids)>
<2>向wlan driver发送NL80211_ATTR_SCAN_FREQUENCIES以获取该SSID下对应的频率(即对应信道!!!)
<packet->GetAttribute(NL80211_ATTR_SCAN_FREQUENCIES, &freqs_attr);freqs_attr.GetListOfAttributeValues(&freqs)>
(以上两条命令皆是定义在nl80211.h中)
<3>最后将扫描结果通知上层至scanner_impl.cpp(具体如何通知到上层???如何到达scanner_impl.cpp中?)
handler->second(if_index, aborted, ssids, freqs);//Run scan result notification handler.
其后scanner_impl.cpp进行如下操作:std::bind(&ScannerImpl::OnScanResultsReady, this, _1, _2, _3, _4),继而:
scanner_impl.cpp->ScannerImpl::OnScanResultsReady(...)
scan_event_handler_->OnScanResultReady();(此hander即为WificondControl.java中的private class ScanEventHandler
extends IScanEvent.Stub)
WificondControl.java->class ScanEventHandler->OnScanResultReady()->mWifiMonitor.broadcastScanResultEvent(iface, SCAN_RESULTS_EVENT);
注意:WificondControl.OnScanResultReady 上报 WifiMonitor,然后大致的扫描过程如下:
WifiMonitor -> WificondScannerImpl --> WifiScaningServiceImpl->WifiService -->
WifiTracker --> WifiSettings 刷新扫描结果
此处为过程详解:
WifiMonitor.java->broadcastScanResultEvent(String iface) <sendMessage(iface, SCAN_RESULTS_EVENT);>
然后:(WificondScannerImpl的handle收到此事件!)
WificondScannerImpl.java->handleMessage(Message msg) <cancelScanTimeout();>(取消定时器)
<pollLatestScanData();
(通过AIDL从wificond中先获取当前扫描结果,此处获取貌似没有任何意义?!!)
->mNativeScanResults = mWifiNative.getScanResults(mIfaceName);->mWificondControl.getScanResults();->scannerImpl.getScanResults();
(此处WificondControl.getScanResults()中会打印类似“get 16 scan results from wificond”的日志!)
(若mLastScanSettings.singleScanEventHandler不为空,则发送CMD_SCAN_RESULTS_AVAILABLE,何意???)
->mLastScanSettings.singleScanEventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);>
(此WIFI_SCAN_RESULTS_AVAILABLE定义于WifiNative.java->public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
而非nl80211.h中所创建的命令!nl80211.h中的cmd应该是专门发往wlan驱动或驱动发来用的!!!)
然后(上面发送WIFI_SCAN_RESULTS_AVAILABLE):
WifiScanningServiceImpl.java->class WifiSingleScanStateMachine->onScanStatus(...) <sendMessage(CMD_SCAN_RESULTS_AVAILABLE);>
->class WifiSingleScanStateMachine->class ScanningState->processMessage(Message msg) reportScanResults(
mScannerImpl.getLatestSingleScanResults());->entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults);
WifiScanner.java->class ServiceHandler->handleMessage(Message msg) <((ScanListener) listener).onResults(
((ParcelableScanData) msg.obj).getResults());>
public interface ScanListener extends ActionListener->onResults(ScanData[] results);(接口定义)
ScanRequestProxy.java->GlobalScanListener implements WifiScanner.ScanListener->onResults(...)
->mLastScanResults.addAll(Arrays.asList(scanResults));(保存扫描结果,该结果会被上层调用!!!)
->sendScanResultBroadcast(true);-><Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);mContext.
sendBroadcastAsUser(intent, UserHandle.ALL);>(发送广播SCAN_RESULTS_AVAILABLE_ACTION,以提醒上层的WifiTracker
wifi扫描已经完毕,可以获取扫描结果了!对应1、节中的WifiTracker.java->final BroadcastReceiver
mReceiver,即广播接收器)
3、AP扫描流程(android P-非setting界面,亮屏/屏,且有保存网络时-此保存网络是指配置文件是否已有保存的网络)
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java)
WifiConnectivityManager.java->handleScreenStateChanged(boolean screenOn) startConnectivityScan(SCAN_ON_SCHEDULE);
若此时屏幕仍处于亮屏状态:(默认扫描最小间隔min=20s, 最大间隔max=160s,3917已经得到验证!)
->startPeriodicScan(scanImmediately);->startPeriodicSingleScan();->startSingleScan(isFullBandScan, WIFI_WORK_SOURCE);
若此时屏幕处于灭屏状态: (PNO扫描)
->startDisconnectedPnoScan(); (有保存网络-此保存网络是指配置文件是否已有保存的网络,但未连接,则开启PNO扫描,且默认最小
间隔min=20s,最大间隔max=20s*3=60s3917实际验证时并得到效果!!!)
补充:Android Wi-Fi扫描机制(Android P)
Android P的扫描场景可以归结为以下四种:
1.亮屏情况下,在Wifi settings界面,固定扫描,时间间隔为10s
2.亮屏情况下,非Wifi settings界面,二进制指数退避扫描,退避:interval*(2^n), 最小间隔min=20s, 最大间隔max=160s
3.灭屏情况下,有保存网络时,若已连接,不扫描,否则,PNO扫描,即只扫描已保存的网络。最小间隔min=20s,最大间隔max=20s*3=60s
(PNO 即Preferred Network Offload,用于系统在休眠的时候连接WiFi)
4.无保存网络情况下,固定扫描,间隔为5分钟,用于通知用户周围存在可用开放网络。(第四种情况属于Android O的逻辑,因为在P的代码里还
没有找到关于这个扫描的代码,也可能取消了!!!)
4、wifi开启流程(android 9.0 即P)
大致的描述过程如下:
WIfiEnabler->WifiManager->WifiService->WifiServiceImpl->WIfiStateMachinePrime->WIfiStateMachine->WifiNative
此处为详解:
1.在wifisettings activity的onStart函数中,创建一个WifiEnabler对象,用于实现wifi开关功能
WifiSettings.java->onStart() <mWifiEnabler = createWifiEnabler();>
2.WifiEnabler实现了SwitchWidgetController.OnSwitchChangeListener接口,所以重写了onSwitchToggled方法。WifiEnabler开关
onSwitchToggled中会调用WifiManager.setWifiEnabled方法
WifiEnabler.java->onSwitchToggled(boolean isChecked) <mWifiManager.setWifiEnabled(isChecked)>
WifiManager.java->setWifiEnabled(...) <mService.setWifiEnabled(mContext.getOpPackageName(), enabled);>
3.WifiServiceImpl中实现WifiManager的方法,在setWifiEnabled函数中向WifiController发消息:CMD_WIFI_TOGGLED
WifiServiceImpl.java->setWifiEnabled(...) <mWifiController.sendMessage(CMD_WIFI_TOGGLED);>
class StaDisabledState->processMessage(Message msg) <transitionTo(mDeviceActiveState);>
class DeviceActiveState->enter() <mWifiStateMachinePrime.enterClientMode();>
3.执行enterClientMode函数,给ModeStateMachine状态机发送CMD_START_CLIENT_MODE消息
WifiStateMachinePrime.java->enterClientMode() <changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);->mModeStateMachine.sendMessage(newMode);>
class ModeStateMachine->checkForAndHandleModeChange(Message message) <mModeStateMachine.transitionTo(mClientModeActiveState);>
class ClientModeActiveState->enter() <mManager.start();>
ActiveModeManager.java->interface ActiveModeManager <start()> (此处仅是一个接口)
4.ClientModeManager!!!里首先是调用了start函数,发送消息CMD_START给ClientModeStateMachine,消息是IdleState进行处理
ClientModeManager.java->ClientModeManager implements ActiveModeManager->start() mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
class IdleState->processMessage(Message message) <mWifiNative.setupInterfaceForClientMode(...)>
5.setupInterfaceForClientMode的相应处理
WifiNative.java->setupInterfaceForClientMode(...)
<startHal()> (启动HAL,加载wlan.ko,即wlan driver!!!)
mWifiVendorHal.startVendorHal()
WifiVendorHal.java->startVendorHal() <mHalDeviceManager.start()> (该层日志打印标签为WifiVendorHal)
HalDeviceManager.java->start() <startWifi();->WifiStatus status = mWifi.start();> (注:private IWifi mWifi;)
(IWifi即代表IWifi.hal,包含在/hardware/interfaces/wifi目录下,至此通过某种交互方式,如JNI、AIDL或HIDL,进入HAL层。
在编译后会自动产生IWifi.java文件(此处使用AIDL机制生成),之前通过mifi调用的接口都是通过它实现的)
(该层日志打印标签为isHalDevMgr)
(而HAL层的文件,一般放在hardware的wifi_hal目录下,其日志标签为WifiHAL,也算是wifi日志中最底层的信息了!)
(在IWifi.java->getService->asInterface中可找到IWifi对应的服务端为:wifi.cpp 如通常保存路径为:
/hardware/interfaces/wifi/1.3/default/,1.3可视为版本号)
<startSupplicant()> (通过init的.rc或者WPAS的HIDL启动supplicant,最终都是以service形式起来!)
<setupInterfaceForClientMode(iface.name)> (非加载驱动,具体用处待定???)
<mWifiMonitor.startMonitoring(iface.name);> (启动WifiMonitor)
补充:(android Q中5.处处理方法对应:WifiNative.java->setupInterfaceForClientInConnectivityMode(...))
<startHal()> -> mWifiVendorHal.startVendorHal() (此处加载驱动的地方,具体流程如下:!!!详情可见:
https://blog.csdn.net/nilingxi/article/details/103311159)
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java)
<startVendorHal()> -> <mHalDeviceManager.start()>
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java)
<start()> -> <return startWifi();> -> <initIWifiIfNecessary();> -> <mWifi=getWifiServiceMockable();> -> <IWifi.getService(true);>
(注:此处getService就是获取android.hardware.wifi@1.0-service,而
android.hardware.wifi@1.0-service就是我们编译生成的结果,WiFi Service层会通
过这个服务来与我们的WiFi Hal层进行通信!!!)
<mWifi.start()> (下述是紧跟着start走的!)
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java)
<start(...)> -> <Wifi::startInternal> -> <initializeModeControllerAndLegacyHal()> -> <mode_controller_->initialize()>
(/hardware/interfaces/wifi/1.3/default/wifi.cpp)
<initialize()> -> <driver_tool_->LoadDriver()>
(/hardware/interfaces/wifi/1.3/default/wifi_mode_controller.cpp)
<LoadDriver()> -> <wifi_load_driver()>
(/frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp)
<wifi_load_driver()!!!> -> <insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)>
(/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp)
<startSupplicant()> (启动supplicant)
<mWificondControl.setupInterfaceForClientMode(iface.name)> (开启wificond服务,Setup interface for client mode via wificond)
<mSupplicantStaIfaceHal.setupIface(iface.name)> (Setup a STA interface for the specified iface name)
(注:此处interface为何要安装两次???)
<mWifiMonitor.startMonitoring(iface.name)> (启动WifiMonitor)
5、Android P wifi连接流程
1.WifiSettings.java->onSubmit(WifiDialog dialog) <submit(mDialog.getController());->connect(...);->mWifiManager.
connect(config, mConnectListener);>
WifiManager.java->connect(...) <getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
putListener(listener), config);>
WifiServiceImpl.java->class ClientHandler->case WifiManager.CONNECT_NETWORK <mWifiStateMachine.sendMessage
(Message.obtain(msg));>
(注意:android Q中此处不再用WifiStateMachine.java,而是用ClientModeImpl.java!!!,此处可具体情况具体分析)
WifiStateMachine.java->class ConnectModeState->connectToUserSelectNetwork(...) <startConnectToNetwork(...);->
sendMessage(CMD_START_CONNECT, networkId, uid, bssid);>
2.从save network 连接热点又一次转化, 转为CMD_START_CONNECT送到内部状态机(ConnectModeState )处理送到WifiNative 进行处理
Connect
WifiStateMachine.java->class ConnectModeState->processMessage(Message message) <mWifiNative.connectToNetwork(mInterfaceName,
config)>
3.WifiNative –> SupplicantStaIfaceHal -> SupplicantStaNetworkHal -> WifMonitor(关联阶段)
SupplicantStaIfaceHal -> SupplicantStaNetworkHal添加网络,select(实则通过hidl将connect 传给到 wpa_supplicant)
wpa_supplicant完成一系列与路由器的之间的beacon帧(probe、assoc(之前还要完成必要的authentication)、4way-handshake 、
group-handshake)后,再能取到路由器的颁发的认可证(既是拿到最后的compelted)
最后,通过wifiMonitor上报wpa_supplicant 任务已完成,既是完成连接的第一阶段(关联阶段)
WiFiMonitor上报的事件是,NETWORK_CONNECTION_EVENT (又一次回到WifiStateMachine)
4.获取IP阶段
WifMonitor --> WifiStateMachine
WifiStateMachine.java->class ConnectModeState->processMessage(Message message) case WifiMonitor.NETWORK_CONNECTION_EVENT:
sendNetworkStateChangeBroadcast(mLastBssid);transitionTo(mObtainingIpState);
class ObtainingIpState->enter()
setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
clearTargetBssid("ObtainingIpAddress");
stopIpClient();
mIpClient.setHttpProxy(currentConfig.getHttpProxy());
IpClient.buildProvisioningConfiguration();
注:ObtainingIpState 获取IP 的流程中规中矩,先是update 系统的State
停掉IpClient (自从Android N 后,获取IP已废弃了dhcpd,扶持了另一位的IpClient 、IpManager来完成自己的事业 !!!)
清掉bssid以避免其影响到漫游导致断链
Ipclient 开始接管舞台(启动获取IP) (此处dhcp协议,后续学习并更新)
6、wifi关闭流程(android Q-3917)
由前面4、节可知framework层提供的wifi开关接口都是setWifiEnabled,只是参数不同而已。true表示开启wifi、false表示关闭wifi。
WifiEnabler.java->onSwitchToggled(boolean isChecked) -> <mWifiManager.setWifiEnabled(isChecked)>
WifiManager.java->setWifiEnabled(...) <mService.setWifiEnabled(mContext.getOpPackageName(), enabled);>
WifiServiceImpl.java->setWifiEnabled(...) <mWifiController.sendMessage(CMD_WIFI_TOGGLED);>
(wifi开启的时候,WifiController中状态为DeviceActiveState(其父状态为StaEnabledState),故
以下是StaEnabledState对CMD_WIFI_TOGGLED消息的处理)
class StaEnabledState processMessage(...)->CMD_WIFI_TOGGLED:transitionTo(mStaDisabledWithScanState);或transitionTo(mStaDisabledState);
(注:isWifiToggleEnabled为false表示要关闭wifi,则将状态切换到StaDisabledWithScanState(如果可以一直扫描)或
ApStaDisabledState。下面主要看切换到ApStaDisabledState状态的流程操作)
class StaDisabledState enter()->mActiveModeWarden.disableWifi();
ActiveModeWarden.java->changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
class ModeStateMachine checkForAndHandleModeChange(...)->mModeStateMachine.transitionTo(mWifiDisabledState);
class WifiDisabledState enter()->空空如也,有待深究???
7、热点开启流程(到WifiNative层,android Q验证所得结果!)
./packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
->onSwitchToggled mWifiManager.isWifiApEnabled()+startTether();
->startTether mConnectivityManager.startTethering
./frameworks/base/core/java/android/net/ConnectivityManager.java
./frameworks/base/services/core/java/com/android/server/ConnectivityService.java
./frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
./frameworks/base/wifi/java/android/net/wifi/WifiManager.java
./frameworks/base/wifi/java/com/android/server/wifi/BaseWifiService.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeManager.java (interface)
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
./frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
...
注意:具体可参加见log验证结果截图-tetherOpen
SoftApManager.java的处理:
SoftApManager!!!里首先是调用了start函数,发送消息CMD_START给SoftApStateMachine,消息是IdleState进行处理
1、 mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(...),如下:
(android Q中WifiNative处理方法对应:WifiNative.java->setupInterfaceForSoftApMode(...))
<startHal()> -> mWifiVendorHal.startVendorHal() (此处加载驱动的部分基本与本篇.4节中STA模式下开启wifi时所分析的流程一致!)
<startHostapd()> (通过hostapd的HIDL启动Hostapd,最终是以service形式起来!)
<mWificondControl.setupInterfaceForSoftApMode(iface.name)> (开启wificond服务,Setup interface for softAp mode via wificond)
以上完成了加载驱动和通过hostapd安装接口的部分,后续开始按所提供的配置开启AP:
2、result = startSoftAp((WifiConfiguration) message.obj);
<mWifiNative.startSoftAp(mApInterfaceName, localConfig, mSoftApListener)>
注意:Android 基本套路大框架还是不变的: apps – services – native – drv(kernel)!!!(此处不包括services通过wificond与drv交互的情况!)
8、HandlerThread("WifiService")线程的创建与使用(有何用???)
(注:类似这样的线程还有:ClientModeImpl、WifiP2pService,都是在WifiInjector.java中定义!)
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java)
class WifiInjector:
mWifiServiceHandlerThread = new HandlerThread("WifiService");(注:HandlerThread extends Thread !)
mWifiServiceHandlerThread.start(); (启动该线程)
getWifiServiceHandlerThread()->return mWifiServiceHandlerThread;
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java)
public WifiServiceImpl():
HandlerThread wifiServiceHandlerThread = mWifiInjector.getWifiServiceHandlerThread(); (线程实例的创建)
mClientModeImplHandler = new ClientModeImplHandler(TAG, wifiServiceHandlerThread.getLooper(), asyncChannel); (handle实例的创建)
(注:ClientModeImplHandler extends WifiHandler,而HandlerThread extends Thread!在ClientModeImplHandler中
handleMessage(Message msg)一般会被重写!)
9、android wifi信号强度与图标对应关系
android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格.
根据wifimanager中的算法calculateSignalLevel可以算得对应的信号强度:
0 rssi<=-100
1 (-100, -88]
2 (-88, -77]
3 (-66, -55]
4 rssi>=-55
具体可见:https://blog.csdn.net/h784707460/article/details/94581149
10、wifi一般开机注册并开启的三大服务(wifip2p、wifiscanner、wifi)
1.启动流程(以wifi为例,其他两项类似!)
(/frameworks/base/services/java/com/android/server/SystemServer.java)
private static final String WIFI_SERVICE_CLASS="com.android.server.wifi.WifiService";
traceBeginAndSlog("StartWifi");
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
(/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java)
startService(...)-> mServices.add(service);
service.onStart();(继下)
(/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java)
onStart() -> publishBinderService(Context.WIFI_SERVICE, mImpl);
(注:final WifiServiceImpl mImpl; WIFI_SERVICE定义于/frameworks/base/core/java/android/content/Context.java的public
public static final String WIFI_SERVICE = "wifi";类似定义还有WIFI_P2P_SERVICE、WIFI_SCANNING_SERVICE等)