一 前言
这次接着讲Wifi工程流程中的Wifi热点查找过程,也是Wifi启动的过程延续,Wifi启动过程中会更新Wifi的状态,框架层也有相应广播发出,应用层接收到广播后开始进行热点的扫描。可以先看前面Wifi启动的分析过程。
二 图示调用流程
由于在 frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java直接接收到框架层发出的wifi状态改变的广播WIFI_STATE_CHANGED_ACTION(这个在后面有交待),所以这里的图示调用流程将从WifiTracker.java开始。
三 代码具体流程
我们先回顾一下之前wifi启动过程的相关细节,wifi启动过程会走到ClientModeStateMachine这个状态机,具体看 Wifi模块—源码分析Wifi启动1(Android P)。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java
看ClientModeStateMachine的构造函数。
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
addState(mIdleState);
addState(mStartedState);
setInitialState(mIdleState);
start();
}
再看start()。
/**
* Start client mode.
*/
public void start() {
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
}
发送了一个消息ClientModeStateMachine.CMD_START。
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;
}
}
在IdleState的状态里接收到消息做相关处理updateWifiState,继续看这个方法。
/**
* Update Wifi state and send the broadcast.
* @param newState new Wifi state
* @param currentState current wifi state
*/
private void updateWifiState(int newState, int currentState) {
if (!mExpectedStop) {
mListener.onStateChanged(newState);
} else {
Log.d(TAG, "expected stop, not triggering callbacks: newState = "
+ newState);
}
// Once we report the mode has stopped/failed any other stop signals are redundant
// note: this can happen in failure modes where we get multiple callbacks as underlying
// components/interface stops or the underlying interface is destroyed in cleanup
if (newState == WifiManager.WIFI_STATE_UNKNOWN
|| newState == WifiManager.WIFI_STATE_DISABLED) {
mExpectedStop = true;
}
if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
// do not need to broadcast failure to system
return;
}
mWifiStateMachine.setWifiStateForApiCalls(newState);
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_WIFI_STATE, newState);
intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
在这里发送了一个广播sendStickyBroadcastAsUser,广播具体是WifiManager.WIFI_STATE_CHANGED_ACTION。
OK,上面的分析都属于上次分析wifi启动的部分,就是wifi在启动过程中会更新wifi状态并发送wifi状态改变的广播。不过。上次在分析wifi启动过程中也没有分析这个更新wifi状态发送广播的这个内容,这次作为一个补充也是开启接下来的wifi热点扫描的流程分析,接下来的wifi扫描过程是指打开wifi之后自动扫描过程而不是手动去刷新扫描。
1 应用层
1.1 packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
在WifiSettings.java里初始化WifiTracker。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mWifiTracker = WifiTrackerFactory.create(
getActivity(), this, getLifecycle(), true, true);
mWifiManager = mWifiTracker.getManager();
...
}
1.2 packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
应用层在扫描过程中貌似没做什么事情但暂且提一下WifiEnabler也会接收到WifiManager.WIFI_STATE_CHANGED_ACTION广播并会相关的处理。
private boolean mStateMachineEvent;
private final IntentFilter mIntentFilter;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
handleWifiStateChanged(mWifiManager.getWifiState());
} else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
if (!mConnected.get()) {
handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState)
intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
}
} else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
mConnected.set(info.isConnected());
handleStateChanged(info.getDetailedState());
}
}
};
看handleWifiStateChanged。
private void handleWifiStateChanged(int state) {
// Clear any previous state
mSwitchWidget.setDisabledByAdmin(null);
switch (state) {
case WifiManager.WIFI_STATE_ENABLING:
break;
case WifiManager.WIFI_STATE_ENABLED:
setSwitchBarChecked(true);
mSwitchWidget.setEnabled(true);
break;
case WifiManager.WIFI_STATE_DISABLING:
break;
case WifiManager.WIFI_STATE_DISABLED:
setSwitchBarChecked(f