赞
踩
设置界面启动wifi
1、wifisettings:设置中wifi主界面对应的代码
2、WifiEnabler:设置中负责wifi开关打开和关闭事件处理的类
--->wifisettings.java 中的onstart函数
此函数创建了WifiEnabler类,实现了wifi的开关功能,
---creatWifiEnabler(),创建WifEnable这个类同时使用了SwitchBarController这个类,目的是为了监听开关的状态,
当开关打开时会调用相应的函数处理
---SwitchBarController这个类,需要关注两个函数startListening和onSwitchChanged,一个是启动SwitchBar的监听,一个监听到有变化之后的调用
当检测到开关打开后,会调用onSwitchToggled函数处理
--->WifiEnabler.java中的wifiEnabler函数
---setupSwitchController()的作用就是把控制变量设置为ture启动SwitchBar的监听。
---onSwitchToggled(boolean isChecked),打开wifi开关,此函数为处理入口
SwitchToggled中会调用WifiManager.setWifiEnabled方法。看到这里其实发现应用层打开和关闭WiFi就是调用了WifiManager的setWifiEabled(boolean)接口
----------------------------------------------------------------------APP层总结------------------------------------------------------------------------------------
wifi的app层作用:创建wifienabler类,监控wifi开关。 监控到wifi开关状态改变,调用framework的wifimanager处理
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
app和framework之间的通信是通过aidl机制,wifiservice和wifimanager之间就是才采用这样的方式
IWifiManager, IWifiManager.Stub, IWifiManager.Stub.Proxy都由IWifiManger.aidl生成
WifiManager:系统为app提供的接口。
Context.getSystemService(Context.WIFI_SERVICE)返回的实际对象类型是IWifiManager.Stub.Proxy,这也就是应用层的对象。
IWifiManager.Stub.Proxy的实例:app端的代理,将WifiManager的方法的参数序列到parcel,经Binder发送给system_server进程
--->WifiServiceImpl中的setWifiEnabled方法。
应用层的wifimanager.stub.proxy对象通过aidl将方法的参数序列发送到wifiservice进程,并调用相应的方法。
WifiServiceImpl中实现WifiService的方法,
setWifiEnabled方法中,打印log->进行wifi打开动作是否允许的判断->向WifiController发消息:CMD_WIFI_TOGGLED.
- "key log setWifiEnabled"
-
- Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid() + ", package=" + packageName);
-
- ...
- mWifiController.sendMessage(CMD_WIFI_TOGGLED);
--->状态机处理消息:CMD_WIFI_TOGGLED
wifisevice处理之后就把任务交给了wifi的状态机进行处理
--->WIFIEnable第一个状态机----------WifiControlle
1、在初始化设置为StaDisabledState状态
2、Enable流程中wifiservice会调用此状态机发送CMD_WIFI_TOGGLED消息\
3、在StaDisabledState处理此消息状态机进入DeviceActiveState
4、在DeviceActiveState的enter函数中调用mWifiStateMachinePrime.enterClientMode()
--->WIFIEnable第二个状态机--------ModeStateMachin
1、初始设置为WiFiDisableState状态
2、在WifiController中由DeviceActiveState的enter函数调用enterClientMode()调用到此状态机
3、在WiFiDisableState状态处理CMD_STAR_CLIENT_MODE消息进入ClientModeActiveState
4、ClientModeActiveState的enter函数工作
--->ClientModeManager.start
-->updateBatteryStatsWifiState
--->WIFIEnable第三个状态机--------ClientModeStateMachine
1、初始状态IdleState
2、由ModeStateMachine状态机的ClientModeActiveState的enter调用
3、IdleState状态处理CMD_START消息,
wifinative.setupInterForClienMode进行驱动装载、使能supplicant、wifimonitor、创建网口等
--->wifinative中的setupInterForClienMode方法
wifi enable 过程wifi状态机的控制到这里基本完成了他的使命,接下里WifiNative中的setupInterForClienMode将调用其他的类来完成接下来的工作
- public String setupInterfaceForClientMode(boolean lowPrioritySta,
- @NonNull InterfaceCallback interfaceCallback) {
- synchronized (mLock) {
- if (!startHal()) {
- Log.e(TAG, "Failed to start Hal");
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
- return null;
- }
- if (!startSupplicant()) {
- Log.e(TAG, "Failed to start supplicant");
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
- return null;
- }
- Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
- if (iface == null) {
- Log.e(TAG, "Failed to allocate new STA iface");
- return null;
- }
- iface.externalListener = interfaceCallback;
- iface.name = createStaIface(iface, lowPrioritySta);
- if (TextUtils.isEmpty(iface.name)) {
- Log.e(TAG, "Failed to create STA iface in vendor HAL");
- mIfaceMgr.removeIface(iface.id);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
- return null;
- }
- if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
- Log.e(TAG, "Failed to setup iface in wificond on " + iface);
- teardownInterface(iface.name);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
- return null;
- }
- if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
- Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
- teardownInterface(iface.name);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
- return null;
- }
- iface.networkObserver = new NetworkObserverInternal(iface.id);
- if (!registerNetworkObserver(iface.networkObserver)) {
- Log.e(TAG, "Failed to register network observer on " + iface);
- teardownInterface(iface.name);
- return null;
- }
- mWifiMonitor.startMonitoring(iface.name);
- // Just to avoid any race conditions with interface state change callbacks,
- // update the interface state before we exit.
- onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
- initializeNwParamsForClientInterface(iface.name);
- Log.i(TAG, "Successfully setup " + iface);
- return iface.name;
- }
- }

