Wifi笔记 | Android P 启动流程之startHal
2020-01-12 本文已影响0人
力卉编程
android O wifi启动流程主要包括驱动的加载,supplicant的启动,以及supplicant的连接(hidl),之前也看过Android 4.4的WiFi启动流程,前面提及的几个主要部分功能实现还是差不多的,Android O主要引入了Wificond和hidl。
一、WIFI启动总体总体流程
![](https://img.haomeiwen.com/i19137640/a489c099cbdecc79.png)
二、WIFI启动消息图
![](https://img.haomeiwen.com/i19137640/e04372052e0686d9.jpg)
三、代码流程
3.1 WifiManager
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
3.2 WifiSerivceImpl
public synchronized boolean setWifiEnabled(String packageName, boolean enable)
throws RemoteException {
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid() + ", package=" + packageName);
mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
.c(Binder.getCallingUid()).c(enable).flush();
boolean isFromSettings = checkNetworkSettingsPermission(
Binder.getCallingPid(), Binder.getCallingUid());
// If Airplane mode is enabled, only Settings is allowed to toggle Wifi
if (mSettingsStore.isAirplaneModeOn() && !isFromSettings) {
mLog.info("setWifiEnabled in Airplane mode: only Settings can enable wifi").flush();
return false;
}
// If SoftAp is enabled, only Settings is allowed to toggle wifi
boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
if (apEnabled && !isFromSettings) {
mLog.info("setWifiEnabled SoftAp not disabled: only Settings can enable wifi").flush();
return false;
}
/*
* Caller might not have WRITE_SECURE_SETTINGS,
* only CHANGE_WIFI_STATE is enforced
*/
long ident = Binder.clearCallingIdentity();
try {
if (! mSettingsStore.handleWifiToggled(enable)) {
// Nothing to do if wifi cannot be toggled
return true;
}
} finally {
Binder.restoreCallingIdentity(ident);
}
if (mPermissionReviewRequired) {
final int wiFiEnabledState = getWifiEnabledState();
if (enable) {
if (wiFiEnabledState == WifiManager.WIFI_STATE_DISABLING
|| wiFiEnabledState == WifiManager.WIFI_STATE_DISABLED) {
if (startConsentUi(packageName, Binder.getCallingUid(),
WifiManager.ACTION_REQUEST_ENABLE)) {
return true;
}
}
} else if (wiFiEnabledState == WifiManager.WIFI_STATE_ENABLING
|| wiFiEnabledState == WifiManager.WIFI_STATE_ENABLED) {
if (startConsentUi(packageName, Binder.getCallingUid(),
WifiManager.ACTION_REQUEST_DISABLE)) {
return true;
}
}
}
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
return true;
}
3.3 WifiController
对比Android O的WifiController简略了很多
- ap相关(softap)剥离了,
- StaEnabledState和DeviceActiveState其实是一个了,合成一个。
// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
addState(mStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
addState(mDeviceActiveState, mStaEnabledState);
addState(mStaDisabledWithScanState, mDefaultState);
addState(mEcmState, mDefaultState);
// CHECKSTYLE:ON IndentationCheck
看下ModeStateMachine的模式
// Commands for the state machine - these will be removed,
// along with the StateMachine itself
public static final int CMD_START_CLIENT_MODE = 0;
public static final int CMD_START_SCAN_ONLY_MODE = 1;
public static final int CMD_DISABLE_WIFI = 3;
有3个模式
- ClientMode模式,应该就是WiFi普通打开模式,
- Scan_ONLY应该就是不打开WiFi只打开WiFi扫描的模式,
- Disable_WIFI应该是上面两个都没打开的情况。
3.4 ClientModeManager 合并了SoftAp功能,这是Android P的新的改变
这里从api注释来看解耦出来了一个接口,用于Client, ScanOnly and SoftAp的实现。
/** Manager WiFi in Client Mode where we connect to configured networks. */
public class ClientModeManager implements ActiveModeManager {
/**
* Base class for available WiFi operating modes.
*
* Currently supported modes include Client, ScanOnly and SoftAp.
*/
public interface ActiveModeManager {
String TAG = "ActiveModeManager";
/**
* Method used to start the Manager for a given Wifi operational mode.
*/
void start();
/**
* Method used to stop the Manager for a give Wifi operational mode.
*/
void stop();
/**
* Method to dump for logging state.
*/
void dump(FileDescriptor fd, PrintWriter pw, String[] args);
/**
* Method that allows Mode Managers to update WifiScanner about the current state.
*
* @param context Context to use for the notification
* @param available boolean indicating if scanning is available
*/
default void sendScanAvailableBroadcast(Context context, boolean available) {
Log.d(TAG, "sending scan available broadcast: " + available);
final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
if (available) {
intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_ENABLED);
} else {
intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
}
context.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
}
3.5 WifiNative
WifiNative 主要工作:
- startHal
- startSupplicant
- createStaIface
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;
}
}
3.5.1 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;
}
}
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;
}
}
//HalDeviceManager
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;
}
}
}
最重要的一句:WifiStatus status = mWifi.start();
3.5.2 WIFI连接驱动硬件
最后一句:driver_tool_->LoadDriver()
//hardware/interfaces/wifi/1.0/default/wifi.cpp
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) {
// 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";
} 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";
}
return wifi_status;
}
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);
}
///hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp
bool WifiModeController::initialize() {
if (!driver_tool_->LoadDriver()) {
LOG(ERROR) << "Failed to load WiFi driver";
return false;
}
return true;
}
3.5.3 驱动硬件
/hardware/interfaces/wifi/1.2/default/wifi_legacy_hal.cpp
wifi_error WifiLegacyHal::initialize() {
LOG(DEBUG) << "Initialize legacy HAL";
// TODO: Add back the HAL Tool if we need to. All we need from the HAL tool
// for now is this function call which we can directly call.
if (!initHalFuncTableWithStubs(&global_func_table_)) {
LOG(ERROR)
<< "Failed to initialize legacy hal function table with stubs";
return WIFI_ERROR_UNKNOWN;
}
wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
if (status != WIFI_SUCCESS) {
LOG(ERROR) << "Failed to initialize legacy hal function table";
}
return status;
}
到这边startHal就走完了。