Android Q WIFI开启流程
一、点击wifi开关 默认有2种方式打开wifi 1)从设置打开 \packages\apps\Settings\src\com\android\settings\wifi\WifiEnabler.java 调用了WifiManager的setWifiEnabled
@Override
public boolean onSwitchToggled(boolean isChecked) {
if (mStateMachineEvent) {
return true;
}
if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {
Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
mSwitchWidget.setChecked(false);
return false;
}
if (isChecked) {
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_ON);
} else {
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_OFF,
mConnected.get());
}
if (!mWifiManager.setWifiEnabled(isChecked)) {
mSwitchWidget.setEnabled(true);
Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
}
return true;
}
2)从状态栏点击打开 \frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\WifiTile.java mController.setWifiEnabled
@Override
protected void handleClick() {
mState.copyTo(mStateBeforeClick);
boolean wifiEnabled = mState.value;
refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
mController.setWifiEnabled(!wifiEnabled);
mExpectDisabled = wifiEnabled;
if (mExpectDisabled) {
mHandler.postDelayed(() -> {
if (mExpectDisabled) {
mExpectDisabled = false;
refreshState();
}
}, QSIconViewImpl.QS_ANIM_LENGTH);
}
}
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\NetworkControllerImpl.java 调用了WifiManager的setWifiEnabled
@Override
public void setWifiEnabled(final boolean enabled) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... args) {
mWifiManager.setWifiEnabled(enabled);
return null;
}
}.execute();
}
两种方法最后都是调用的WifiManager.setWifiEnabled方法
二、AndroidQ 默认加入了支持双WiFi的代码。这里打开WiFi就提供了俩个接口 frameworks/base/wifi/java/android/net/wifi/WifiManager.java 正常打开WiFi是调用这个单参的函数。
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
在service中调用setWifiEnabled 会默认传入 staId为STA_PRIMARY来调用setWifiEnabled2方法 这个方法是用来指定staId的 frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
@Override
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
return setWifiEnabled2(packageName, STA_PRIMARY, enable);
}
@Override
public synchronized boolean setWifiEnabled2(String packageName, int staId,boolean enable) {
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid(), packageName)
&& !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
Binder.getCallingUid())
&& !isSystem(packageName, Binder.getCallingUid())) {
mLog.info("setWifiEnabled not allowed for uid=%")
.c(Binder.getCallingUid()).flush();
return false;
}
if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();
return false;
}
if (!isPrivileged && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();
return false;
}
mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
.c(Binder.getCallingUid()).c(enable).flush();
long ident = Binder.clearCallingIdentity();
try {
if (staId == STA_PRIMARY && !mSettingsStore.handleWifiToggled(enable)) {
return true;
}
} finally {
Binder.restoreCallingIdentity(ident);
}
if (mWifiPermissionsUtil.checkNetworkSettingsPermission(Binder.getCallingUid())) {
if (enable) {
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
} else {
WifiInfo wifiInfo = mClientModeImpl.syncRequestConnectionInfo();
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_OFF,
wifiInfo == null ? -1 : wifiInfo.getNetworkId());
}
}
if (!mIsControllerStarted) {
Log.e(TAG,"WifiController is not yet started, abort setWifiEnabled");
return false;
}
mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
if(staId == STA_PRIMARY)
mActiveModeWarden.wifiToggled();
else if(staId == STA_SECONDARY && (getNumConcurrentStaSupported() > 1) && (getWifiEnabledState() == WifiManager.WIFI_STATE_ENABLED))
mActiveModeWarden.qtiWifiToggled(staId, enable);
else
Log.e(TAG,"setWifiEnabled not allowed for Id: " + staId);
return true;
}
三、看到SetWifiEnabled2方法中调用了mActiveModeWarden.wifiToggled(); \frameworks\opt\net\wifi\service\java\com\android\server\wifi\ActiveModeWarden.java
public void wifiToggled() {
mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED);
}
发送了CMD_WIFI_TOGGLED消息通知状态改变
四、WifiController处理消息 WifiController是ActiveModeWarden.java中的一个内部类是一个状态机 因为是开启流程 所以目前默认状态是DisabledState
@Override
public boolean processMessageFiltered(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
case CMD_SCAN_ALWAYS_MODE_CHANGED:
if (shouldEnableSta()) {
startClientModeManager();
transitionTo(mEnabledState);
}
break;
}
}
调用了startClientModeManager()方法 来启动一个新的客户端管理。
private boolean startClientModeManager() {
Log.d(TAG, "Starting ClientModeManager");
ClientListener listener = new ClientListener();
ClientModeManager manager = mWifiInjector.makeClientModeManager(listener);
listener.setActiveModeManager(manager);
manager.start();
if (!switchClientModeManagerRole(manager)) {
manager.stop();
return false;
}
mActiveModeManagers.add(manager);
return true;
}
五、ClientModeManager.start() \frameworks\opt\net\wifi\service\java\com\android\server\wifi\ClientModeManager.java
@Override
public void start() {
Log.d(TAG, "Starting with role ROLE_CLIENT_SCAN_ONLY");
mRole = ROLE_CLIENT_SCAN_ONLY;
mTargetRole = ROLE_CLIENT_SCAN_ONLY;
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
}
start()方法发送了CMD_START 这个消息 ClientModeStateMachine是一个状态机 因为第一次打开WIFI所以默认是IdleState
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_START:
mClientInterfaceName =
mWifiNative.setupInterfaceForClientInScanMode(
mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
mModeListener.onStartFailure();
break;
}
transitionTo(mScanOnlyModeState);
break;
default:
Log.d(TAG, "received an invalid message: " + message);
return NOT_HANDLED;
}
return HANDLED;
}
六、mWifiNative.setupInterfaceForClientInScanMode() \frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiNative.java
public String setupInterfaceForClientInScanMode(
@NonNull InterfaceCallback interfaceCallback) {
synchronized (mLock) {
if (!startHal()) {
Log.e(TAG, "Failed to start Hal");
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
if (iface == null) {
Log.e(TAG, "Failed to allocate new STA iface");
return null;
}
iface.externalListener = interfaceCallback;
iface.name = createStaIface(iface);
if (TextUtils.isEmpty(iface.name)) {
Log.e(TAG, "Failed to create iface in vendor HAL");
mIfaceMgr.removeIface(iface.id);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,
new NormalScanEventCallback(iface.name),
new PnoScanEventCallback(iface.name))) {
Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
return null;
}
iface.networkObserver = new NetworkObserverInternal(iface.id);
if (!registerNetworkObserver(iface.networkObserver)) {
Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
teardownInterface(iface.name);
return null;
}
mWifiMonitor.startMonitoring(iface.name);
onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
Log.i(TAG, "Successfully setup " + iface);
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
return iface.name;
}
}
1)WifiNative 这里首先去打开HAL
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;
}
}
mWifiVendorHal.startVendorHal() \frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiVendorHal.java
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;
}
}
mHalDeviceManager.start() \frameworks\opt\net\wifi\service\java\com\android\server\wifi\HalDeviceManager.java
public boolean start() {
return startWifi();
}
private boolean startWifi() {
if (VDBG) Log.d(TAG, "startWifi");
initIWifiIfNecessary();
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) {
Log.e(TAG, "Cannot start IWifi: " + statusString(status)
+ ", Retrying...");
try {
Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
} catch (InterruptedException ignore) {
}
triedCount++;
} else {
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;
}
}
}
mWifi.start()方法是启动实际加载WiFi动作的调用,这里涉及HIDL机制调用。通过获取IWifi接口对象,调用其方法。这里IWifi接口对象是IWifi.hal文件中实现。
hardware\interfaces\wifi\1.0\IWifi.hal 通过编译生成对应的java文件生成在
out\soong\.intermediates\hardware\interfaces\wifi\1.0\android.hardware.wifi-V1.0-java_gen_java\gen\srcs\android\hardware\wifi\V1_0\IWifi.java
@Override
public android.hardware.wifi.V1_0.WifiStatus start()
throws android.os.RemoteException {
android.os.HwParcel _hidl_request = new android.os.HwParcel();
_hidl_request.writeInterfaceToken(android.hardware.wifi.V1_0.IWifi.kInterfaceName);
android.os.HwParcel _hidl_reply = new android.os.HwParcel();
try {
mRemote.transact(3 , _hidl_request, _hidl_reply, 0 );
_hidl_reply.verifySuccess();
_hidl_request.releaseTemporaryStorage();
android.hardware.wifi.V1_0.WifiStatus _hidl_out_status = new android.hardware.wifi.V1_0.WifiStatus();
((android.hardware.wifi.V1_0.WifiStatus) _hidl_out_status).readFromParcel(_hidl_reply);
return _hidl_out_status;
} finally {
_hidl_reply.release();
}
}
通过binder调用到wifi.cpp的start方法 hardware\interfaces\wifi\1.4\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) {
chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
iface_util_, 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";
event_cb_handler_.invalidate();
}
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);
}
mode_controller_->initialize() hardware\interfaces\wifi\1.4\default\wifi_mode_controller.cpp
bool WifiModeController::deinitialize() {
if (!driver_tool_->UnloadDriver()) {
LOG(ERROR) << "Failed to unload WiFi driver";
return false;
}
return true;
}
driver_tool_->UnloadDriver() frameworks\opt\net\wifi\libwifi_hal\driver_tool.cpp
bool DriverTool::UnloadDriver() {
return ::wifi_unload_driver() == 0;
}
frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cpp
int wifi_unload_driver() {
if (!is_wifi_driver_loaded()) {
return 0;
}
#ifdef WIFI_DRIVER_MODULE_PATH
if (rmmod(DRIVER_MODULE_NAME) == 0) {
int count = 20;
while (count-- > 0) {
if (!is_wifi_driver_loaded()) break;
usleep(500000);
}
usleep(500000);
if (count) {
return 0;
}
return -1;
} else
return -1;
#else
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
if (is_wifi_driver_loaded()) {
if (wifi_change_driver_state(WIFI_DRIVER_STATE_OFF) < 0) return -1;
}
#endif
is_driver_loaded = false;
property_set(DRIVER_PROP_NAME, "unloaded");
return 0;
#endif
}
到此startHal() 调用结束
2)mWifiCondManager.setupInterfaceForClientMode frameworks\base\wifi\java\android\net\wifi\nl80211\WifiNl80211Manager.java
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;
}
if (scanCallback == null || pnoScanCallback == null || executor == null) {
Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
return false;
}
IClientInterface clientInterface = null;
try {
clientInterface = mWificond.createClientInterface(ifaceName);
} 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;
}
Binder.allowBlocking(clientInterface.asBinder());
mClientInterfaces.put(ifaceName, clientInterface);
try {
IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl();
if (wificondScanner == null) {
Log.e(TAG, "Failed to get WificondScannerImpl");
return false;
}
mWificondScanners.put(ifaceName, wificondScanner);
Binder.allowBlocking(wificondScanner.asBinder());
ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback);
mScanEventHandlers.put(ifaceName, scanEventHandler);
wificondScanner.subscribeScanEvents(scanEventHandler);
PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
pnoScanCallback);
mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler);
wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
} catch (RemoteException e) {
Log.e(TAG, "Failed to refresh wificond scanner due to remote exception");
}
return true;
}
这个方法主要作用是为了底层添加了一下接口.createClientInterface
七、之后回到了IdelState 继续执行transitionTo(mScanOnlyModeState); 这个作用是将状态机的状态置成ScanOnlyModeState
状态机初始化状态如下
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
addState(mIdleState);
addState(mStartedState, mIdleState);
addState(mScanOnlyModeState, mStartedState);
addState(mConnectModeState, mStartedState);
setInitialState(mIdleState);
start();
}
所以状态机会按照下面的方法执行
IdleState.exit()->StartedState.enter()->StartedState.exit()->ScanOnlyModeState.enter()
这个之后回到了第四步 start()之后 继续执行switchClientModeManagerRole()
private boolean switchClientModeManagerRole(@NonNull ClientModeManager modeManager) {
if (mSettingsStore.isWifiToggleEnabled()) {
modeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY);
} else if (checkScanOnlyModeAvailable()) {
modeManager.setRole(ActiveModeManager.ROLE_CLIENT_SCAN_ONLY);
} else {
Log.e(TAG, "Something is wrong, no client mode toggles enabled");
return false;
}
return true;
}
查看isWifiToggleEnabled frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiSettingsStore.java
public synchronized boolean isWifiToggleEnabled() {
if (mAirplaneModeOn) {
return mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE;
} else {
return mPersistWifiState != WIFI_DISABLED;
}
}
在setWifiEnabled2的时候会调用handleWifiToggled
public synchronized boolean handleWifiToggled(boolean wifiEnabled) {
if (mAirplaneModeOn && !isAirplaneToggleable()) {
return false;
}
if (wifiEnabled) {
if (mAirplaneModeOn) {
persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
persistWifiState(WIFI_ENABLED);
}
} else {
persistWifiState(WIFI_DISABLED);
}
return true;
}
private void persistWifiState(int state) {
final ContentResolver cr = mContext.getContentResolver();
mPersistWifiState = state;
Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state);
}
所以isWifiToggleEnabled这个方法在此返回了ture
因此执行modeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY);
@Override
public void setRole(@Role int role) {
Preconditions.checkState(CLIENT_ROLES.contains(role));
if (role == ROLE_CLIENT_SCAN_ONLY) {
mTargetRole = role;
mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_SCAN_ONLY_MODE);
} else if (CLIENT_CONNECTIVITY_ROLES.contains(role)) {
mTargetRole = role;
mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE, role);
}
}
List<Integer> CLIENT_CONNECTIVITY_ROLES = Arrays.asList(
ROLE_CLIENT_PRIMARY,
ROLE_CLIENT_SECONDARY,
ROLE_CLIENT_LOCAL_ONLY);
ROLE_CLIENT_PRIMARY包含在CLIENT_CONNECTIVITY_ROLES 数组中
所以会执行 mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE, role);
查看发现有 StartedState 和ConnectModeState状态处理 CMD_SWITCH_TO_CONNECT_MODE消息 但是现在还没有到ConnectModeState状态所以会由StartedState 处理
@Override
public boolean processMessage(Message message) {
switch(message.what) {
case CMD_START:
break;
case CMD_SWITCH_TO_CONNECT_MODE:
mRole = message.arg1;
updateConnectModeState(WifiManager.WIFI_STATE_ENABLING,
WifiManager.WIFI_STATE_DISABLED);
if (!mWifiNative.switchClientInterfaceToConnectivityMode(
mClientInterfaceName)) {
updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLING);
updateConnectModeState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_UNKNOWN);
mModeListener.onStartFailure();
break;
}
transitionTo(mConnectModeState);
break;
}
}
mWifiNative.switchClientInterfaceToConnectivityMode
public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName) {
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;
}
if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
return true;
}
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;
}
iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
return true;
}
}
启动了startSupplicant
private boolean startSupplicant() {
synchronized (mLock) {
if (!mIfaceMgr.hasAnyStaIfaceForConnectivity()) {
if (!startAndWaitForSupplicantConnection()) {
Log.e(TAG, "Failed to connect to supplicant");
return false;
}
if (!mSupplicantStaIfaceHal.registerDeathHandler(
new SupplicantDeathHandlerInternal())) {
Log.e(TAG, "Failed to register supplicant death handler");
return false;
}
}
return true;
}
}
private boolean startAndWaitForSupplicantConnection() {
if (!mSupplicantStaIfaceHal.isInitializationStarted()
&& !mSupplicantStaIfaceHal.initialize()) {
return false;
}
if (!mSupplicantStaIfaceHal.startDaemon()) {
Log.e(TAG, "Failed to startup supplicant");
return false;
}
boolean connected = false;
int connectTries = 0;
while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
connected = mSupplicantStaIfaceHal.isInitializationComplete();
if (connected) {
break;
}
try {
Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
} catch (InterruptedException ignore) {
}
}
return connected;
}
mSupplicantStaIfaceHal.startDaemon() frameworks\opt\net\wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHal.java
public boolean startDaemon() {
synchronized (mLock) {
if (isV1_1()) {
Log.i(TAG, "Starting supplicant using HIDL");
return startDaemon_V1_1();
} else {
Log.i(TAG, "Starting supplicant using init");
mFrameworkFacade.startSupplicant();
return true;
}
}
}
private boolean startDaemon_V1_1() {
synchronized (mLock) {
try {
getSupplicantMockableV1_1();
} catch (RemoteException e) {
Log.e(TAG, "Exception while trying to start supplicant: "
+ e);
supplicantServiceDiedHandler(mDeathRecipientCookie);
return false;
} catch (NoSuchElementException e) {
Log.d(TAG, "Successfully triggered start of supplicant using HIDL");
}
return true;
}
}
protected android.hardware.wifi.supplicant.V1_1.ISupplicant getSupplicantMockableV1_1()
throws RemoteException, NoSuchElementException {
synchronized (mLock) {
android.hardware.wifi.supplicant.V1_1.ISupplicant iSupplicantDerived =
android.hardware.wifi.supplicant.V1_1.ISupplicant.castFrom(
getSupplicantMockable());
if (iSupplicantDerived == null) {
throw new NoSuchElementException("Cannot cast to V1.1 service.");
}
return iSupplicantDerived;
}
}
protected ISupplicant getSupplicantMockable() throws RemoteException, NoSuchElementException {
synchronized (mLock) {
ISupplicant iSupplicant = ISupplicant.getService();
if (iSupplicant == null) {
throw new NoSuchElementException("Cannot get root service.");
}
return iSupplicant;
}
}
ISupplicant.getService(); 这个也是通过HIDL实现
out\soong\.intermediates\hardware\interfaces\wifi\supplicant\1.0\android.hardware.wifi.supplicant-V1.0-java_gen_java\gen\srcs\android\hardware\wifi\supplicant\V1_0\ISupplicant.java
public static ISupplicant getService() throws android.os.RemoteException {
return getService("default");
}
public static ISupplicant getService(String serviceName) throws android.os.RemoteException {
return ISupplicant.asInterface(android.os.HwBinder.getService("android.hardware.wifi.supplicant@1.0::ISupplicant", serviceName));
}
八、 在这个方法中将触发启动wpa_supplicant进程,这里需要注意,在manifest.xml中对其需要进行配置,运行时会将服务名称注册到hwservicemanager中。
wpa_supplicant目录下文件调用:
external\wpa_supplicant_8\wpa_supplicant\main.c
external\wpa_supplicant_8\wpa_supplicant\wpa_supplicant.c
external\wpa_supplicant_8\wpa_supplicant\notify.c
external\wpa_supplicant_8\wpa_supplicant\hidl\1.3\hidl.cpp
external\wpa_supplicant_8\wpa_supplicant\hidl\1.3\hidl_manager.cpp
out\soong\.intermediates\hardware\interfaces\wifi\supplicant\1.3\android.hardware.wifi.supplicant@1.3_genc++\gen\android\hardware\wifi\supplicant\1.3\SupplicantAll.cpp
system\libhidl\transport\ServiceManagement.cpp
system\hwservicemanager\ServiceManager.cpp
main.c -> main() ==> main.c -> wpa_supplicant_init()
==> wpa_supplicant.c -> wpa_supplicant_init() ==> notify.c -> wpas_notify_supplicant_initialized()
==> hidl.cpp -> wpas_hidl_init() ==> hidl_manager.cpp -> registerHidlService()
==> SupplicantAll.cpp -> registerAsService() ==> ServiceManagement.cpp -> registerAsServiceInternal()
==> ServiceManager.cpp -> addWithChain() ==> ServiceManager.cpp -> addImpl()
==> ServiceManager.cpp -> sendPackageRegistrationNotification()
==> onRegistration(fqName, instanceName, false ) 触发回调
在SupplicantStaIfaceHal.java 初始化的时候注册了回调的监听
public boolean initialize() {
synchronized (mLock) {
if (mVerboseLoggingEnabled) {
Log.i(TAG, "Registering ISupplicant service ready callback.");
}
mISupplicant = null;
mISupplicantVendor = null;
mISupplicantStaIfaces.clear();
mISupplicantVendorStaIfaces.clear();
if (mIServiceManager != null) {
return true;
}
try {
mIServiceManager = getServiceManagerMockable();
if (mIServiceManager == null) {
Log.e(TAG, "Failed to get HIDL Service Manager");
return false;
}
if (!linkToServiceManagerDeath()) {
return false;
}
if (!mIServiceManager.registerForNotifications(
ISupplicant.kInterfaceName, "default", mServiceNotificationCallback)) {
Log.e(TAG, "Failed to register for notifications to "
+ ISupplicant.kInterfaceName);
mIServiceManager = null;
return false;
}
} catch (RemoteException e) {
Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
+ e);
supplicantServiceDiedHandler(mDeathRecipientCookie);
}
return true;
}
}
private final IServiceNotification mServiceNotificationCallback =
new IServiceNotification.Stub() {
public void onRegistration(String fqName, String name, boolean preexisting) {
synchronized (mLock) {
if (mVerboseLoggingEnabled) {
Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
+ ", " + name + " preexisting=" + preexisting);
}
if (!initSupplicantService()) {
Log.e(TAG, "initalizing ISupplicant failed.");
supplicantServiceDiedHandler(mDeathRecipientCookie);
} else {
Log.i(TAG, "Completed initialization of ISupplicant.");
}
}
}
};
private boolean initSupplicantService() {
synchronized (mLock) {
try {
mISupplicant = getSupplicantMockable();
} catch (RemoteException e) {
Log.e(TAG, "ISupplicant.getService exception: " + e);
return false;
} catch (NoSuchElementException e) {
Log.e(TAG, "ISupplicant.getService exception: " + e);
return false;
}
if (mISupplicant == null) {
Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
return false;
}
if (!linkToSupplicantDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) {
return false;
}
}
if (!initSupplicantVendorService())
Log.e(TAG, "Failed to init SupplicantVendor service");
return true;
}
到此supplicant已经启动
九、switchClientInterfaceToConnectivityMode 之后会继续执行mSupplicantStaIfaceHal.setupIface(iface.name) 来设置接口,完成后打印
Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
十、StartedState 继续处理 CMD_SWITCH_TO_CONNECT_MODE 消息 执行transitionTo(mConnectModeState); 方法 进入 ConnectModeState状态
@Override
public void enter() {
Log.d(TAG, "entering ConnectModeState");
mClientModeImpl.registerModeListener(mClientModeImplListener);
mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
mClientInterfaceName);
}
继续处理CMD_SWITCH_TO_CONNECT_MODE 消息
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_SWITCH_TO_CONNECT_MODE:
int newRole = message.arg1;
if (newRole != mRole) {
mRole = newRole;
mModeListener.onStarted();
}
break;
}
}
触发onStarted()回调
onStarted()在ActiveModeWarden.java中定义
private class ClientListener extends ModeCallback implements ActiveModeManager.Listener {
@Override
public void onStarted() {
updateClientScanMode();
updateBatteryStats();
}
@Override
public void onStopped() {
mActiveModeManagers.remove(getActiveModeManager());
updateClientScanMode();
updateBatteryStats();
mWifiController.sendMessage(WifiController.CMD_STA_STOPPED);
}
@Override
public void onStartFailure() {
mActiveModeManagers.remove(getActiveModeManager());
updateClientScanMode();
updateBatteryStats();
mWifiController.sendMessage(WifiController.CMD_STA_START_FAILURE);
}
}
然后执行updateClientScanMode
private void updateClientScanMode() {
boolean scanEnabled = hasAnyClientModeManager();
boolean scanningForHiddenNetworksEnabled;
if (mContext.getResources().getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) {
scanningForHiddenNetworksEnabled = hasAnyClientModeManager();
} else {
scanningForHiddenNetworksEnabled = hasAnyClientModeManagerInConnectivityRole();
}
mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
}
mScanRequestProxy.enableScanning() frameworks\opt\net\wifi\service\java\com\android\server\wifi\ScanRequestProxy.java
private void enableScanningInternal(boolean enable) {
if (!retrieveWifiScannerIfNecessary()) {
Log.e(TAG, "Failed to retrieve wifiscanner");
return;
}
mWifiScanner.setScanningEnabled(enable);
sendScanAvailableBroadcast(mContext, enable);
clearScanResults();
Log.i(TAG, "Scanning is " + (enable ? "enabled" : "disabled"));
}
private void enableScanningInternal(boolean enable) {
if (!retrieveWifiScannerIfNecessary()) {
Log.e(TAG, "Failed to retrieve wifiscanner");
return;
}
mWifiScanner.setScanningEnabled(enable);
sendScanAvailableBroadcast(mContext, enable);
clearScanResults();
Log.i(TAG, "Scanning is " + (enable ? "enabled" : "disabled"));
}
mWifiScanner.setScanningEnabled frameworks\base\wifi\java\android\net\wifi\WifiScanner.java
@SystemApi
@RequiresPermission(Manifest.permission.NETWORK_STACK)
public void setScanningEnabled(boolean enable) {
validateChannel();
mAsyncChannel.sendMessage(enable ? CMD_ENABLE : CMD_DISABLE);
}
之后就可就是开始扫描AP
|