关键性的操作:
启动Hal:startHal()
启动supplicant:startSupplicant()
创建网口:setupInterfaceForClientMode()
启动WifiMonitor:WifiMonitor.startMonitoring()
WifiMonitor.startMonitoring():这一步主要是在WifiMonitor中建立与wpa_supplicant通信的socket通道、创建一个线程接收底层事件并分发处理。这里会创建两个socket通道与wpa_s通信,一个用于下发指令,另一个用于接收事件。成功后WifiMonitor会向WifiStateMachine发送一个代表socket通信建立成功的消息:SUP_CONNECTION_EVENT;收到这个消息就表示Wifi已经启动成功了
--->startHal()将启动hal层装载驱动
- "WifiNative code 使用WiFiVendor 方法"
- /** Helper method invoked to start supplicant if there were no ifaces */
- private boolean startHal() {
- synchronized (mLock) {
- if (!mIfaceMgr.hasAnyIface()) {
- if (mWifiVendorHal.isVendorHalSupported()) {
- if (!mWifiVendorHal.startVendorHal()) {
- Log.e(TAG, "Failed to start vendor HAL");
- return false;
- }
- } else {
- Log.i(TAG, "Vendor Hal not supported, ignoring start.");
- }
- }
- return true;
- }
- }

--->wifivendorHal.java
在此文件中的startVendorHal方法中没有没有其他的实质性的操作,也是直接调用的HalDeviceaManager的start方法
- /**
- * Bring up the HIDL Vendor HAL.
- * @return true on success, false otherwise.
- */
- public boolean startVendorHal() {
- synchronized (sLock) {
- if (!mHalDeviceManager.start()) {
- mLog.err("Failed to start vendor HAL").flush();
- return false;
- }
- mLog.info("Vendor Hal started successfully").flush();
- return true;
- }
- }
--->HalDeviceaManager.java
startHal从wifinative到目前这个文件的start方法之前,都没有什么实质性操作,真正有操作的地方从HalDeviceaManager中的start方法开始。
- /**
- * Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or
- * the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
- * success.
- *
- * Note: direct call to HIDL.
- */
- public boolean start() {
- return startWifi();
- }
-
- private boolean startWifi() {
- if (VDBG) Log.d(TAG, "startWifi");
-
- synchronized (mLock) {
- try {
- if (mWifi == null) {
- Log.w(TAG, "startWifi called but mWifi is null!?");
- return false;
- } else {
- int triedCount = 0;
- while (triedCount <= START_HAL_RETRY_TIMES) {
- WifiStatus status = mWifi.start();
- if (status.code == WifiStatusCode.SUCCESS) {
- initIWifiChipDebugListeners();
- managerStatusListenerDispatch();
- if (triedCount != 0) {
- Log.d(TAG, "start IWifi succeeded after trying "
- + triedCount + " times");
- }
- return true;
- } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
- // Should retry. Hal might still be stopping.
- Log.e(TAG, "Cannot start IWifi: " + statusString(status)
- + ", Retrying...");
- try {
- Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
- } catch (InterruptedException ignore) {
- // no-op
- }
- triedCount++;
- } else {
- // Should not retry on other failures.
- Log.e(TAG, "Cannot start IWifi: " + statusString(status));
- return false;
- }
- }
- Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "startWifi exception: " + e);
- return false;
- }
- }
- }

