Android -- Wifi的forget()操作
我们在处理某个Wifi连接时,有时会需要忘掉当前连接的密码信息。执行这项操作,我们需要调用WifiManager::forget()函数:
从函数介绍可知,调用forget()函数,当前网络连接的配置信息就会从wpa_supplicant.conf中删掉;之后这个网络就不会有自动重连的动作,因为conf文件中已经没有该网络的配置信息。
- /**
- * Delete the network in the supplicant config.
- *
- * This function is used instead of a sequence of removeNetwork()
- * and saveConfiguration().
- *
- * @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 forget(int netId, ActionListener listener) {
- if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative");
- validateChannel();
- sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener));
- }
跟踪FORGET_NETWORK消息,WifiServiceImpl::ClientHandler处理:
简单地将该消息转发给WifiStateMachine。此时Wifi是连接状态,WifiStateMachine中当前状态是ConnectedState,它的父状态ConnectModeState处理:
mWifiConfigStore.forgetNetwork():
根据传入的当前网络的netId,分别调用WifiNative的removeNetwork()、saveConfig()方法删除conf文件的配置信息并进行保存;执行完成后,forget()函数结束了。通过代码我们发现,执行forget()函数并不会引起WifiStateMachine中状态的切换。
- case WifiManager.FORGET_NETWORK:
- if (isOwner(msg.sendingUid)) {
- mWifiStateMachine.sendMessage(Message.obtain(msg));
- } else {
- Slog.e(TAG, "Forget is not authorized for user");
- replyFailed(msg, WifiManager.FORGET_NETWORK_FAILED,
- WifiManager.NOT_AUTHORIZED);
- }
- break;
- case WifiManager.FORGET_NETWORK:
- // Debug only, remember last configuration that was forgotten
- WifiConfiguration toRemove
- = mWifiConfigStore.getWifiConfiguration(message.arg1);
- if (toRemove == null) {
- lastForgetConfigurationAttempt = null;
- } else {
- lastForgetConfigurationAttempt = new WifiConfiguration(toRemove);
- }
- // check that the caller owns this network
- netId = message.arg1;
- if (!mWifiConfigStore.canModifyNetwork(message.sendingUid, netId,
- /* onlyAnnotate */ false)) {
- logw("Not authorized to forget network "
- + " cnid=" + netId
- + " uid=" + message.sendingUid);
- replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
- WifiManager.NOT_AUTHORIZED);
- break;
- }
- if (mWifiConfigStore.forgetNetwork(message.arg1)) {
- replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED);
- broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_FORGOT,
- (WifiConfiguration) message.obj);
- } else {
- loge("Failed to forget network");
- replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
- WifiManager.ERROR);
- }
- break;
- /**
- * Forget the specified network and save config
- *
- * @param netId network to forget
- * @return {@code true} if it succeeds, {@code false} otherwise
- */
- boolean forgetNetwork(int netId) {
- if (showNetworks) localLog("forgetNetwork", netId);
- WifiConfiguration config = mConfiguredNetworks.get(netId);
- boolean remove = removeConfigAndSendBroadcastIfNeeded(netId);
- if (!remove) {
- //success but we dont want to remove the network from supplicant conf file
- return true;
- }
- if (mWifiNative.removeNetwork(netId)) {
- if (config != null && config.isPasspoint()) {
- writePasspointConfigs(config.FQDN, null);
- }
- mWifiNative.saveConfig();
- writeKnownNetworkHistory(true);
- return true;
- } else {
- loge("Failed to remove network " + netId);
- return false;
- }
- }