一 前言
在前面一篇简单地说明了用户在WifiSettings界面选择一个AP显示配置AP参数的对话框的过程,当用户在对话框中选择好加密方式和输入密码之后,点击确定按钮,Android就会去连接这个AP,这一篇将主要分析连接AP的过程(AP参数没有保存的这种情况)。
二 图示调用流程
为了调用流程图更简洁明了,整个调用流程图示将以一条主线走下去,对于其它的一些方法调用将不在流程图显示,更详细更细节地可以看下面的代码具体流程。
三 代码具体流程
1 应用层
1.1 packages/apps/settings/WifiSettings.java
当填写完配置相关参数后,点击确定按钮会监听到操作。
@Override
public void onSubmit(WifiDialog dialog) {
if (mDialog != null) {
submit(mDialog.getController());
}
}
看submit。
/* package */ void submit(WifiConfigController configController) {
final WifiConfiguration config = configController.getConfig();
if (config == null) {
if (mSelectedAccessPoint != null
&& mSelectedAccessPoint.isSaved()) {
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */);
}
} else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) {
mWifiManager.save(config, mSaveListener);
} else {
mWifiManager.save(config, mSaveListener);
if (mSelectedAccessPoint != null) { // Not an "Add network"
connect(config, false /* isSavedNetwork */);
}
}
mWifiTracker.resumeScanning();
}
看mWifiManager.save。
2 框架层
2.1 frameworks/base/wifi/java/android/net/wifi/WifiManager.java
/**
* Save the given network to the list of configured networks for the
* foreground user. If the network already exists, the configuration
* is updated. Any new network is enabled by default.
*
* For a new network, this function is used instead of a
* sequence of addNetwork() and enableNetwork().
*
* For an existing network, it accomplishes the task of updateNetwork()
*
* This API will cause reconnect if the crecdentials of the current active
* connection has been changed.
*
* @param config the set of variables that describe the configuration,
* contained in a {@link WifiConfiguration} object.
* @param listener for callbacks on success or failure. Can be null.
* @throws IllegalStateException if the WifiManager instance needs to be
* initialized again
* @hide
*/
public void save(WifiConfiguration config, ActionListener listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config);
通过异步通道AsyncChannel来调用WifiServiceImpl的ClientHandler来处理SAVE_NETWORK消息。
2.2 frameworks/base/wifi/java/android/net/wifi/WifiServiceImpl.java
/**
* Handles client connections
*/
private class ClientHandler extends WifiHandler {
ClientHandler(String tag, Looper looper) {
super(tag, looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
...
case WifiManager.SAVE_NETWORK: {
if (checkChangePermissionAndReplyIfNotAuthorized(
msg, WifiManager.SAVE_NETWORK_FAILED)) {
WifiConfiguration config = (WifiConfiguration) msg.obj;
int networkId = msg.arg1;
Slog.d(TAG, "SAVE"
+ " nid=" + Integer.toString(networkId)
+ " config=" + config
+ " uid=" + msg.sendingUid
+ " name="
+ mContext.getPackageManager().getNameForUid(msg.sendingUid));
if (config != null) {
/* Command is forwarded to state machine */
mWifiStateMachine.sendMessage(Message.obtain(msg));
} else {
Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED,
WifiManager.INVALID_ARGS);
}
}
break;
}
...
}
}
...
}
mWifiStateMachine.sendMessage发送消息直接让WifiStateMachine状态机来处理。
2.3 frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper,
UserManager userManager, WifiInjector wifiInjector,
BackupManagerProxy backupManagerProxy, WifiCountryCode countryCode,
WifiNative wifiNative,
WrongPasswordNotifier wrongPasswordNotifier,
SarManager sarManager) {
...
// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
addState(mConnectModeState, mDefaultState);
addState(mL2ConnectedState, mConnectModeState);
addState(mObtainingIpState, mL2ConnectedState);
addState(mConnectedState, mL2ConnectedState);
addState(mRoamingState, mL2ConnectedState);
addState(mDisconnectingState, mConnectModeS