另有一篇类似的 Wifi模块—源码分析Wifi启动1(Android P)_wifi ap_started csdn-CSDN博客
1.回顾
android O wifi启动流程主要包括驱动的加载,supplicant的启动,以及supplicant的连接(hidl),之前也看过Android 4.4的WiFi启动流程,前面提及的几个主要部分功能实现还是差不多的,Android O主要引入了Wificond和hidl。
2.流程梳理
下面这个图来自于 Wifi模块—源码分析Wifi启动1(Android P)_wifi ap_started csdn-CSDN博客
2.1 WifiManager
/**
* Enable or disable Wi-Fi.
* <p>
* Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
* permission to toggle wifi.
*
* @param enabled {@code true} to enable, {@code false} to disable.
* @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
* either already in the requested state, or in progress toward the requested state.
* @throws {@link java.lang.SecurityException} if the caller is missing required permissions.
*/
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2.2 WifiSerivceImpl
/**
* see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
* @param enable {@code true} to enable, {@code false} to disable.
* @return {@code true} if the enable/disable operation was
* started or is already in the queue.
*/
@Override
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;
}
2.3 WifiController
先看下状态机
// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
addState(mStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
addState(mDeviceActiveState, mStaEnabledState);
addState(mStaDisabledWithScanState, mDefaultState);
addState(mEcmState, mDefaultState);
// CHECKSTYLE:ON IndentationCheck
对比Android O的
简略了很多,ap相关(softap)剥离了,StaEnabledState和DeviceActiveState其实是一个了,可以合成一个。
初始状态
if (checkScanOnlyModeAvailable()) {
setInitialState(mStaDisabledWithScanState);
} else {
setInitialState(mStaDisabledState);
}
先暂时略过ScanOnly,先看StaDisabledState
class StaDisabledState extends State {
private int mDeferredEnableSerialNumber = 0;
private boolean mHaveDeferredEnable = false;
private long mDisabledTimestamp;
@Override
public void enter() {
mWifiStateMachinePrime.disableWifi();
// Supplicant can't restart right away, so note the time we switched off
mDisabledTimestamp = SystemClock.elapsedRealtime();
mDeferredEnableSerialNumber++;
mHaveDeferredEnable = false;
mWifiStateMachine.clearANQPCache();
}
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (mSettingsStore.isWifiToggleEnabled()) {
if (doDeferEnable(msg)) {
if (mHaveDeferredEnable) {
// have 2 toggles now, inc serial number and ignore both
mDeferredEnableSerialNumber++;
}
mHaveDeferredEnable = !mHaveDeferredEnable;
break;
}
transitionTo(mDeviceActiveState);
} else if (checkScanOnlyModeAvailable()) {
// only go to scan mode if we aren't in airplane mode
if (mSettingsStore.isAirplaneModeOn()) {
transitionTo(mStaDisabledWithScanState);
}
}
break;
打开WiFi后WifiController状态机切换(这边先梳理主动打开WiFi逻辑,always scan后续梳理)
/**
* Parent: StaEnabledState
*
* TODO (b/79209870): merge DeviceActiveState and StaEnabledState into a single state
*/
class DeviceActiveState extends State {
@Override
public void enter() {
mWifiStateMachinePrime.enterClientMode();
mWifiStateMachine.setHighPerfModeEnabled(false);
}
@Override
public boolean processMessage(Message msg) {
if (msg.what == CMD_USER_PRESENT) {
// TLS networks can't connect until user unlocks keystore. KeyStore
// unlocks when the user punches PIN after the reboot. So use this
// trigger to get those networks connected.
if (mFirstUserSignOnSeen == false) {
mWifiStateMachine.reloadTlsNetworksAndReconnect();
}
mFirstUserSignOnSeen = true;
return HANDLED;
} else if (msg.what == CMD_RECOVERY_RESTART_WIFI) {
final String bugTitle;
final String bugDetail;
if (msg.arg1 < SelfRecovery.REASON_STRINGS.length && msg.arg1 >= 0) {
bugDetail = SelfRecovery.REASON_STRINGS[msg.arg1];
bugTitle = "Wi-Fi BugReport: " + bugDetail;
} else {
bugDetail = "";
bugTitle = "Wi-Fi BugReport";
}
if (msg.arg1 != SelfRecovery.REASON_LAST_RESORT_WATCHDOG) {
(new Handler(mWifiStateMachineLooper)).post(() -> {
mWifiStateMachine.takeBugReport(bugTitle, bugDetail);
});
}
return NOT_HANDLED;
}
return NOT_HANDLED;
}
}
这边不一样了,出现了个WifiStateMachinePrime
mWifiStateMachinePrime.enterClientMode();
mWifiStateMachine.setHighPerfModeEnabled(false);
2.4 WifiStateMachinePrime
先瞄一眼这个新类的初始化
WifiInjector
mWifiStateMachinePrime = new WifiStateMachinePrime(this, mContext, wifiStateMachineLooper,
mWifiNative, new DefaultModeManager(mContext, wifiStateMachineLooper),
mBatteryStats);
...
mWifiController = new WifiController(mContext, mWifiStateMachine, wifiStateMachineLooper,
mSettingsStore, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade,
mWifiStateMachinePrime);
看下enterClientMode
/**
* Method to switch wifi into client mode where connections to configured networks will be
* attempted.
*/
public void enterClientMode() {
changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
}
看下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应该是上面两个都没打开的情况。(具体情况待更新)
private void changeMode(int newMode) {
mModeStateMachine.sendMessage(newMode);
}
看下ModeStateMachine状态机
private class ModeStateMachine extends StateMachine {
// 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;
private final State mWifiDisabledState = new WifiDisabledState();
private final State mClientModeActiveState = new ClientModeActiveState();
private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState();
ModeStateMachine() {
super(TAG, mLooper);
addState(mClientModeActiveState);
addState(mScanOnlyModeActiveState);
addState(mWifiDisabledState);
Log.d(TAG, "Starting Wifi in WifiDisabledState");
setInitialState(mWifiDisabledState);
start();
}
初始WifiDiabledState处理刚发来的切换状态消息
class WifiDisabledState extends ModeActiveState {
@Override
public void enter() {
Log.d(TAG, "Entering WifiDisabledState");
mDefaultModeManager.sendScanAvailableBroadcast(mContext, false);
mScanRequestProxy.enableScanningForHiddenNetworks(false);
mScanRequestProxy.clearScanResults();
}
@Override
public boolean processMessage(Message message) {
Log.d(TAG, "received a message in WifiDisabledState: " + message);
if (checkForAndHandleModeChange(message)) {
return HANDLED;
}
return NOT_HANDLED;
}
@Override
public void exit() {
// do not have an active mode manager... nothing to clean up
}
}
private boolean checkForAndHandleModeChange(Message message) {
switch(message.what) {
case ModeStateMachine.CMD_START_CLIENT_MODE:
Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
mModeStateMachine.transitionTo(mClientModeActiveState);
break;
case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
break;
case ModeStateMachine.CMD_DISABLE_WIFI:
Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
状态切换到ClientModeActiveState
class ClientModeActiveState extends ModeActiveState {
ClientListener mListener;
private class ClientListener implements ClientModeManager.Listener {
@Override
public void onStateChanged(int state) {
// make sure this listener is still active
if (this != mListener) {
Log.d(TAG, "Client mode state change from previous manager");
return;
}
Log.d(TAG, "State changed from client mode. state = " + state);
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
// error while setting up client mode or an unexpected failure.
mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
// client mode stopped
mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
// client mode is ready to go
Log.d(TAG, "client mode active");
} else {
// only care if client mode stopped or started, dropping
}
}
}
@Override
public void enter() {
Log.d(TAG, "Entering ClientModeActiveState");
mListener = new ClientListener();
mManager = mWifiInjector.makeClientModeManager(mListener);
mManager.start();
mActiveModeManagers.add(mManager);
updateBatteryStatsWifiState(true);
}
@Override
public void exit() {
super.exit();
mListener = null;
}
@Override
public boolean processMessage(Message message) {
if (checkForAndHandleModeChange(message)) {
return HANDLED;
}
switch(message.what) {
case CMD_START_CLIENT_MODE:
Log.d(TAG, "Received CMD_START_CLIENT_MODE when active - drop");
break;
case CMD_CLIENT_MODE_FAILED:
if (mListener != message.obj) {
Log.d(TAG, "Client mode state change from previous manager");
return HANDLED;
}
Log.d(TAG, "ClientMode failed, return to WifiDisabledState.");
// notify WifiController that ClientMode failed
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
case CMD_CLIENT_MODE_STOPPED:
if (mListener != message.obj) {
Log.d(TAG, "Client mode state change from previous manager");
return HANDLED;
}
Log.d(TAG, "ClientMode stopped, return to WifiDisabledState.");
// notify WifiController that ClientMode stopped
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
return NOT_HANDLED;
}
return NOT_HANDLED;
}
}
enter方法里主要干了两件事
Log.d(TAG, "Entering ClientModeActiveState");
mListener = new ClientListener();
mManager = mWifiInjector.makeClientModeManager(mListener);
mManager.start();
mActiveModeManagers.add(mManager);
updateBatteryStatsWifiState(true);
/**
* Create a ClientModeManager
*
* @param listener listener for ClientModeManager state changes
* @return a new instance of ClientModeManager
*/
public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
return new ClientModeManager(mContext, mWifiStateMachineHandlerThread.getLooper(),
mWifiNative, listener, mWifiMetrics, mScanRequestProxy, mWifiStateMachine);
}
/**
* Helper method to report wifi state as on/off (doesn't matter which mode).
*
* @param enabled boolean indicating that some mode has been turned on or off
*/
private void updateBatteryStatsWifiState(boolean enabled) {
try {
if (enabled) {
if (mActiveModeManagers.size() == 1) {
// only report wifi on if we haven't already
mBatteryStats.noteWifiOn();
}
} else {
if (mActiveModeManagers.size() == 0) {
// only report if we don't have any active modes
mBatteryStats.noteWifiOff();
}
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to note battery stats in wifi");
}
}
ClientModeManager.start
updateBatteryStatsWifiState
主要看下ClientModeManager.start
/**
* 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);
}
}
这里从api注释来看解耦出来了一个接口,用于Client, ScanOnly and SoftAp的实现。
看下start()方法
ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy,
WifiStateMachine wifiStateMachine) {
mContext = context;
mWifiNative = wifiNative;
mListener = listener;
mWifiMetrics = wifiMetrics;
mScanRequestProxy = scanRequestProxy;
mWifiStateMachine = wifiStateMachine;
mStateMachine = new ClientModeStateMachine(looper);
}
/**
* Start client mode.
*/
public void start() {
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
}
初始化了一个状态机,start是发出了一个消息给状态机来处理
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
addState(mIdleState);
addState(mStartedState);
setInitialState(mIdleState);
start();
}
状态机很简单,就两个状态,IdleState是初始状态。
private class IdleState extends State {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
mClientInterfaceName = null;
mIfaceIsUp = false;
}
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_START:
updateWifiState(WifiManager.WIFI_STATE_ENABLING,
WifiManager.WIFI_STATE_DISABLED);
mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
false /* not low priority */, mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLING);
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_UNKNOWN);
break;
}
sendScanAvailableBroadcast(false);
mScanRequestProxy.enableScanningForHiddenNetworks(false);
mScanRequestProxy.clearScanResults();
transitionTo(mStartedState);
break;
default:
Log.d(TAG, "received an invalid message: " + message);
return NOT_HANDLED;
}
return HANDLED;
}
}
这边逻辑和Android O的WiFi启动逻辑很像了,应该是初始化驱动和启动supplicant,具体看下。
private class StartedState extends State {
private void onUpChanged(boolean isUp) {
if (isUp == mIfaceIsUp) {
return; // no change
}
mIfaceIsUp = isUp;
if (isUp) {
Log.d(TAG, "Wifi is ready to use for client mode");
sendScanAvailableBroadcast(true);
mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,
mClientInterfaceName);
updateWifiState(WifiManager.WIFI_STATE_ENABLED,
WifiManager.WIFI_STATE_ENABLING);
} else {
if (mWifiStateMachine.isConnectedMacRandomizationEnabled()) {
// Handle the error case where our underlying interface went down if we
// do not have mac randomization enabled (b/72459123).
return;
}
// if the interface goes down we should exit and go back to idle state.
Log.d(TAG, "interface down!");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLED);
mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
}
}
@Override
public void enter() {
Log.d(TAG, "entering StartedState");
mIfaceIsUp = false;
onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
mScanRequestProxy.enableScanningForHiddenNetworks(true);
}
进入到StartedState可以看到wifi状态就更新为enabled了。
2.5 WifiNative
/**
* Setup an interface for Client mode operations.
*
* This method configures an interface in STA mode in all the native daemons
* (wificond, wpa_supplicant & vendor HAL).
*
* @param lowPrioritySta The requested STA has a low request priority (lower probability of
* getting created, higher probability of getting destroyed).
* @param interfaceCallback Associated callback for notifying status changes for the iface.
* @return Returns the name of the allocated interface, will be null on failure.
*/
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;
}
}
这边逻辑不大一样,framework基本梳理完了到hal了,先梳理下面3步
startHal
startSupplicant
createStaIface
/** 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;
}
}
2.6 WifiVendorHal
/**
* 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;
}
}
2.7 HalDeviceManager
/**
* 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;
}
}
}
先看下mWifi是什么
/**
* Initialize IWifi and register death listener and event callback.
*
* - It is possible that IWifi is not ready - we have a listener on IServiceManager for it.
* - It is not expected that any of the registrations will fail. Possible indication that
* service died after we obtained a handle to it.
*
* Here and elsewhere we assume that death listener will do the right thing!
*/
private void initIWifiIfNecessary() {
if (mDbg) Log.d(TAG, "initIWifiIfNecessary");
synchronized (mLock) {
if (mWifi != null) {
return;
}
try {
mWifi = getWifiServiceMockable();
if (mWifi == null) {
Log.e(TAG, "IWifi not (yet) available - but have a listener for it ...");
return;
}
if (!mWifi.linkToDeath(mIWifiDeathRecipient, /* don't care */ 0)) {
Log.e(TAG, "Error on linkToDeath on IWifi - will retry later");
return;
}
WifiStatus status = mWifi.registerEventCallback(mWifiEventCallback);
if (status.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "IWifi.registerEventCallback failed: " + statusString(status));
mWifi = null;
return;
}
// Stopping wifi just in case. This would also trigger the status callback.
stopWifi();
} catch (RemoteException e) {
Log.e(TAG, "Exception while operating on IWifi: " + e);
}
}
}
/**
* Wrapper function to access the HIDL services. Created to be mockable in unit-tests.
*/
protected IWifi getWifiServiceMockable() {
try {
return IWifi.getService();
} catch (RemoteException e) {
Log.e(TAG, "Exception getting IWifi service: " + e);
return null;
}
}
这和之前Android O一样的
2.8 wifi.cpp
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;
}
看下initializeModeControllerAndLegacyHal
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);
}
这边也有两步,第二步应该和Android O一样
mode_controller_->initialize()
legacy_hal_->initialize()
2.9 wifi_mode_controller.cpp
/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;
}
加载WiFi驱动
2.10 wifi_legacy_hal.cpp
/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;
}
这边初始化legacy hal和Android O一模一样,不重复梳理了。
到这边startHal就梳理完了,下面接着梳理startSupplicant
2.11 WificondControl
回头看下WifiNative的startSupplicant
/** Helper method invoked to start supplicant if there were no STA ifaces */
private boolean startSupplicant() {
synchronized (mLock) {
if (!mIfaceMgr.hasAnyStaIface()) {
if (!mWificondControl.enableSupplicant()) {
Log.e(TAG, "Failed to enable supplicant");
return false;
}
if (!waitForSupplicantConnection()) {
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;
}
}
/**
* This method is called to wait for establishing connection to wpa_supplicant.
*
* @return true if connection is established, false otherwise.
*/
private boolean waitForSupplicantConnection() {
// Start initialization if not already started.
if (!mSupplicantStaIfaceHal.isInitializationStarted()
&& !mSupplicantStaIfaceHal.initialize()) {
return false;
}
boolean connected = false;
int connectTries = 0;
while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
// Check if the initialization is complete.
connected = mSupplicantStaIfaceHal.isInitializationComplete();
if (connected) {
break;
}
try {
Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
} catch (InterruptedException ignore) {
}
}
return connected;
}
可以看到先启动supplicant,然后等待supplicant连接上方便后续通信,连接逻辑也和Android O一样的。
WificondControl
/**
* Enable wpa_supplicant via wificond.
* @return Returns true on success.
*/
public boolean enableSupplicant() {
if (!retrieveWificondAndRegisterForDeath()) {
return false;
}
try {
return mWificond.enableSupplicant();
} catch (RemoteException e) {
Log.e(TAG, "Failed to enable supplicant due to remote exception");
}
return false;
}
2.12 server.cpp
/system/connectivity/wificond/server.cpp
Status Server::enableSupplicant(bool* success) {
*success = supplicant_manager_->StartSupplicant();
return Status::ok();
}
2.13 supplicant_manager.cpp
/frameworks/opt/net/wifi/libwifi_system/supplicant_manager.cpp
bool SupplicantManager::StartSupplicant() {
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 200; /* wait at most 20 seconds for completion */
const prop_info* pi;
unsigned serial = 0;
/* Check whether already running */
if (property_get(kSupplicantInitProperty, supp_status, NULL) &&
strcmp(supp_status, "running") == 0) {
return true;
}
/*
* Get a reference to the status property, so we can distinguish
* the case where it goes stopped => running => stopped (i.e.,
* it start up, but fails right away) from the case in which
* it starts in the stopped state and never manages to start
* running at all.
*/
pi = __system_property_find(kSupplicantInitProperty);
if (pi != NULL) {
serial = __system_property_serial(pi);
}
property_set("ctl.start", kSupplicantServiceName);
sched_yield();
while (count-- > 0) {
if (pi == NULL) {
pi = __system_property_find(kSupplicantInitProperty);
}
if (pi != NULL) {
/*
* property serial updated means that init process is scheduled
* after we sched_yield, further property status checking is based on this
*/
if (__system_property_serial(pi) != serial) {
__system_property_read(pi, NULL, supp_status);
if (strcmp(supp_status, "running") == 0) {
return true;
} else if (strcmp(supp_status, "stopped") == 0) {
return false;
}
}
}
usleep(100000);
}
return false;
}
和Android O一样调用到libwifi_system启动supplicant
2.14 WifiVendorHal
最后看下WifiNative的createStaIface
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);
/**
* Helper function to handle creation of STA iface.
* For devices which do not the support the HAL, this will bypass HalDeviceManager &
* teardown any existing iface.
*/
private String createStaIface(@NonNull Iface iface, boolean lowPrioritySta) {
synchronized (mLock) {
if (mWifiVendorHal.isVendorHalSupported()) {
return mWifiVendorHal.createStaIface(lowPrioritySta,
new InterfaceDestoyedListenerInternal(iface.id));
} else {
Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
return handleIfaceCreationWhenVendorHalNotSupported(iface);
}
}
}
WifiVendorHal
/**
* Create a STA iface using {@link HalDeviceManager}.
*
* @param lowPrioritySta The requested STA has a low request priority (lower probability of
* getting created, higher probability of getting destroyed).
* @param destroyedListener Listener to be invoked when the interface is destroyed.
* @return iface name on success, null otherwise.
*/
public String createStaIface(boolean lowPrioritySta,
InterfaceDestroyedListener destroyedListener) {
synchronized (sLock) {
IWifiStaIface iface = mHalDeviceManager.createStaIface(lowPrioritySta,
new StaInterfaceDestroyedListenerInternal(destroyedListener), null);
if (iface == null) {
mLog.err("Failed to create STA iface").flush();
return stringResult(null);
}
String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
if (TextUtils.isEmpty(ifaceName)) {
mLog.err("Failed to get iface name").flush();
return stringResult(null);
}
if (!registerStaIfaceCallback(iface)) {
mLog.err("Failed to register STA iface callback").flush();
return stringResult(null);
}
mIWifiRttController = mHalDeviceManager.createRttController();
if (mIWifiRttController == null) {
mLog.err("Failed to create RTT controller").flush();
return stringResult(null);
}
if (!registerRttEventCallback()) {
mLog.err("Failed to register RTT controller callback").flush();
return stringResult(null);
}
if (!retrieveWifiChip((IWifiIface) iface)) {
mLog.err("Failed to get wifi chip").flush();
return stringResult(null);
}
enableLinkLayerStats(iface);
mIWifiStaIfaces.put(ifaceName, iface);
return ifaceName;
}
}
2.15 HalDeviceManager
/**
* Create a STA interface if possible. Changes chip mode and removes conflicting interfaces if
* needed and permitted by priority.
*
* @param lowPrioritySta Indicates whether the requested STA is a low priority STA. The priority
* and preemption rules for low priority STA are:
* - Do not destroy any interface for it (even another low priority STA)
* - Destroy it for any other request
* @param destroyedListener Optional (nullable) listener to call when the allocated interface
* is removed. Will only be registered and used if an interface is
* created successfully.
* @param handler Handler on which to dispatch listener. Null implies the listener will be
* invoked synchronously from the context of the client which triggered the
* iface destruction.
* @return A newly created interface - or null if the interface could not be created.
*/
public IWifiStaIface createStaIface(boolean lowPrioritySta,
@Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler) {
return (IWifiStaIface) createIface(IfaceType.STA, lowPrioritySta, destroyedListener,
handler);
}
private IWifiIface createIface(int ifaceType, boolean lowPriority,
InterfaceDestroyedListener destroyedListener, Handler handler) {
if (mDbg) {
Log.d(TAG, "createIface: ifaceType=" + ifaceType + ", lowPriority=" + lowPriority);
}
synchronized (mLock) {
WifiChipInfo[] chipInfos = getAllChipInfo();
if (chipInfos == null) {
Log.e(TAG, "createIface: no chip info found");
stopWifi(); // major error: shutting down
return null;
}
if (!validateInterfaceCache(chipInfos)) {
Log.e(TAG, "createIface: local cache is invalid!");
stopWifi(); // major error: shutting down
return null;
}
IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, lowPriority,
destroyedListener, handler);
if (iface != null) { // means that some configuration has changed
if (!dispatchAvailableForRequestListeners()) {
return null; // catastrophic failure - shut down
}
}
return iface;
}
}
看下createIfaceIfPossible
private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType,
boolean lowPriority, InterfaceDestroyedListener destroyedListener, Handler handler) {
if (VDBG) {
Log.d(TAG, "createIfaceIfPossible: chipInfos=" + Arrays.deepToString(chipInfos)
+ ", ifaceType=" + ifaceType + ", lowPriority=" + lowPriority);
}
synchronized (mLock) {
IfaceCreationData bestIfaceCreationProposal = null;
for (WifiChipInfo chipInfo: chipInfos) {
for (IWifiChip.ChipMode chipMode: chipInfo.availableModes) {
for (IWifiChip.ChipIfaceCombination chipIfaceCombo : chipMode
.availableCombinations) {
int[][] expandedIfaceCombos = expandIfaceCombos(chipIfaceCombo);
if (VDBG) {
Log.d(TAG, chipIfaceCombo + " expands to "
+ Arrays.deepToString(expandedIfaceCombos));
}
for (int[] expandedIfaceCombo: expandedIfaceCombos) {
IfaceCreationData currentProposal = canIfaceComboSupportRequest(
chipInfo, chipMode, expandedIfaceCombo, ifaceType, lowPriority);
if (compareIfaceCreationData(currentProposal,
bestIfaceCreationProposal)) {
if (VDBG) Log.d(TAG, "new proposal accepted");
bestIfaceCreationProposal = currentProposal;
}
}
}
}
}
if (bestIfaceCreationProposal != null) {
IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);
if (iface != null) {
InterfaceCacheEntry cacheEntry = new InterfaceCacheEntry();
cacheEntry.chip = bestIfaceCreationProposal.chipInfo.chip;
cacheEntry.chipId = bestIfaceCreationProposal.chipInfo.chipId;
cacheEntry.name = getName(iface);
cacheEntry.type = ifaceType;
if (destroyedListener != null) {
cacheEntry.destroyedListeners.add(
new InterfaceDestroyedListenerProxy(
cacheEntry.name, destroyedListener, handler));
}
cacheEntry.creationTime = mClock.getUptimeSinceBootMillis();
cacheEntry.isLowPriority = lowPriority;
if (mDbg) Log.d(TAG, "createIfaceIfPossible: added cacheEntry=" + cacheEntry);
mInterfaceInfoCache.put(
Pair.create(cacheEntry.name, cacheEntry.type), cacheEntry);
return iface;
}
}
}
return null;
}
/**
* Performs chip reconfiguration per the input:
* - Removes the specified interfaces
* - Reconfigures the chip to the new chip mode (if necessary)
* - Creates the new interface
*
* Returns the newly created interface or a null on any error.
*/
private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
int ifaceType) {
if (mDbg) {
Log.d(TAG, "executeChipReconfiguration: ifaceCreationData=" + ifaceCreationData
+ ", ifaceType=" + ifaceType);
}
synchronized (mLock) {
try {
// is this a mode change?
boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
|| ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);
// first delete interfaces/change modes
if (isModeConfigNeeded) {
// remove all interfaces pre mode-change
// TODO: is this necessary? note that even if we don't want to explicitly
// remove the interfaces we do need to call the onDeleted callbacks - which
// this does
for (WifiIfaceInfo[] ifaceInfos: ifaceCreationData.chipInfo.ifaces) {
for (WifiIfaceInfo ifaceInfo: ifaceInfos) {
removeIfaceInternal(ifaceInfo.iface); // ignore return value
}
}
WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
ifaceCreationData.chipModeId);
if (status.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "executeChipReconfiguration: configureChip error: "
+ statusString(status));
return null;
}
} else {
// remove all interfaces on the delete list
for (WifiIfaceInfo ifaceInfo: ifaceCreationData.interfacesToBeRemovedFirst) {
removeIfaceInternal(ifaceInfo.iface); // ignore return value
}
}
// create new interface
Mutable<WifiStatus> statusResp = new Mutable<>();
Mutable<IWifiIface> ifaceResp = new Mutable<>();
switch (ifaceType) {
case IfaceType.STA:
ifaceCreationData.chipInfo.chip.createStaIface(
(WifiStatus status, IWifiStaIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.AP:
ifaceCreationData.chipInfo.chip.createApIface(
(WifiStatus status, IWifiApIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.P2P:
ifaceCreationData.chipInfo.chip.createP2pIface(
(WifiStatus status, IWifiP2pIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
case IfaceType.NAN:
ifaceCreationData.chipInfo.chip.createNanIface(
(WifiStatus status, IWifiNanIface iface) -> {
statusResp.value = status;
ifaceResp.value = iface;
});
break;
}
if (statusResp.value.code != WifiStatusCode.SUCCESS) {
Log.e(TAG, "executeChipReconfiguration: failed to create interface ifaceType="
+ ifaceType + ": " + statusString(statusResp.value));
return null;
}
return ifaceResp.value;
} catch (RemoteException e) {
Log.e(TAG, "executeChipReconfiguration exception: " + e);
return null;
}
}
}
2.16 wifi_chip.cpp
Return<void> WifiChip::configureChip(ChipModeId mode_id,
configureChip_cb hidl_status_cb) {
return validateAndCallWithLock(
this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::configureChipInternal, hidl_status_cb, mode_id);
}
WifiStatus WifiChip::configureChipInternal(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
if (!isValidModeId(mode_id)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
if (mode_id == current_mode_id_) {
LOG(DEBUG) << "Already in the specified mode " << mode_id;
return createWifiStatus(WifiStatusCode::SUCCESS);
}
WifiStatus status = handleChipConfiguration(lock, mode_id);
if (status.code != WifiStatusCode::SUCCESS) {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onChipReconfigureFailure(status).isOk()) {
LOG(ERROR)
<< "Failed to invoke onChipReconfigureFailure callback";
}
}
return status;
}
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onChipReconfigured(mode_id).isOk()) {
LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
}
}
current_mode_id_ = mode_id;
LOG(INFO) << "Configured chip in mode " << mode_id;
return status;
}
WifiStatus WifiChip::handleChipConfiguration(
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
ChipModeId mode_id) {
// If the chip is already configured in a different mode, stop
// the legacy HAL and then start it after firmware mode change.
if (isValidModeId(current_mode_id_)) {
LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
<< " to mode " << mode_id;
invalidateAndRemoveAllIfaces();
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->stop(lock, []() {});
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to stop legacy HAL: "
<< legacyErrorToString(legacy_status);
return createWifiStatusFromLegacyError(legacy_status);
}
}
// Firmware mode change not needed for V2 devices.
bool success = true;
if (mode_id == kV1StaChipModeId) {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
} else if (mode_id == kV1ApChipModeId) {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
}
if (!success) {
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to start legacy HAL: "
<< legacyErrorToString(legacy_status);
return createWifiStatusFromLegacyError(legacy_status);
}
// Every time the HAL is restarted, we need to register the
// radio mode change callback.
WifiStatus status = registerRadioModeChangeCallback();
if (status.code != WifiStatusCode::SUCCESS) {
// This probably is not a critical failure?
LOG(ERROR) << "Failed to register radio mode change callback";
}
return createWifiStatus(WifiStatusCode::SUCCESS);
}
2.17 wifi_mode_controller.cpp
/hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp
bool WifiModeController::changeFirmwareMode(IfaceType type) {
if (!driver_tool_->ChangeFirmwareMode(
convertIfaceTypeToFirmwareMode(type))) {
LOG(ERROR) << "Failed to change firmware mode";
return false;
}
return true;
}
切换firmwareMode也完成了
3.总结
流程看起来和以前有点不大一样,变成了
加载驱动-启动supplicant-连接supplicant-切换firmwareMode
常见日志
setWifiEnabled: true
WifiStateMachine ->WifiDisabledState to ClientMode ->ClientModeActiveState IdleState
WifiStateMachine: setting wifi state to: 2n (ENABLING)
SettingsProvider: content://settings/global/wifi_on
wificond->wpa_supplicant
wpa_supplicant: Successfully initialized wpa_supplicant
SupplicantStaIfaceHal: Completed initialization of ISupplicant
HalDevMgr: createIface: ifaceType=0, lowPriority=false
WifiHAL : Initializing wifi
WifiHAL : Initialized Wifi HAL Successfully
[email protected]: Adding interface handle for wlan0
[email protected]: Adding interface handle for p2p0
HalDevMgr: createIfaceIfPossible: added cacheEntry={name=wlan0
wpa_supplicant: Override interface parameter: ctrl_interface
wpa_supplicant: wlan0: Added interface wlan0
WifiNative: Successfully setup Iface:{Name=wlan0,Id=1,Type=STA}
WifiClientModeManager: entering StartedState (IDLE->Started)
WifiStateMachine: setting wifi state to: 3(WIFI_STATE_ENABLED)
---------------------------------------
setWifiEnabled: false
WifiStateMachinePrime: Switching from ClientModeActiveState to WifiDisabled
WifiClientModeManager: currentstate: StartedState
WifiStateMachine: setting wifi state to: 0(DISABLING)
HalDevMgr: removeIfaceInternal: iface(name)=wlan0, type=0
wpa_supplicant: wlan0: Removing interface wlan0
wpa_supplicant: wlan0: Request to deauthenticate
wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED
wpa_supplicant: wlan0: State: COMPLETED -> DISCONNECTED
wpa_supplicant: wlan0: State: DISCONNECTED -> DISCONNECTED
wpa_supplicant: Remove interface wlan0 from radio phy0
DhcpClient: Read error
init : Received control message 'stop' for 'wpa_supplicant' from pid: 1384 (/system/bin/wificond)
SupplicantStaIfaceHal: ISupplicant died: cookie=0
DhcpClient: doQuit
[email protected]: Wifi HAL stopped
WifiVendorHal: Vendor Hal stopped
WifiStateMachine: setting wifi state to: 1 (DISABLED)
————————————————
版权声明:本文为CSDN博主「i加加」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_20059415/article/details/88206937