(九十三) Android O 连接WiFi AP流程梳理续——保存网络
发布日期:2021-06-30 15:25:21 浏览次数:2 分类:技术文章

本文共 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;        }        ArrayList
sharedConfigurations = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:(九十四) Android O 连接WiFi AP流程梳理续——连接网络
下一篇:(九十二) Android O WiFi热点 开启流程梳理续

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月22日 18时56分10秒