[android-wifi]开启,扫描与连接相关流程
来源:互联网 发布:android 仿淘宝分类 编辑:程序博客网 时间:2024/05/23 01:19
[android-wifi]开启,扫描与连接相关流程
*重要知识点*:
<pre>
mP0
/ \
mP1 mS0
/ \
mS2 mS1
/ \ \
mS3 mS4 mS5 ---> initial state
</pre>
* <p>After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
* So the order of calling processMessage when a message is received is mS5,
* mS1, mP1, mP0 assuming each processMessage indicates it can't handle this
* message by returning false or NOT_HANDLED.</p>
*
* <p>Now assume mS5.processMessage receives a message it can handle, and during
* the handling determines the machine should change states. It could call
* transitionTo(mS4) and return true or HANDLED. Immediately after returning from
* processMessage the state machine runtime will find the common parent,
* which is mP1. It will then call mS5.exit, mS1.exit, mS2.enter and then
* mS4.enter. The new list of active states is mP0, mP1, mS2 and mS4. So
* when the next message is received mS4.processMessage will be invoked.
解释如下:
假设目前的状态机是如上图所示.
1.当目前的状态机是mS5时,收到消息处理的顺序为mS5,mS1, mP1, mP0而且是当方法processMessage 返回的是NOT_HANDLED消息才能被上一层继续处理.
而且处理的时候应该当改变相应的状态并返回真.比如mS5收到消息后转换相应的状态到mS4并返回HANDLED.
2.转换到mS4时,状态机将会发现mS5和mS4同样的父层级是mP1,接着状态机会调用mS5的exit方法,mS1的exit方法.调用mS2的enter和mS4的enter方法。
这个时候新的激活状态结构为mP0,mP1,mS2,mS4,而接收消息会被mS4优先处理
举列说明:
Android-7.1(4.4基本一样)代码的WIFI模块中:
在WifiController文件中的的状态机 "部分结构" 如下[其中mApStaDisabledState为状态机初始状态]:
mDefaultState.....................................................
| |
mApStaDisabledState mStaEnabledState.....................
|
mDeviceActiveState
|
DeviceActiveHighPerfState
简单表示如下:
mP0(mDefaultState)
/ \
(mStaEnabledState)mP1 mS0(mApStaDisabledState)
/ \
mS1(mDeviceActiveState)
当前状态为:mP0(mDefaultState),mS0(mApStaDisabledState)
经过下面操作后状态为:mP0,mP1(mStaEnabledState),mS1(mDeviceActiveState)而且会调用mP1(mStaEnabledState)的enter方法再调用mS1(mDeviceActiveState)的enter方法
操作步骤:打开设置中的wifi开关在WifiController文件中的状态机会发生变化如下(因为mApStaDisabledState状态机是初始状态首先收到信息并进行相应的逻辑处理):
mApStaDisabledState状态机优先处理消息
{
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (mDeviceIdle == false) {
checkLocksAndTransitionWhenDeviceActive();//假设走个方法"当前设备是活动使用状态"
} else {
checkLocksAndTransitionWhenDeviceIdle();
}
break;
return HANDLED
}
private void checkLocksAndTransitionWhenDeviceActive() {
if (mWifiLockManager.getStrongestLockMode() == WIFI_MODE_FULL_HIGH_PERF) {
// It is possible for the screen to be off while the device is
// is active (mIdleMillis), so we need the high-perf mode
// otherwise powersaving mode will be turned on.
transitionTo(mDeviceActiveHighPerfState);//为mDeviceActiveState的子层级
} else {
transitionTo(mDeviceActiveState);//假设走这个方法
}
}
说明:这个时候mApStaDisabledState状态会处理完消息并转换成mDeviceActiveState状态
根据状态机原理会调用mDeviceActiveState的父级mStaEnabledState的enter方法和mDeviceActiveState的enter方法
mStaEnabledState
{
@Override
public void enter() {
mWifiStateMachine.setSupplicantRunning(true);
//上面这个方法会调用sendMessage(CMD_START_SUPPLICANT)在WifiStateMachine的状态机内部进行消息传递
//而WifiStateMachine的默认初始状态为InitialState处理此消息调用wifiNative.loadDriver
//继续调用mWifiNative.startHal方法和mWifiNative.startSupplicant 就把wifi驱动和hal层和wpa_supplicant建立起来可以进行下一步连接wifi
//而WifiStateMachine从InitialState状态变为transitionTo(mSupplicantStartingState)状态
}
}
说明:这样通过状态机有效的管理Wifi的驱动被加载,HAL层和关键模块wpa_supplicant也被启动.下一步wifi的连接动作就可以进行了
*在WifiController的状态机变为*:
mDefaultState---mStaEnabledState---mDeviceActiveState
这样状态机的例子就结束了.应该可以看出状态机如果理解对代码就比较好梳理.
不过上面逻辑已经到WifiStateMachine的setSupplicantRunning了趁热继续详细分析一下
WifiStateMachine::setSupplicantRunning
public void setSupplicantRunning(boolean enable) {
if (enable) {
WifiNative.setApMode(false);
sendMessage(CMD_START_SUPPLICANT);//发送消息 此时WifiStateMachine的初始状态机InitialState会处理此消息
}
}
InitialState{
@Override
public boolean processMessage(Message message) {
logStateAndMessage(message, this);
switch (message.what) {
case CMD_START_SUPPLICANT:
//见上面简单描述
mWifiNative.loadDriver()
mNwService.wifiFirmwareReload(mInterfaceName, "STA");
mWifiNative.startHal()
mWifiNative.startSupplicant(mP2pSupported)
mWifiMonitor.startMonitoring(mInterfaceName);//启动监听器状态机
transitionTo(mSupplicantStartingState)//转换状态
}
*在WifiStateMachine的状态机变为*:
mDefaultState---mSupplicantStartingState
看下关键代码:
WifiMonitor::startMonitoring
{
mWifiNative.connectToSupplicant();//启动supplicant后会接着启动MonitorThread线程调用WifiNative.waitForEvent 来监听事件
//事件调用方法比如handleSupplicantStateChange或者handleDriverEvent
sendMessage(iface, SUP_CONNECTION_EVENT)
}
又因为在WifiStateMachine中通过如下方法注册了
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_CONNECTION_EVENT, getHandler())
所以WifiStateMachine的mSupplicantStartingState会处理此消息
mSupplicantStartingState
{
@Override
public boolean processMessage(Message message) {
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
setWifiState(WIFI_STATE_ENABLED);
mWifiInfo.setMacAddress(mWifiNative.getMacAddress());//设置MAC地址
transitionTo(mDriverStartedState);//转换状态到mDriverStartedState
}
}
*在WifiStateMachine的状态机又变为*
mDefaultState---mSupplicantStartedState(因为是mDriverStartedState的父层级)---mDriverStartedState
继续趁热分析
mSupplicantStartedState
{
@Override
public void enter() {
mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000)//设置扫描周期会保存到wpa_supplicant相应的结构体中
}
}
mDriverStartedState
{
@Override
public void enter() {
transitionTo(mDisconnectedState);/转换到mDisconnectedState状态
}
}
*在WifiStateMachine的状态机又变为*
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState(因为是父层级)---mDisconnectedState
mDisconnectedState
{
@Override
public void enter() {
//执行300S后周期搜索无线网络
//<integer translatable="false" name="config_wifi_no_network_periodic_scan_interval">300000</integer>
if (mNoNetworksPeriodicScan != 0 && !mP2pConnected.get()
&& mWifiConfigManager.getSavedNetworks().size() == 0) {
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);
}
}
@Override
public boolean processMessage(Message message) {
boolean ret = HANDLED;
switch (message.what) {
case CMD_NO_NETWORKS_PERIODIC_SCAN:
if (mP2pConnected.get()) break;
if (mNoNetworksPeriodicScan != 0 && message.arg1 == mPeriodicScanToken &&
mWifiConfigManager.getSavedNetworks().size() == 0) {
startScan(UNKNOWN_SCAN_SOURCE, -1, null, WIFI_WORK_SOURCE);//开始搜索网络
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);//重新执行搜索网络
}
break;
}
----------------"以上逻辑4.4与7.1代码 大同小异 相差不是很大 状态机基本一样"-----------
----------------"开启supplicant后要进行扫描网络接入点"----------------
1.余下为搜索网络相关逻辑
由于7.1针对搜索网络添加了新的状态机机制所以这部分和4.4有比较大的区别
packages.SettingsLib.wifi.WifiTracker::mReceiver监听到此广播
{
WifiManager.WIFI_STATE_CHANGED_ACTION//此状态是由mSupplicantStartingState传过来
mWifiManager.startScan//最终调用接口启动扫描
}
而界面上的更新接入点是在WifiTracker::updateAccessPoints实现
由上面可知当前状态是由mDriverStartedState启动扫描
WifiStateMachine.DriverStartedState
{
case CMD_START_SCAN:
handleScanRequest(message);
break;
}
接着调用WifiStateMachine.startScanNative
{
mWifiScanner.startScan
}
在frameowkrs.base.wifi.WifiScanner.startScan
{
mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams)
}
-------扫描服务介绍----
1.WifiScanningServiceImpl extends IWifiScanner.Stub
2.在FrameworkFacade.makeWifiScanner{
new WifiScanner(context, IWifiScanner.Stub.asInterface(
getService(Context.WIFI_SCANNING_SERVICE)), looper)
}
//把WifiScanningServiceImpl保存到WifiScanner的内部通过AsyncChannel将两者的ServiceHandler和ClientHandler连接起来
//所以WifiScanner.startScan(CMD_START_SINGLE_SCAN)消息将在WifiScanningServiceImpl实现
WifiScanningServiceImpl
{
case WifiScanner.CMD_START_SINGLE_SCAN:
case WifiScanner.CMD_STOP_SINGLE_SCAN:
mSingleScanStateMachine.sendMessage(Message.obtain(msg));
}
WifiScanningServiceImpl.SingleScanStateMachine.DriverStartedState
{
case WifiScanner.CMD_START_SINGLE_SCAN:
mWifiMetrics.incrementOneshotScanCount();
tryToStartNewScan
}
WifiScanningServiceImpl的tryToStartNewScan方法
{
mScannerImpl.startSingleScan//通过WifiScannerImpl去执行搜索
transitionTo(mScanningState);//转换状态
}
而WifiScanningService的构造方法传递WifiScannerImpl的实现类
{
mImpl = new WifiScanningServiceImpl(getContext(), mHandlerThread.getLooper(),
WifiScannerImpl.DEFAULT_FACTORY, BatteryStatsService.getService(),
WifiInjector.getInstance());
//工厂类是HalWifiScannerImpl或者SupplicantWifiScannerImpl这里走SupplicantWifiScannerImpl
}
最终会调用SupplicantWifiScannerImpl类 并调用mWifiNative.scan进行扫描网络热入点
而在WifiMonitor.handleEvent
{
case SCAN_RESULTS:
sendMessage(iface, SCAN_RESULTS_EVENT);
break;
}
又在SupplicantWifiScannerImpl.SupplicantWifiScannerImpl中进行注册
{
WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler);
}
又在WifiStateMachine中进行注册
{
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_RESULTS_EVENT, getHandler());
}
SupplicantWifiScannerImpl
{
case WifiMonitor.SCAN_RESULTS_EVENT:
mAlarmManager.cancel(mScanTimeoutListener);
pollLatestScanData();
processPendingScans();
break;
}
会执行SupplicantWifiScannerImpl.pollLatestScanData方法
{
mWifiNative.getScanResults
}
而WifiScanningServiceImpl:onScanStatus
{
sendMessage(CMD_SCAN_RESULTS_AVAILABLE)
}
//由前面而知在扫描之后会入ScanningState状态所以事件消息将会由此处理
在WifiScanningServiceImpl.WifiSingleScanStateMachine.ScanningState
{
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_SCAN_RESULTS_AVAILABLE:
reportScanResults(mScannerImpl.getLatestSingleScanResults());//调用SupplicantWifiScannerImpl
mActiveScans.clear();
transitionTo(mIdleState);//转换状态
}
回调到WifiScanner
{
case CMD_SCAN_RESULT :
((ScanListener) listener).onResults(((ParcelableScanData) msg.obj).getResults());
return;
}
在看WifiStateMachine.SupplicantStartedState中对事件的处理
{
case WifiMonitor.SCAN_RESULTS_EVENT:
case WifiMonitor.SCAN_FAILED_EVENT:
maybeRegisterNetworkFactory(); // Make sure our NetworkFactory is registered
setScanResults();
//如上方法会调用ArrayList<ScanDetail> scanResults = mWifiNative.getScanResults()供WifiServiceImpl调用
if (mIsFullScanOngoing || mSendScanResultsBroadcast) {
/* Just updated results from full scan, let apps know about this */
boolean scanSucceeded = message.what == WifiMonitor.SCAN_RESULTS_EVENT;
sendScanResultsAvailableBroadcast(scanSucceeded);//发送广播
}
}
2.------------4.4的扫描流程--------------------
packages.apps.Settings.WifiSettings文件
{
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//监听广播如mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
handleEvent(context, intent);
}
};
状态上来后会调用WifiManager.startScan
}
WifiStateMachine.DriverStartedState
{
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP)
}
WifiStateMachine.startScanNative
{
mWifiNative.scan(type)
}
事件上传WifiMonitor.handleEvent
{
case SCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
break;
}
在WifiStateMachine.SupplicantStartedState
{
case WifiMonitor.SCAN_RESULTS_EVENT:
setScanResults();
sendScanResultsAvailableBroadcast();
mScanResultIsPending = false;
break;
}
在WifiStateMachine.setScanResults
{
mWifiNative.scanResults并保存在mScanResults中
}
而WifiStateMachine的syncGetScanResultsList可以提供给wifiManager使用
至此4.4和7.1搜索网络逻辑分析完毕其中7.1逻辑较为复杂而4.4比较简洁
-----------------------------------------------------------------------
2.搜索完网络 通过wifiManager.connect进行网络连接
注意:连接网络消息CONNECT_NETWORK将在mConnectModeState中进行处理
-----7.1----连接逻辑
WifiServiceImpl.ClientHandler
{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case WifiManager.CONNECT_NETWORK:
mWifiStateMachine.sendMessage(Message.obtain(msg));
}
}
}
由上可知状态为ConnectModeState
{
case WifiManager.CONNECT_NETWORK:
mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ true,
message.sendingUid) && mWifiNative.reconnect()
}
连接事件在ConnectModeState
{
case WifiMonitor.NETWORK_CONNECTION_EVENT:
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);//转换状态
}
:此时WifiStateMachine状态为
mDefaultState---mSupplicantStartedState---mDriverStartedState---mL2ConnectedState---mObtainingIpState
在mObtainingIpState.enter
{
final IpManager.ProvisioningConfiguration prov =
mIpManager.buildProvisioningConfiguration()
.withPreDhcpAction()
.withApfCapabilities(mWifiNative.getApfCapabilities())
.build();
mIpManager.startProvisioning(prov)
}
//又WifiStateMachine里面对IpManager实例化的时候有相应的回调类IpManagerCallback将被IpManager回调相应的方法并发送消息.
//相应的状态机会拦截相应的消息
在IpManager的RunningState.enter方法内
{
startIPv6();
startIPv4();
}
在L2ConnectedState的状态的处理消息方法中
{
case CMD_IP_CONFIGURATION_SUCCESSFUL:
handleSuccessfulIpConfiguration();
reportConnectionAttemptEnd(
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE);
sendConnectedState();
transitionTo(mConnectedState);
break;
}
此时进入连接状态
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState---mL2ConnectedState---mConnectedState
-----------------------------------------------------------------------------------------------------------------------------------
----4.4---连接逻辑
ConnectModeState.
{
case WifiManager.CONNECT_NETWORK
if (mWifiConfigStore.selectNetwork(netId) && mWifiNative.reconnect()) {
transitionTo(mDisconnectingState);
}
}
ObtainingIpState.enter
{
startDhcp();
}
//接着到VerifyingLinkState状态最后到CaptivePortalCheckState认证状态
//在此状态根据CMD_CAPTIVE_CHECK_COMPLETE消息调整到连接状态transitionTo(mConnectedState)
此时进入连接状态
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState---mL2ConnectedState---mConnectedState
--------------------------------------------------------------------------------------------------------------------------------
*重要知识点*:
<pre>
mP0
/ \
mP1 mS0
/ \
mS2 mS1
/ \ \
mS3 mS4 mS5 ---> initial state
</pre>
* <p>After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
* So the order of calling processMessage when a message is received is mS5,
* mS1, mP1, mP0 assuming each processMessage indicates it can't handle this
* message by returning false or NOT_HANDLED.</p>
*
* <p>Now assume mS5.processMessage receives a message it can handle, and during
* the handling determines the machine should change states. It could call
* transitionTo(mS4) and return true or HANDLED. Immediately after returning from
* processMessage the state machine runtime will find the common parent,
* which is mP1. It will then call mS5.exit, mS1.exit, mS2.enter and then
* mS4.enter. The new list of active states is mP0, mP1, mS2 and mS4. So
* when the next message is received mS4.processMessage will be invoked.
解释如下:
假设目前的状态机是如上图所示.
1.当目前的状态机是mS5时,收到消息处理的顺序为mS5,mS1, mP1, mP0而且是当方法processMessage 返回的是NOT_HANDLED消息才能被上一层继续处理.
而且处理的时候应该当改变相应的状态并返回真.比如mS5收到消息后转换相应的状态到mS4并返回HANDLED.
2.转换到mS4时,状态机将会发现mS5和mS4同样的父层级是mP1,接着状态机会调用mS5的exit方法,mS1的exit方法.调用mS2的enter和mS4的enter方法。
这个时候新的激活状态结构为mP0,mP1,mS2,mS4,而接收消息会被mS4优先处理
举列说明:
Android-7.1(4.4基本一样)代码的WIFI模块中:
在WifiController文件中的的状态机 "部分结构" 如下[其中mApStaDisabledState为状态机初始状态]:
mDefaultState.....................................................
| |
mApStaDisabledState mStaEnabledState.....................
|
mDeviceActiveState
|
DeviceActiveHighPerfState
简单表示如下:
mP0(mDefaultState)
/ \
(mStaEnabledState)mP1 mS0(mApStaDisabledState)
/ \
mS1(mDeviceActiveState)
当前状态为:mP0(mDefaultState),mS0(mApStaDisabledState)
经过下面操作后状态为:mP0,mP1(mStaEnabledState),mS1(mDeviceActiveState)而且会调用mP1(mStaEnabledState)的enter方法再调用mS1(mDeviceActiveState)的enter方法
操作步骤:打开设置中的wifi开关在WifiController文件中的状态机会发生变化如下(因为mApStaDisabledState状态机是初始状态首先收到信息并进行相应的逻辑处理):
mApStaDisabledState状态机优先处理消息
{
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (mDeviceIdle == false) {
checkLocksAndTransitionWhenDeviceActive();//假设走个方法"当前设备是活动使用状态"
} else {
checkLocksAndTransitionWhenDeviceIdle();
}
break;
return HANDLED
}
private void checkLocksAndTransitionWhenDeviceActive() {
if (mWifiLockManager.getStrongestLockMode() == WIFI_MODE_FULL_HIGH_PERF) {
// It is possible for the screen to be off while the device is
// is active (mIdleMillis), so we need the high-perf mode
// otherwise powersaving mode will be turned on.
transitionTo(mDeviceActiveHighPerfState);//为mDeviceActiveState的子层级
} else {
transitionTo(mDeviceActiveState);//假设走这个方法
}
}
说明:这个时候mApStaDisabledState状态会处理完消息并转换成mDeviceActiveState状态
根据状态机原理会调用mDeviceActiveState的父级mStaEnabledState的enter方法和mDeviceActiveState的enter方法
mStaEnabledState
{
@Override
public void enter() {
mWifiStateMachine.setSupplicantRunning(true);
//上面这个方法会调用sendMessage(CMD_START_SUPPLICANT)在WifiStateMachine的状态机内部进行消息传递
//而WifiStateMachine的默认初始状态为InitialState处理此消息调用wifiNative.loadDriver
//继续调用mWifiNative.startHal方法和mWifiNative.startSupplicant 就把wifi驱动和hal层和wpa_supplicant建立起来可以进行下一步连接wifi
//而WifiStateMachine从InitialState状态变为transitionTo(mSupplicantStartingState)状态
}
}
说明:这样通过状态机有效的管理Wifi的驱动被加载,HAL层和关键模块wpa_supplicant也被启动.下一步wifi的连接动作就可以进行了
*在WifiController的状态机变为*:
mDefaultState---mStaEnabledState---mDeviceActiveState
这样状态机的例子就结束了.应该可以看出状态机如果理解对代码就比较好梳理.
不过上面逻辑已经到WifiStateMachine的setSupplicantRunning了趁热继续详细分析一下
WifiStateMachine::setSupplicantRunning
public void setSupplicantRunning(boolean enable) {
if (enable) {
WifiNative.setApMode(false);
sendMessage(CMD_START_SUPPLICANT);//发送消息 此时WifiStateMachine的初始状态机InitialState会处理此消息
}
}
InitialState{
@Override
public boolean processMessage(Message message) {
logStateAndMessage(message, this);
switch (message.what) {
case CMD_START_SUPPLICANT:
//见上面简单描述
mWifiNative.loadDriver()
mNwService.wifiFirmwareReload(mInterfaceName, "STA");
mWifiNative.startHal()
mWifiNative.startSupplicant(mP2pSupported)
mWifiMonitor.startMonitoring(mInterfaceName);//启动监听器状态机
transitionTo(mSupplicantStartingState)//转换状态
}
*在WifiStateMachine的状态机变为*:
mDefaultState---mSupplicantStartingState
看下关键代码:
WifiMonitor::startMonitoring
{
mWifiNative.connectToSupplicant();//启动supplicant后会接着启动MonitorThread线程调用WifiNative.waitForEvent 来监听事件
//事件调用方法比如handleSupplicantStateChange或者handleDriverEvent
sendMessage(iface, SUP_CONNECTION_EVENT)
}
又因为在WifiStateMachine中通过如下方法注册了
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_CONNECTION_EVENT, getHandler())
所以WifiStateMachine的mSupplicantStartingState会处理此消息
mSupplicantStartingState
{
@Override
public boolean processMessage(Message message) {
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
setWifiState(WIFI_STATE_ENABLED);
mWifiInfo.setMacAddress(mWifiNative.getMacAddress());//设置MAC地址
transitionTo(mDriverStartedState);//转换状态到mDriverStartedState
}
}
*在WifiStateMachine的状态机又变为*
mDefaultState---mSupplicantStartedState(因为是mDriverStartedState的父层级)---mDriverStartedState
继续趁热分析
mSupplicantStartedState
{
@Override
public void enter() {
mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000)//设置扫描周期会保存到wpa_supplicant相应的结构体中
}
}
mDriverStartedState
{
@Override
public void enter() {
transitionTo(mDisconnectedState);/转换到mDisconnectedState状态
}
}
*在WifiStateMachine的状态机又变为*
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState(因为是父层级)---mDisconnectedState
mDisconnectedState
{
@Override
public void enter() {
//执行300S后周期搜索无线网络
//<integer translatable="false" name="config_wifi_no_network_periodic_scan_interval">300000</integer>
if (mNoNetworksPeriodicScan != 0 && !mP2pConnected.get()
&& mWifiConfigManager.getSavedNetworks().size() == 0) {
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);
}
}
@Override
public boolean processMessage(Message message) {
boolean ret = HANDLED;
switch (message.what) {
case CMD_NO_NETWORKS_PERIODIC_SCAN:
if (mP2pConnected.get()) break;
if (mNoNetworksPeriodicScan != 0 && message.arg1 == mPeriodicScanToken &&
mWifiConfigManager.getSavedNetworks().size() == 0) {
startScan(UNKNOWN_SCAN_SOURCE, -1, null, WIFI_WORK_SOURCE);//开始搜索网络
sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);//重新执行搜索网络
}
break;
}
----------------"以上逻辑4.4与7.1代码 大同小异 相差不是很大 状态机基本一样"-----------
----------------"开启supplicant后要进行扫描网络接入点"----------------
1.余下为搜索网络相关逻辑
由于7.1针对搜索网络添加了新的状态机机制所以这部分和4.4有比较大的区别
packages.SettingsLib.wifi.WifiTracker::mReceiver监听到此广播
{
WifiManager.WIFI_STATE_CHANGED_ACTION//此状态是由mSupplicantStartingState传过来
mWifiManager.startScan//最终调用接口启动扫描
}
而界面上的更新接入点是在WifiTracker::updateAccessPoints实现
由上面可知当前状态是由mDriverStartedState启动扫描
WifiStateMachine.DriverStartedState
{
case CMD_START_SCAN:
handleScanRequest(message);
break;
}
接着调用WifiStateMachine.startScanNative
{
mWifiScanner.startScan
}
在frameowkrs.base.wifi.WifiScanner.startScan
{
mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams)
}
-------扫描服务介绍----
1.WifiScanningServiceImpl extends IWifiScanner.Stub
2.在FrameworkFacade.makeWifiScanner{
new WifiScanner(context, IWifiScanner.Stub.asInterface(
getService(Context.WIFI_SCANNING_SERVICE)), looper)
}
//把WifiScanningServiceImpl保存到WifiScanner的内部通过AsyncChannel将两者的ServiceHandler和ClientHandler连接起来
//所以WifiScanner.startScan(CMD_START_SINGLE_SCAN)消息将在WifiScanningServiceImpl实现
WifiScanningServiceImpl
{
case WifiScanner.CMD_START_SINGLE_SCAN:
case WifiScanner.CMD_STOP_SINGLE_SCAN:
mSingleScanStateMachine.sendMessage(Message.obtain(msg));
}
WifiScanningServiceImpl.SingleScanStateMachine.DriverStartedState
{
case WifiScanner.CMD_START_SINGLE_SCAN:
mWifiMetrics.incrementOneshotScanCount();
tryToStartNewScan
}
WifiScanningServiceImpl的tryToStartNewScan方法
{
mScannerImpl.startSingleScan//通过WifiScannerImpl去执行搜索
transitionTo(mScanningState);//转换状态
}
而WifiScanningService的构造方法传递WifiScannerImpl的实现类
{
mImpl = new WifiScanningServiceImpl(getContext(), mHandlerThread.getLooper(),
WifiScannerImpl.DEFAULT_FACTORY, BatteryStatsService.getService(),
WifiInjector.getInstance());
//工厂类是HalWifiScannerImpl或者SupplicantWifiScannerImpl这里走SupplicantWifiScannerImpl
}
最终会调用SupplicantWifiScannerImpl类 并调用mWifiNative.scan进行扫描网络热入点
而在WifiMonitor.handleEvent
{
case SCAN_RESULTS:
sendMessage(iface, SCAN_RESULTS_EVENT);
break;
}
又在SupplicantWifiScannerImpl.SupplicantWifiScannerImpl中进行注册
{
WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(),
WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler);
}
又在WifiStateMachine中进行注册
{
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_RESULTS_EVENT, getHandler());
}
SupplicantWifiScannerImpl
{
case WifiMonitor.SCAN_RESULTS_EVENT:
mAlarmManager.cancel(mScanTimeoutListener);
pollLatestScanData();
processPendingScans();
break;
}
会执行SupplicantWifiScannerImpl.pollLatestScanData方法
{
mWifiNative.getScanResults
}
而WifiScanningServiceImpl:onScanStatus
{
sendMessage(CMD_SCAN_RESULTS_AVAILABLE)
}
//由前面而知在扫描之后会入ScanningState状态所以事件消息将会由此处理
在WifiScanningServiceImpl.WifiSingleScanStateMachine.ScanningState
{
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_SCAN_RESULTS_AVAILABLE:
reportScanResults(mScannerImpl.getLatestSingleScanResults());//调用SupplicantWifiScannerImpl
mActiveScans.clear();
transitionTo(mIdleState);//转换状态
}
回调到WifiScanner
{
case CMD_SCAN_RESULT :
((ScanListener) listener).onResults(((ParcelableScanData) msg.obj).getResults());
return;
}
在看WifiStateMachine.SupplicantStartedState中对事件的处理
{
case WifiMonitor.SCAN_RESULTS_EVENT:
case WifiMonitor.SCAN_FAILED_EVENT:
maybeRegisterNetworkFactory(); // Make sure our NetworkFactory is registered
setScanResults();
//如上方法会调用ArrayList<ScanDetail> scanResults = mWifiNative.getScanResults()供WifiServiceImpl调用
if (mIsFullScanOngoing || mSendScanResultsBroadcast) {
/* Just updated results from full scan, let apps know about this */
boolean scanSucceeded = message.what == WifiMonitor.SCAN_RESULTS_EVENT;
sendScanResultsAvailableBroadcast(scanSucceeded);//发送广播
}
}
2.------------4.4的扫描流程--------------------
packages.apps.Settings.WifiSettings文件
{
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//监听广播如mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
handleEvent(context, intent);
}
};
状态上来后会调用WifiManager.startScan
}
WifiStateMachine.DriverStartedState
{
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP)
}
WifiStateMachine.startScanNative
{
mWifiNative.scan(type)
}
事件上传WifiMonitor.handleEvent
{
case SCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
break;
}
在WifiStateMachine.SupplicantStartedState
{
case WifiMonitor.SCAN_RESULTS_EVENT:
setScanResults();
sendScanResultsAvailableBroadcast();
mScanResultIsPending = false;
break;
}
在WifiStateMachine.setScanResults
{
mWifiNative.scanResults并保存在mScanResults中
}
而WifiStateMachine的syncGetScanResultsList可以提供给wifiManager使用
至此4.4和7.1搜索网络逻辑分析完毕其中7.1逻辑较为复杂而4.4比较简洁
-----------------------------------------------------------------------
2.搜索完网络 通过wifiManager.connect进行网络连接
注意:连接网络消息CONNECT_NETWORK将在mConnectModeState中进行处理
-----7.1----连接逻辑
WifiServiceImpl.ClientHandler
{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case WifiManager.CONNECT_NETWORK:
mWifiStateMachine.sendMessage(Message.obtain(msg));
}
}
}
由上可知状态为ConnectModeState
{
case WifiManager.CONNECT_NETWORK:
mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ true,
message.sendingUid) && mWifiNative.reconnect()
}
连接事件在ConnectModeState
{
case WifiMonitor.NETWORK_CONNECTION_EVENT:
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);//转换状态
}
:此时WifiStateMachine状态为
mDefaultState---mSupplicantStartedState---mDriverStartedState---mL2ConnectedState---mObtainingIpState
在mObtainingIpState.enter
{
final IpManager.ProvisioningConfiguration prov =
mIpManager.buildProvisioningConfiguration()
.withPreDhcpAction()
.withApfCapabilities(mWifiNative.getApfCapabilities())
.build();
mIpManager.startProvisioning(prov)
}
//又WifiStateMachine里面对IpManager实例化的时候有相应的回调类IpManagerCallback将被IpManager回调相应的方法并发送消息.
//相应的状态机会拦截相应的消息
在IpManager的RunningState.enter方法内
{
startIPv6();
startIPv4();
}
在L2ConnectedState的状态的处理消息方法中
{
case CMD_IP_CONFIGURATION_SUCCESSFUL:
handleSuccessfulIpConfiguration();
reportConnectionAttemptEnd(
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE);
sendConnectedState();
transitionTo(mConnectedState);
break;
}
此时进入连接状态
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState---mL2ConnectedState---mConnectedState
-----------------------------------------------------------------------------------------------------------------------------------
----4.4---连接逻辑
ConnectModeState.
{
case WifiManager.CONNECT_NETWORK
if (mWifiConfigStore.selectNetwork(netId) && mWifiNative.reconnect()) {
transitionTo(mDisconnectingState);
}
}
ObtainingIpState.enter
{
startDhcp();
}
//接着到VerifyingLinkState状态最后到CaptivePortalCheckState认证状态
//在此状态根据CMD_CAPTIVE_CHECK_COMPLETE消息调整到连接状态transitionTo(mConnectedState)
此时进入连接状态
mDefaultState---mSupplicantStartedState---mDriverStartedState---mConnectModeState---mL2ConnectedState---mConnectedState
--------------------------------------------------------------------------------------------------------------------------------
阅读全文
0 2
- [android-wifi]开启,扫描与连接相关流程
- Android -- Wifi扫描流程分析
- Android -- Wifi扫描流程分析
- Android wifi扫描及连接
- android WiFi扫描并连接
- android WiFi扫描并连接
- Android扫描wifi二维码自动连接wifi
- Android扫描wifi二维码自动连接wifi
- WIFI开启扫描热点
- Android wifi相关添加流程
- Android -- Wifi连接流程分析
- Android -- Wifi连接流程分析
- Android -- Wifi连接流程分析
- Android WiFi 扫描和连接热点
- Android WiFi 扫描和连接热点
- Android WiFi 扫描和连接热点
- Android WiFi 扫描和连接热点
- android wifi操作(扫描和连接)
- HDU-2017 多校训练赛1-1002-Balala Power!
- Linux服务器上监控网络带宽的18个常用命令
- js全国城市三级联动
- nyoj括号配对问题
- 数据结构之线性表
- [android-wifi]开启,扫描与连接相关流程
- vue上传图片组件编写
- 对hibernate List一对多中list-index的理解
- Spark成长之路(11)-ngram
- 最令程序员沮丧的 10 件事
- 一篇彻底学会常用的sql语句
- 古典概型题目 python练习
- K3后台修改采购模块(采购订单、收料送检单、外购入库单)供应商信息
- 字节流