基于原生的Android S代码: http://aospxref.com/android-13.0.0_r3/
上一篇文章我们记录到:
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
在 IdleState 状态里处理 CMD_START 方法
825 private class IdleState extends State {
844 public boolean processMessage(Message message) {
845 switch (message.what) {
846 case CMD_START:
847 // Always start in scan mode first.
848 RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
849 mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode( ---> 继续这个往下看
850 mWifiNativeInterfaceCallback, roleChangeInfo.requestorWs);
851 if (TextUtils.isEmpty(mClientInterfaceName)) {
852 Log.e(getTag(), "Failed to create ClientInterface. Sit in Idle");
853 takeBugReportInterfaceFailureIfNeeded(
854 "Wi-Fi scan STA interface HAL failure");
855 mModeListener.onStartFailure(ConcreteClientModeManager.this);
856 break;
857 }
858 if (roleChangeInfo.role instanceof ClientConnectivityRole) {
859 sendMessage(CMD_SWITCH_TO_CONNECT_MODE, roleChangeInfo);
860 transitionTo(mStartedState);
861 } else {
862 mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
863 transitionTo(mScanOnlyModeState);
864 }
865 break;
}
/packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
1263 public String setupInterfaceForClientInScanMode(
1264 @NonNull InterfaceCallback interfaceCallback, @NonNull WorkSource requestorWs) {
1265 synchronized (mLock) {
1266 if (!startHal()) { ---> 第一点
1267 Log.e(TAG, "Failed to start Hal");
1268 mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
1269 return null;
1270 }
1271 Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
1272 if (iface == null) {
1273 Log.e(TAG, "Failed to allocate new STA iface");
1274 return null;
1275 }
1276 iface.externalListener = interfaceCallback;
1277 iface.name = createStaIface(iface, requestorWs);
1278 if (TextUtils.isEmpty(iface.name)) {
1279 Log.e(TAG, "Failed to create iface in vendor HAL");
1280 mIfaceMgr.removeIface(iface.id);
1281 mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
1282 return null;
1283 }
1284 if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run, ---> 第二点
1285 new NormalScanEventCallback(iface.name),
1286 new PnoScanEventCallback(iface.name))) {
1287 Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
1288 teardownInterface(iface.name);
1289 mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
1290 return null;
1291 }
1292 iface.networkObserver = new NetworkObserverInternal(iface.id);
1293 if (!registerNetworkObserver(iface.networkObserver)) { ---> 第三点
1294 Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
1295 teardownInterface(iface.name);
1296 return null;
1297 }
1298 mWifiMonitor.startMonitoring(iface.name); ---> 第四点比较简单,开始监视传入的iface
1299 // Just to avoid any race conditions with interface state change callbacks,
1300 // update the interface state before we exit.
1301 onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
1302 mWifiVendorHal.enableLinkLayerStats(iface.name);
1303 Log.i(TAG, "Successfully setup " + iface);
1304
1305 iface.featureSet = getSupportedFeatureSetInternal(iface.name);
1306 return iface.name;
1307 }
1308 }
我们现在来细看下,上面标出的几点代码:
第一点:startHal()
492 /** Helper method invoked to start supplicant if there were no ifaces */
493 private boolean startHal() {
494 synchronized (mLock) {
495 if (!mIfaceMgr.hasAnyIface()) { ---> 是否有这个接口
496 if (mWifiVendorHal.isVendorHalSupported()) { ---> 是否支持HAl
497 if (!mWifiVendorHal.startVendorHal()) { ---> 启动 Hal
498 Log.e(TAG, "Failed to start vendor HAL");
499 return false;
500 }
501 if (SdkLevel.isAtLeastS()) { ---> 版本大于S执行
502 mWifiVendorHal.setCoexUnsafeChannels(
503 mCachedCoexUnsafeChannels, mCachedCoexRestrictions);
504 }
505 } else {
506 Log.i(TAG, "Vendor Hal not supported, ignoring start.");
507 }
508 }
509 registerWificondListenerIfNecessary();
510 return true;
511 }
512 }
393 * Bring up the HIDL Vendor HAL.
394 * @return true on success, false otherwise.
395 */
396 public boolean startVendorHal() {
397 synchronized (sLock) {
398 if (!mHalDeviceManager.start()) { ---> 继续追下去
399 mLog.err("Failed to start vendor HAL").flush();
400 return false;
401 }
402 mLog.info("Vendor Hal started successfully").flush();
403 return true;
404 }
405 }
/packages/modules/Wifi/service/java/com/android/server/wifi/HalDeviceManager.java
mHalDeviceManager.start() —> HalDeviceManager. startWifi() 执行:
private boolean startWifi() {
if (VDBG) Log.d(TAG, "startWifi");
initIWifiIfNecessary(); // 初始化 IWifi 接口,如果尚未初始化
synchronized (mLock) {
try {
if (mWifi == null) {
Log.w(TAG, "startWifi called but mWifi is null!?");
return false;
} else { // mWifi 不为空,走下面逻辑
int triedCount = 0;
while (triedCount <= START_HAL_RETRY_TIMES) { //可以尝试 3 次
WifiStatus status = mWifi.start(); // 调用 mWifi 的 start 方法来启动 Wi-Fi HAL
if (status.code == WifiStatusCode.SUCCESS) {
initIWifiChipDebugListeners(); // 初始化 IWifiChip 调试监听器
managerStatusListenerDispatch(); // 触发管理状态监听器
if (triedCount != 0) {
Log.d(TAG, "start IWifi succeeded after trying "
+ triedCount + " times"); // 如果尝试次数不为 0,则打印成功日志
}
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..."); // 如果返回的状态是 ERROR_NOT_AVAILABLE,则说明 HAL 可能仍在停止,打印重试日志
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");
}
} catch (RemoteException e) {
Log.e(TAG, "startWifi exception: " + e);
return false;
}
}
}
继续看下mWifi.start()方法:http://aospxref.com/android-13.0.0_r3/xref/hardware/interfaces/wifi/1.6/default/wifi.cpp#69
Return<void> Wifi::start(start_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal, hidl_status_cb);
}
WifiStatus Wifi::startInternal() {
if (run_state_ == RunState::STARTED) {
return createWifiStatus(WifiStatusCode::SUCCESS);
} else if (run_state_ == RunState::STOPPING) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
}
WifiStatus wifi_status = initializeModeControllerAndLegacyHal(); ---> 看下这个方法
if (wifi_status.code == WifiStatusCode::SUCCESS) {
// Register the callback for subsystem restart
const auto& on_subsystem_restart_callback = [this](const std::string& error) {
WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
LOG(INFO) << "Attempting to invoke onSubsystemRestart "
"callback";
if (!callback->onSubsystemRestart(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
} else {
LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
"callback";
}
}
};
// Create the chip instance once the HAL is started.
android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
for (auto& hal : legacy_hals_) {
chips_.push_back(
new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
feature_flags_, on_subsystem_restart_callback));
chipId++;
}
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";
} else {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onFailure(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onFailure callback";
}
}
LOG(ERROR) << "Wifi HAL start failed";
// Clear the event callback objects since the HAL start failed.
event_cb_handler_.invalidate();
}
return wifi_status;
}
WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
if (!mode_controller_->initialize()) { ---> 这里的mode_controller 指的是WifiModeController,所以到这个类看下初始化方法
LOG(ERROR) << "Failed to initialize firmware mode controller";
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
legacy_hals_ = legacy_hal_factory_->getHals();
if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
int index = 0; // for failure log
for (auto& hal : legacy_hals_) {
legacy_hal::wifi_error legacy_status = hal->initialize();
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
// Currently WifiLegacyHal::initialize does not allocate extra mem,
// only initializes the function table. If this changes, need to
// implement WifiLegacyHal::deinitialize and deinitalize the
// HALs already initialized
LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
<< " error: " << legacyErrorToString(legacy_status);
return createWifiStatusFromLegacyError(legacy_status);
}
index++;
}
return createWifiStatus(WifiStatusCode::SUCCESS);
}
http://aospxref.com/android-13.0.0_r3/xref/hardware/interfaces/wifi/1.6/default/wifi_mode_controller.cpp
bool WifiModeController::initialize() {
if (!driver_tool_->LoadDriver()) { ---> 这个就是我们熟知的去加载驱动操作了
LOG(ERROR) << "Failed to load WiFi driver";
return false;
}
return true;
}
// driver_tool_定义的地方
#include <wifi_hal/driver_tool.h>
std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
全集搜索下,可以发现位置在:
http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/include/wifi_hal/driver_tool.h
再找到对的LoadDriver:http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp#34
bool DriverTool::LoadDriver() {
return ::wifi_load_driver() == 0;
}
http://aospxref.com/android-13.0.0_r3/xref/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp?fi=wifi_load_driver#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) {
#ifdef WIFI_DRIVER_MODULE_PATH
PLOG(WARNING) << "Driver unloading, err='fail to change driver state'";
if (rmmod(DRIVER_MODULE_NAME) == 0) {
PLOG(DEBUG) << "Driver unloaded";
} else {
// Set driver prop to "ok", expect HL to restart Wi-Fi.
PLOG(DEBUG) << "Driver unload failed! set driver prop to 'ok'.";
property_set(DRIVER_PROP_NAME, "ok");
}
#endif
return -1;
}
#endif
is_driver_loaded = true;
return 0;
}
int is_wifi_driver_loaded() {
char driver_status[PROPERTY_VALUE_MAX];
#ifdef WIFI_DRIVER_MODULE_PATH
FILE *proc;
char line[sizeof(DRIVER_MODULE_TAG) + 10];
#endif
if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
return 0; /* driver not loaded */
}
if (!is_driver_loaded) {
return 0;
} /* driver not loaded */
#ifdef WIFI_DRIVER_MODULE_PATH
/*
* If the property says the driver is loaded, check to
* make sure that the property setting isn't just left
* over from a previous manual shutdown or a runtime
* crash.
*/
if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
PLOG(WARNING) << "Could not open " << MODULE_FILE;
is_driver_loaded = false;
if (strcmp(driver_status, "unloaded") != 0) {
property_set(DRIVER_PROP_NAME, "unloaded");
}
return 0;
}
while ((fgets(line, sizeof(line), proc)) != NULL) {
if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
fclose(proc);
return 1;
}
}
fclose(proc);
is_driver_loaded = false;
if (strcmp(driver_status, "unloaded") != 0) {
property_set(DRIVER_PROP_NAME, "unloaded");
}
return 0;
#else
return 1;
#endif
}
第二点:mWifiCondManager.setupInterfaceForClientMode 接口
public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
@NonNull @CallbackExecutor Executor executor,
@NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
Log.d(TAG, "Setting up interface for client mode"); // 设置客户端模式
if (!retrieveWificondAndRegisterForDeath()) {
return false; // 如果无法获取 wificond 并注册死亡监听,则返回失败
}
if (scanCallback == null || pnoScanCallback == null || executor == null) {
Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
return false; // 如果回调为 null,则返回失败
}
IClientInterface clientInterface = null;
try {
clientInterface = mWificond.createClientInterface(ifaceName); // 创建客户端接口,注意这个是IWificond mWificond
} catch (RemoteException e1) {
Log.e(TAG, "Failed to get IClientInterface due to remote exception");
return false; // 如果出现远程异常,则返回失败
}
if (clientInterface == null) {
Log.e(TAG, "Could not get IClientInterface instance from wificond");
return false; // 如果获取到的客户端接口为 null,则返回失败
}
Binder.allowBlocking(clientInterface.asBinder()); // 允许阻塞调用客户端接口的方法
// Refresh Handlers
mClientInterfaces.put(ifaceName, clientInterface); // 将客户端接口添加到接口列表中
try {
IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); // 获取 WifiScannerImpl
if (wificondScanner == null) {
Log.e(TAG, "Failed to get WificondScannerImpl");
return false; // 如果获取到的 WifiScannerImpl 为 null,则返回失败
}
mWificondScanners.put(ifaceName, wificondScanner); // 将 WifiScannerImpl 添加到扫描器列表中
Binder.allowBlocking(wificondScanner.asBinder()); // 允许阻塞调用 WifiScannerImpl 的方法
ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); // 创建扫描事件处理程序
mScanEventHandlers.put(ifaceName, scanEventHandler); // 将扫描事件处理程序添加到处理程序列表中
wificondScanner.subscribeScanEvents(scanEventHandler); // 订阅扫描事件
PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
pnoScanCallback); // 创建 PNO 扫描事件处理程序
mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); // 将 PNO 扫描事件处理程序添加到处理程序列表中
wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); // 订阅 PNO 扫描事件
} catch (RemoteException e) {
Log.e(TAG, "Failed to refresh wificond scanner due to remote exception");
}
return true; // 返回成功
}
第三点:registerNetworkObserver(iface.networkObserver)
private boolean registerNetworkObserver(NetworkObserverInternal observer) {
if (observer == null) return false; // 如果观察者为 null,则返回失败
mNetdWrapper.registerObserver(observer); // 注册网络观察者,mNetdWrapper是网络服务的封装类
return true;
}
上面我们已经大致看完了,总结下:
- 启动HAl层,然后去加载驱动
- 通过和/system/connectivity/wificond/里面的Service建立关系,为了后续扫描作准备
- 注册网络观察者
小伙伴有没有疑惑?为啥没有启动wpa_supplicant呢,这个可以负责整个Wi-Fi连接、认证、加密等等重要的步骤,说到这,我们就要知道自从Android P开始,扫描这块就逐渐的从wpa_supplicant中给剥离了,由 IWificond 去负责,所以我们在WifiNative.setupInterfaceForClientInScanMode模式中并没有看到这个初始化步骤,那我们既然是梳理打开Wi-Fi的流程,怎么可能只是ClientScanMode模式呢,肯定是要切换到连接的mode。再回到当初最开始ConcreteClientModeManager类中,StartedState状态处理CMD_SWITCH_TO_CONNECT_MODE消息的时候,没有印象的看我之前记录的这篇:Android S Wi-Fi 打开流程(一)
其中有这样一句代码:mWifiNative.switchClientInterfaceToConnectivityMode
http://aospxref.com/android-13.0.0_r3/xref/packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java#1436
public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName, @NonNull WorkSource requestorWs) {
synchronized (mLock) {
final Iface iface = mIfaceMgr.getIface(ifaceName);
if (iface == null) {
Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface=" + ifaceName);
return false;
}
//应为此时setupInterfaceForClientInScanMode所分配的iface.type是IFACE_TYPE_STA_FOR_SCAN
//并不是IFACE_TYPE_STA_FOR_CONNECTIVITY,所以这个if不满足
if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
return true;
}
//至此,上面setupInterfaceForClientInScanMode都初始化过了
if (mWifiVendorHal.isVendorHalSupported()
&& !mWifiVendorHal.replaceStaIfaceRequestorWs(iface.name, requestorWs)) {
Log.e(TAG, "Failed to replace requestor ws on " + iface);
teardownInterface(iface.name);
return false;
}
//判断wpa_supplicant是否启动,没有则初始化
if (!startSupplicant()) {
Log.e(TAG, "Failed to start supplicant");
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
return false;
}
//设置接口名和名称对应
if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
return false;
}
if (mContext.getResources().getBoolean( R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)) {
if (!mSupplicantStaIfaceHal.setNetworkCentricQosPolicyFeatureEnabled(iface.name, true)) {
Log.e(TAG, "Failed to set QoS policy feature enabled for iface " + iface.name);
return false;
}
}
iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
//获取支持的能力,比如加密方式、新特性等等
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
saveCompleteFeatureSetInConfigStoreIfNecessary(iface.featureSet);
mIsEnhancedOpenSupported = (iface.featureSet & WIFI_FEATURE_OWE) != 0;
Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
return true;
}
}
现在我们就知道了,原来在这里将启动wpa_supplicant,至此,整个Wi-Fi打开的大致流程就到此梳理完毕,细节的多看下代码即可。