关键点看Iwifi,到这里wif enable的工作framework 已经处理完了,接下来使用hidl通信使打开流程从java走到c++也就是到HAl层
startwifi的功能是状态驱动一直到成功,如果超过规定的时间没有完成,就会返回错误
---------------------------------------------------------------framework总结-----------------------------------------------------------------------------------
framework最关键的点就是wifi状态机了,状态机记录了wifi的各种状态,当wifi的状态改变时,我们就利用状态机来管理,最后一个状态机的改变往往会做真正的工作,向下层传递工作内容。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--->hardware/interfaces/wifi/1.0/IWifi.hal
此文件主要是向framework层提供一些接口
同目录下的Android.bp会在编译中产生一些头文件和源文件
对于C++的Iwifi.hal接口实现的地方,我们需要找到继承了Iwifi.hal里面包含的包和Iwifi.h文件
根据代码查找wifi.cpp是接口实现的文件
--->wifi.cpp start()方法
- Return<void> Wifi::start(start_cb hidl_status_cb) {
- return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
- &Wifi::startInternal, hidl_status_cb);
- }
在此方法中也调用startInternal这个方法
- "key log Wifi HAL started "
-
- WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
- if (wifi_status.code == WifiStatusCode::SUCCESS) {
- // Create the chip instance once the HAL is started.
- chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
- feature_flags_);
- run_state_ = RunState::STARTED;
- for (const auto& callback : event_cb_handler_.getCallbacks()) {
- if (!callback->onStart().isOk()) {
- LOG(ERROR) << "Failed to invoke onStart callback";
- };
- }
- LOG(INFO) << "Wifi HAL started";
startInternal方法主要就是调用 initializeModeControllerAndLegacyHal()进行下一部处理,并对处结构进行反馈。如果驱动已经成功加载,在此答应关键log " wifi HAL started"
initializeModeControllerAndLegacyHal()方法把任务交给了HIDL层C++文件中的wifi_mode_controller.cpp
- WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
- if (!mode_controller_->initialize()) {
- LOG(ERROR) << "Failed to initialize firmware mode controller";
- return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
- }
- legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
- if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- LOG(ERROR) << "Failed to initialize legacy HAL: "
- << legacyErrorToString(legacy_status);
- return createWifiStatusFromLegacyError(legacy_status);
- }
- return createWifiStatus(WifiStatusCode::SUCCESS);
- }
--->wifi_mode_controller.cpp 中的initialize只有一个工作就是调用HAL层装载驱动
- bool WifiModeController::initialize() {
- if (!driver_tool_->LoadDriver()) {
- LOG(ERROR) << "Failed to load WiFi driver";
- return false;
- }
- return true;
- }
--------------------------------------------------------------HIDL总结-------------------------------------------------------------------------------------------
HIDL是为了给framework通信而存在的,C++文件都是上层接口的实现,wifi_mode_controller.cpp会调用更底层的HAl层来实现,可能他就是边缘文件,专门来调用HAl而存在的,因为在这个文件中处除了调用HAL层就没有做其他的事情。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
HAL主要包含3个文件driver_tool .cpp hal_tool.cpp wifi_hal_commom.cppHIdL中实现的接口,最终也要调到HAL层,像装载驱动,需要用到驱动工具driver_tool.cpp的LoadDriver,
- bool DriverTool::LoadDriver() {
- return ::wifi_load_driver() == 0;
- }
此方法的实际调用的wifi_hal_commom.cpp中的wifi_load_driver
- int wifi_load_driver() {
- #ifdef WIFI_DRIVER_MODULE_PATH
- if (is_wifi_driver_loaded()) {
- return 0;
- }
-
- if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
- #endif
-
- #ifdef WIFI_DRIVER_STATE_CTRL_PARAM
- if (is_wifi_driver_loaded()) {
- return 0;
- }
-
- if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1;
- #endif
- property_set(DRIVER_PROP_NAME, "ok");
- return 0;
- }

几经周折终于到了真正装载驱动得代码,在insmod中根据我们定义的驱动实际的路径,执行装载驱动的动作。
---------------------------------------------------------------HAL层总结-----------------------------------------------------------------------------------------
Wifi Enable 工作到了HAl层首先要经过driver_tool .cpp中的LoadDriver方法,但是真正的装载是在wifi_hal_commom.cpp中。可能后者才是真的工作执行的位置,前者是用来工作分类的,所有的驱动类的工作都在driver_tool .cpp文件中,便于更好的管理。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上便是装载wifi驱动的过程,接下来start supplicat -> createStaIface -> startMonitoring 类似装载驱动的流程,完成以上工作wifi 就算完成了打开工作,会广播wifi_state_change_action 这一类的消息,这样系统就知道wiif已经打开,可以进行扫描了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。