本文共 35344 字,大约阅读时间需要 117 分钟。
前言: 之前在 梳理连接流程梳理到SupplicantStaNetworkHal 然后没梳理的下去,现在继续梳理下。
之前梳理的时序图
1.流程梳理-保存网络
现在重新梳理了下流程发现漏了些细节,完善一下。
1.1 Settings
/* 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(); }
在第一次连接WiFi的时候,我们一般先输入密码,然后连接,之后的过程是先调用WifiManager保存该网络,可以观察到我们连接过的网络都会在已保存网络里有所显示,之后才是连接网络。而其中的参数WifiConfiguration是从WifiConfigController中获取的,这其实就是将用户输入转换为对象。
/* package */ WifiConfiguration getConfig() { if (mMode == WifiConfigUiBase.MODE_VIEW) { return null; } WifiConfiguration config = new WifiConfiguration(); if (mAccessPoint == null) { config.SSID = AccessPoint.convertToQuotedString( mSsidView.getText().toString()); // If the user adds a network manually, assume that it is hidden. config.hiddenSSID = true; } else if (!mAccessPoint.isSaved()) { config.SSID = AccessPoint.convertToQuotedString( mAccessPoint.getSsidStr()); } else { config.networkId = mAccessPoint.getConfig().networkId; config.hiddenSSID = mAccessPoint.getConfig().hiddenSSID; } config.shared = mSharedCheckBox.isChecked(); switch (mAccessPointSecurity) { case AccessPoint.SECURITY_NONE: config.allowedKeyManagement.set(KeyMgmt.NONE); break; case AccessPoint.SECURITY_WEP:... break; case AccessPoint.SECURITY_PSK: config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); if (mPasswordView.length() != 0) { String password = mPasswordView.getText().toString(); if (password.matches("[0-9A-Fa-f]{64}")) { config.preSharedKey = password; } else { config.preSharedKey = '"' + password + '"'; } } break; case AccessPoint.SECURITY_EAP: ... break; default: return null; } config.setIpConfiguration( new IpConfiguration(mIpAssignment, mProxySettings, mStaticIpConfiguration, mHttpProxy)); return config; }
先添加的wpa/wpa2类型的网络 config一般就初始化SSID、hiddenSSID、shared、allowedKeyManagement、preSharedKey和setIpConfiguration。
1.2 WifiManager
/** * 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(), enableNetwork() and saveConfiguration(). * * For an existing network, it accomplishes the task of updateNetwork() * 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 save(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config); }
从注释我们看到了save是一系列方法的封装。
对于新网络:save完成addNetwork(), enableNetwork() and saveConfiguration()
对于已保存网络:save完成updateNetwork() and saveConfiguration()
1.3 WifiServiceImpl
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) + " uid=" + msg.sendingUid + " name=" + mContext.getPackageManager().getNameForUid(msg.sendingUid)); if (config != null) { if (DBG) Slog.d(TAG, "Save network with config " + config); /* 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; }
1.4 WifiStateMachine
case WifiManager.SAVE_NETWORK: result = saveNetworkConfigAndSendReply(message); netId = result.getNetworkId(); if (result.isSuccess() && mWifiInfo.getNetworkId() == netId) { mWifiConnectionStatistics.numWifiManagerJoinAttempt++; if (result.hasCredentialChanged()) { config = (WifiConfiguration) message.obj; // The network credentials changed and we're connected to this network, // start a new connection with the updated credentials. logi("SAVE_NETWORK credential changed for config=" + config.configKey() + ", Reconnecting."); startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY); } else { if (result.hasProxyChanged()) { log("Reconfiguring proxy on connection"); mIpClient.setHttpProxy( getCurrentWifiConfiguration().getHttpProxy()); } if (result.hasIpChanged()) { // The current connection configuration was changed // We switched from DHCP to static or from static to DHCP, or the // static IP address has changed. log("Reconfiguring IP on connection"); // TODO(b/36576642): clear addresses and disable IPv6 // to simplify obtainingIpState. transitionTo(mObtainingIpState); } } } break;
/** * Private method to handle calling WifiConfigManager to add & enable network configs and reply * to the message from the sender of the outcome. * * @return NetworkUpdateResult with networkId of the added/updated configuration. Will return * {@link WifiConfiguration#INVALID_NETWORK_ID} in case of error. */ private NetworkUpdateResult saveNetworkConfigAndSendReply(Message message) { WifiConfiguration config = (WifiConfiguration) message.obj; if (config == null) { loge("SAVE_NETWORK with null configuration " + mSupplicantStateTracker.getSupplicantStateName() + " my state " + getCurrentState().getName()); messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid); if (!result.isSuccess()) { loge("SAVE_NETWORK adding/updating config=" + config + " failed"); messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR); return result; } if (!mWifiConfigManager.enableNetwork( result.getNetworkId(), false, message.sendingUid)) { loge("SAVE_NETWORK enabling config=" + config + " failed"); messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config); replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED); return result; }
1.5 WifiConfigManager
1.5.1 addOrUpdateNetwork
保存网络第一步:添加网络
/** * Add a network or update a network configuration to our database. * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty * network configuration. Otherwise, the networkId should refer to an existing configuration. * * @param config provided WifiConfiguration object. * @param uid UID of the app requesting the network addition/modification. * @return NetworkUpdateResult object representing status of the update. */ public NetworkUpdateResult addOrUpdateNetwork(WifiConfiguration config, int uid) { if (!doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } if (config == null) { Log.e(TAG, "Cannot add/update network with null config"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } if (mPendingStoreRead) { Log.e(TAG, "Cannot add/update network before store is read!"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } NetworkUpdateResult result = addOrUpdateNetworkInternal(config, uid); if (!result.isSuccess()) { Log.e(TAG, "Failed to add/update network " + config.getPrintableSsid()); return result; } WifiConfiguration newConfig = getInternalConfiguredNetwork(result.getNetworkId()); sendConfiguredNetworkChangedBroadcast( newConfig, result.isNewNetwork() ? WifiManager.CHANGE_REASON_ADDED : WifiManager.CHANGE_REASON_CONFIG_CHANGE); // Unless the added network is ephemeral or Passpoint, persist the network update/addition. if (!config.ephemeral && !config.isPasspoint()) { saveToStore(true); if (mListener != null) { if (result.isNewNetwork()) { mListener.onSavedNetworkAdded(newConfig.networkId); } else { mListener.onSavedNetworkUpdated(newConfig.networkId); } } } return result; }
/** * Add a network or update a network configuration to our database. * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty * network configuration. Otherwise, the networkId should refer to an existing configuration. * * @param config provided WifiConfiguration object. * @param uid UID of the app requesting the network addition/deletion. * @return NetworkUpdateResult object representing status of the update. */ private NetworkUpdateResult addOrUpdateNetworkInternal(WifiConfiguration config, int uid) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Adding/Updating network " + config.getPrintableSsid()); } WifiConfiguration newInternalConfig = null; // First check if we already have a network with the provided network id or configKey. WifiConfiguration existingInternalConfig = getInternalConfiguredNetwork(config); // No existing network found. So, potentially a network add. if (existingInternalConfig == null) { if (!WifiConfigurationUtil.validate(config, WifiConfigurationUtil.VALIDATE_FOR_ADD)) { Log.e(TAG, "Cannot add network with invalid config"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } newInternalConfig = createNewInternalWifiConfigurationFromExternal(config, uid); // Since the original config provided may have had an empty // {@link WifiConfiguration#allowedKeyMgmt} field, check again if we already have a // network with the the same configkey. existingInternalConfig = getInternalConfiguredNetwork(newInternalConfig.configKey()); } // Existing network found. So, a network update. if (existingInternalConfig != null) { if (!WifiConfigurationUtil.validate( config, WifiConfigurationUtil.VALIDATE_FOR_UPDATE)) { Log.e(TAG, "Cannot update network with invalid config"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } // Check for the app's permission before we let it update this network. if (!canModifyNetwork(existingInternalConfig, uid, DISALLOW_LOCKDOWN_CHECK_BYPASS)) { Log.e(TAG, "UID " + uid + " does not have permission to update configuration " + config.configKey()); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } newInternalConfig = updateExistingInternalWifiConfigurationFromExternal( existingInternalConfig, config, uid); } // Only add networks with proxy settings if the user has permission to if (WifiConfigurationUtil.hasProxyChanged(existingInternalConfig, newInternalConfig) && !canModifyProxySettings(uid)) { Log.e(TAG, "UID " + uid + " does not have permission to modify proxy Settings " + config.configKey() + ". Must have NETWORK_SETTINGS," + " or be device or profile owner."); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } // Update the keys for non-Passpoint enterprise networks. For Passpoint, the certificates // and keys are installed at the time the provider is installed. if (config.enterpriseConfig != null && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE && !config.isPasspoint()) { if (!(mWifiKeyStore.updateNetworkKeys(newInternalConfig, existingInternalConfig))) { return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } } boolean newNetwork = (existingInternalConfig == null); // This is needed to inform IpClient about any IP configuration changes. boolean hasIpChanged = newNetwork || WifiConfigurationUtil.hasIpChanged( existingInternalConfig, newInternalConfig); boolean hasProxyChanged = newNetwork || WifiConfigurationUtil.hasProxyChanged( existingInternalConfig, newInternalConfig); // Reset the |hasEverConnected| flag if the credential parameters changed in this update. boolean hasCredentialChanged = newNetwork || WifiConfigurationUtil.hasCredentialChanged( existingInternalConfig, newInternalConfig); if (hasCredentialChanged) { newInternalConfig.getNetworkSelectionStatus().setHasEverConnected(false); } // Add it to our internal map. This will replace any existing network configuration for // updates. try { mConfiguredNetworks.put(newInternalConfig); } catch (IllegalArgumentException e) { Log.e(TAG, "Failed to add network to config map", e); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } if (mDeletedEphemeralSSIDs.remove(config.SSID)) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Removed from ephemeral blacklist: " + config.SSID); } } // Stage the backup of the SettingsProvider package which backs this up. mBackupManagerProxy.notifyDataChanged(); NetworkUpdateResult result = new NetworkUpdateResult(hasIpChanged, hasProxyChanged, hasCredentialChanged); result.setIsNewNetwork(newNetwork); result.setNetworkId(newInternalConfig.networkId); localLog("addOrUpdateNetworkInternal: added/updated config." + " netId=" + newInternalConfig.networkId + " configKey=" + newInternalConfig.configKey() + " uid=" + Integer.toString(newInternalConfig.creatorUid) + " name=" + newInternalConfig.creatorName); return result; }
1)这次梳理的保存网络是针对新网络添加,新网络添加会对Settings传来的如下参数进行校验,这和之前梳理的是正好对上的。
public static boolean validate(WifiConfiguration config, boolean isAdd) { if (!validateSsid(config.SSID, isAdd)) { return false; } if (!validateKeyMgmt(config.allowedKeyManagement)) { return false; } if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK) && !validatePsk(config.preSharedKey, isAdd)) { return false; } if (!validateIpConfiguration(config.getIpConfiguration())) { return false; } // TBD: Validate some enterprise params as well in the future here. return true; }
2)校验成功以后会将外部配置转换为内部配置
/** * Create a new internal WifiConfiguration object by copying over parameters from the provided * external configuration and set defaults for the appropriate parameters. * * @param externalConfig WifiConfiguration object provided from the external API. * @return New WifiConfiguration object with parameters merged from the provided external * configuration. */ private WifiConfiguration createNewInternalWifiConfigurationFromExternal( WifiConfiguration externalConfig, int uid) { WifiConfiguration newInternalConfig = new WifiConfiguration(); // First allocate a new network ID for the configuration. newInternalConfig.networkId = mNextNetworkId++; // First set defaults in the new configuration created. setDefaultsInWifiConfiguration(newInternalConfig); // Copy over all the public elements from the provided configuration. mergeWithInternalWifiConfiguration(newInternalConfig, externalConfig); // Copy over the hidden configuration parameters. These are the only parameters used by // system apps to indicate some property about the network being added. // These are only copied over for network additions and ignored for network updates. newInternalConfig.requirePMF = externalConfig.requirePMF; newInternalConfig.noInternetAccessExpected = externalConfig.noInternetAccessExpected; newInternalConfig.ephemeral = externalConfig.ephemeral; newInternalConfig.useExternalScores = externalConfig.useExternalScores; newInternalConfig.shared = externalConfig.shared; // Add debug information for network addition. newInternalConfig.creatorUid = newInternalConfig.lastUpdateUid = uid; newInternalConfig.creatorName = newInternalConfig.lastUpdateName = mContext.getPackageManager().getNameForUid(uid); newInternalConfig.creationTime = newInternalConfig.updateTime = createDebugTimeStampString(mClock.getWallClockMillis()); return newInternalConfig; }
3)初始化NetworkUpdateResult,由于是newNetwork,所以以下参数都是true。
boolean newNetwork = (existingInternalConfig == null); // This is needed to inform IpClient about any IP configuration changes. boolean hasIpChanged = newNetwork || WifiConfigurationUtil.hasIpChanged( existingInternalConfig, newInternalConfig); boolean hasProxyChanged = newNetwork || WifiConfigurationUtil.hasProxyChanged( existingInternalConfig, newInternalConfig); // Reset the |hasEverConnected| flag if the credential parameters changed in this update. boolean hasCredentialChanged = newNetwork || WifiConfigurationUtil.hasCredentialChanged( existingInternalConfig, newInternalConfig); if (hasCredentialChanged) { newInternalConfig.getNetworkSelectionStatus().setHasEverConnected(false); } // Add it to our internal map. This will replace any existing network configuration for // updates. try { mConfiguredNetworks.put(newInternalConfig); } catch (IllegalArgumentException e) { Log.e(TAG, "Failed to add network to config map", e); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } if (mDeletedEphemeralSSIDs.remove(config.SSID)) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Removed from ephemeral blacklist: " + config.SSID); } } // Stage the backup of the SettingsProvider package which backs this up. mBackupManagerProxy.notifyDataChanged(); NetworkUpdateResult result = new NetworkUpdateResult(hasIpChanged, hasProxyChanged, hasCredentialChanged); result.setIsNewNetwork(newNetwork); result.setNetworkId(newInternalConfig.networkId); localLog("addOrUpdateNetworkInternal: added/updated config." + " netId=" + newInternalConfig.networkId + " configKey=" + newInternalConfig.configKey() + " uid=" + Integer.toString(newInternalConfig.creatorUid) + " name=" + newInternalConfig.creatorName);
4)保存数据
mWifiConfigStore.registerStoreData(mNetworkListStoreData); mWifiConfigStore.registerStoreData(mDeletedEphemeralSsidsStoreData); // Unless the added network is ephemeral or Passpoint, persist the network update/addition. if (!config.ephemeral && !config.isPasspoint()) { saveToStore(true); if (mListener != null) { if (result.isNewNetwork()) { mListener.onSavedNetworkAdded(newConfig.networkId); } else { mListener.onSavedNetworkUpdated(newConfig.networkId); } } } /** * Save the current snapshot of the in-memory lists to the config store. * * @param forceWrite Whether the write needs to be forced or not. * @return Whether the write was successful or not, this is applicable only for force writes. */ public boolean saveToStore(boolean forceWrite) { if (mPendingStoreRead) { Log.e(TAG, "Cannot save to store before store is read!"); return false; } ArrayListsharedConfigurations = new ArrayList<>(); ArrayList userConfigurations = new ArrayList<>(); // List of network IDs for legacy Passpoint configuration to be removed. List legacyPasspointNetId = new ArrayList<>(); for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) { // Ignore ephemeral networks and non-legacy Passpoint configurations. if (config.ephemeral || (config.isPasspoint() && !config.isLegacyPasspointConfig)) { continue; } // Migrate the legacy Passpoint configurations owned by the current user to // {@link PasspointManager}. if (config.isLegacyPasspointConfig && WifiConfigurationUtil.doesUidBelongToAnyProfile( config.creatorUid, mUserManager.getProfiles(mCurrentUserId))) { legacyPasspointNetId.add(config.networkId); // Migrate the legacy Passpoint configuration and add it to PasspointManager. if (!PasspointManager.addLegacyPasspointConfig(config)) { Log.e(TAG, "Failed to migrate legacy Passpoint config: " + config.FQDN); } // This will prevent adding |config| to the |sharedConfigurations|. continue; } // We push all shared networks & private networks not belonging to the current // user to the shared store. Ideally, private networks for other users should // not even be in memory, // But, this logic is in place to deal with store migration from N to O // because all networks were previously stored in a central file. We cannot // write these private networks to the user specific store until the corresponding // user logs in. if (config.shared || !WifiConfigurationUtil.doesUidBelongToAnyProfile( config.creatorUid, mUserManager.getProfiles(mCurrentUserId))) { sharedConfigurations.add(config); } else { userConfigurations.add(config); } } // Remove the configurations for migrated Passpoint configurations. for (int networkId : legacyPasspointNetId) { mConfiguredNetworks.remove(networkId); } // Setup store data for write. mNetworkListStoreData.setSharedConfigurations(sharedConfigurations); mNetworkListStoreData.setUserConfigurations(userConfigurations); mDeletedEphemeralSsidsStoreData.setSsidList(mDeletedEphemeralSSIDs); try { mWifiConfigStore.write(forceWrite); } catch (IOException e) { Log.wtf(TAG, "Writing to store failed. Saved networks maybe lost!", e); return false; } catch (XmlPullParserException e) { Log.wtf(TAG, "XML serialization for store failed. Saved networks maybe lost!", e); return false; } return true; }
简单看了下是以xml的形式保存下WiFi的属性配置。而xml最初是由WifiInjector初始化时创建的
WifiInjector.java mWifiConfigStore = new WifiConfigStore( mContext, wifiStateMachineLooper, mClock, WifiConfigStore.createSharedFile()); // Legacy config store DelayedDiskWrite writer = new DelayedDiskWrite(); mIpConfigStore = new IpConfigStore(writer); // Config Manager mWifiConfigManager = new WifiConfigManager(mContext, mClock, UserManager.get(mContext), TelephonyManager.from(mContext), mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil, mWifiPermissionsWrapper, new NetworkListStoreData(mContext), new DeletedEphemeralSsidsStoreData());WifiConfigStore.java private static StoreFile createFile(File storeBaseDir) { File storeDir = new File(storeBaseDir, STORE_DIRECTORY_NAME); if (!storeDir.exists()) { if (!storeDir.mkdir()) { Log.w(TAG, "Could not create store directory " + storeDir); } } return new StoreFile(new File(storeDir, STORE_FILE_NAME)); } /** * Create a new instance of the shared store file. * * @return new instance of the store file or null if the directory cannot be created. */ public static StoreFile createSharedFile() { return createFile(Environment.getDataMiscDirectory()); } /** * Config store file name for both shared & user specific stores. */ private static final String STORE_FILE_NAME = "WifiConfigStore.xml"; /** * Directory to store the config store files in. */ private static final String STORE_DIRECTORY_NAME = "wifi";
应该是在/data/misc/wifi/WifiConfigStore.xml下保存了。
1.5.2 enableNetwork
/** * Enable a network using the public {@link WifiManager#enableNetwork(int, boolean)} API. * * @param networkId network ID of the network that needs the update. * @param disableOthers Whether to disable all other networks or not. This is used to indicate * that the app requested connection to a specific network. * @param uid uid of the app requesting the update. * @return true if it succeeds, false otherwise */ public boolean enableNetwork(int networkId, boolean disableOthers, int uid) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Enabling network " + networkId + " (disableOthers " + disableOthers + ")"); } if (!doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return false; } WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return false; } if (!canModifyNetwork(config, uid, DISALLOW_LOCKDOWN_CHECK_BYPASS)) { Log.e(TAG, "UID " + uid + " does not have permission to update configuration " + config.configKey()); return false; } if (!updateNetworkSelectionStatus( networkId, WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE)) { return false; } if (disableOthers) { setLastSelectedNetwork(networkId); } saveToStore(true); return true; }
/** * Update a network's status (both internal and public) according to the update reason and * its current state. * * Each network has 2 status: * 1. NetworkSelectionStatus: This is internal selection status of the network. This is used * for temporarily disabling a network for Network Selector. * 2. Status: This is the exposed status for a network. This is mostly set by * the public API's {@link WifiManager#enableNetwork(int, boolean)} & * {@link WifiManager#disableNetwork(int)}. * * @param networkId network ID of the network that needs the update. * @param reason reason to update the network. * @return true if the input configuration has been updated, false otherwise. */ public boolean updateNetworkSelectionStatus(int networkId, int reason) { WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return false; } return updateNetworkSelectionStatus(config, reason); } /** * Update a network's status (both internal and public) according to the update reason and * its current state. * * @param config network to be updated. * @param reason reason code for update. * @return true if the input configuration has been updated, false otherwise. */ private boolean updateNetworkSelectionStatus(WifiConfiguration config, int reason) { NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus(); if (reason != NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) { networkStatus.incrementDisableReasonCounter(reason); // For network disable reasons, we should only update the status if we cross the // threshold. int disableReasonCounter = networkStatus.getDisableReasonCounter(reason); int disableReasonThreshold = NETWORK_SELECTION_DISABLE_THRESHOLD[reason]; if (disableReasonCounter < disableReasonThreshold) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Disable counter for network " + config.getPrintableSsid() + " for reason " + NetworkSelectionStatus.getNetworkDisableReasonString(reason) + " is " + networkStatus.getDisableReasonCounter(reason) + " and threshold is " + disableReasonThreshold); } return true; } } return setNetworkSelectionStatus(config, reason); } /** * Sets a network's status (both internal and public) according to the update reason and * its current state. * * This updates the network's {@link WifiConfiguration#mNetworkSelectionStatus} field and the * public {@link WifiConfiguration#status} field if the network is either enabled or * permanently disabled. * * @param config network to be updated. * @param reason reason code for update. * @return true if the input configuration has been updated, false otherwise. */ private boolean setNetworkSelectionStatus(WifiConfiguration config, int reason) { NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus(); if (reason < 0 || reason >= NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) { Log.e(TAG, "Invalid Network disable reason " + reason); return false; } if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) { setNetworkSelectionEnabled(config); setNetworkStatus(config, WifiConfiguration.Status.ENABLED); } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) { setNetworkSelectionTemporarilyDisabled(config, reason); } else { setNetworkSelectionPermanentlyDisabled(config, reason); setNetworkStatus(config, WifiConfiguration.Status.DISABLED); } localLog("setNetworkSelectionStatus: configKey=" + config.configKey() + " networkStatus=" + networkStatus.getNetworkStatusString() + " disableReason=" + networkStatus.getNetworkDisableReasonString() + " at=" + createDebugTimeStampString(mClock.getWallClockMillis())); saveToStore(false); return true; } /** * Helper method to mark a network enabled for network selection. */ private void setNetworkSelectionEnabled(WifiConfiguration config) { NetworkSelectionStatus status = config.getNetworkSelectionStatus(); status.setNetworkSelectionStatus( NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); status.setDisableTime( NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP); status.setNetworkSelectionDisableReason(NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); // Clear out all the disable reason counters. status.clearDisableReasonCounter(); if (mListener != null) mListener.onSavedNetworkEnabled(config.networkId); } /** * Helper method to set the publicly exposed status for the network and send out the network * status change broadcast. */ private void setNetworkStatus(WifiConfiguration config, int status) { config.status = status; sendConfiguredNetworkChangedBroadcast(config, WifiManager.CHANGE_REASON_CONFIG_CHANGE); }
saveConfiguration应该是对应于saveToStore?
2.总结
转载地址:https://jiatai.blog.csdn.net/article/details/82712592 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!