(兩百零七)Android Q wifi config開機加載流程

目錄

1.思路

2.流程梳理

3. 總結


1.思路

wifi config在手機中是以文件形式保存的,那開機的時候手機必然要解析文件成對應的config對象,梳理下流程

 

2.流程梳理

ClientModeImpl

                case CMD_BOOT_COMPLETED:
                    // get other services that we need to manage
                    getAdditionalWifiServiceInterfaces();
                    new MemoryStoreImpl(mContext, mWifiInjector, mWifiScoreCard).start();
                    if (!mWifiConfigManager.loadFromStore()) {
                        Log.e(TAG, "Failed to load from config store");
                    }
                    registerNetworkFactory();
                    break;

WifiConfigManager

    /**
     * Read the config store and load the in-memory lists from the store data retrieved and sends
     * out the networks changed broadcast.
     *
     * This reads all the network configurations from:
     * 1. Shared WifiConfigStore.xml
     * 2. User WifiConfigStore.xml
     *
     * @return true on success or not needed (fresh install), false otherwise.
     */
    public boolean loadFromStore() {
        // If the user unlock comes in before we load from store, which means the user store have
        // not been setup yet for the current user. Setup the user store before the read so that
        // configurations for the current user will also being loaded.
        if (mDeferredUserUnlockRead) {
            Log.i(TAG, "Handling user unlock before loading from store.");
            List<WifiConfigStore.StoreFile> userStoreFiles =
                    WifiConfigStore.createUserFiles(mCurrentUserId);
            if (userStoreFiles == null) {
                Log.wtf(TAG, "Failed to create user store files");
                return false;
            }
            mWifiConfigStore.setUserStores(userStoreFiles);
            mDeferredUserUnlockRead = false;
        }
        try {
            mWifiConfigStore.read();
        } catch (IOException e) {
            Log.wtf(TAG, "Reading from new store failed. All saved networks are lost!", e);
            return false;
        } catch (XmlPullParserException e) {
            Log.wtf(TAG, "XML deserialization of store failed. All saved networks are lost!", e);
            return false;
        }
        loadInternalData(mNetworkListSharedStoreData.getConfigurations(),
                mNetworkListUserStoreData.getConfigurations(),
                mDeletedEphemeralSsidsStoreData.getSsidToTimeMap(),
                mRandomizedMacStoreData.getMacMapping());
        return true;
    }

 

WifiConfigStore

    /**
     * API to read the store data from the config stores.
     * The method reads the user specific configurations from user specific config store and the
     * shared configurations from the shared config store.
     */
    public void read() throws XmlPullParserException, IOException {
        // Reset both share and user store data.
        resetStoreData(mSharedStore);
        if (mUserStores != null) {
            for (StoreFile userStoreFile : mUserStores) {
                resetStoreData(userStoreFile);
            }
        }

        long readStartTime = mClock.getElapsedSinceBootMillis();
        byte[] sharedDataBytes = mSharedStore.readRawData();
        deserializeData(sharedDataBytes, mSharedStore);
        if (mUserStores != null) {
            for (StoreFile userStoreFile : mUserStores) {
                byte[] userDataBytes = userStoreFile.readRawData();
                deserializeData(userDataBytes, userStoreFile);
            }
        }
        long readTime = mClock.getElapsedSinceBootMillis() - readStartTime;
        try {
            mWifiMetrics.noteWifiConfigStoreReadDuration(toIntExact(readTime));
        } catch (ArithmeticException e) {
            // Silently ignore on any overflow errors.
        }
        Log.d(TAG, "Reading from all stores completed in " + readTime + " ms.");
    }

順便看下WifiConfigStore在WifiInjector的初始化

        mWifiConfigStore = new WifiConfigStore(
                mContext, clientModeImplLooper, mClock, mWifiMetrics,
                WifiConfigStore.createSharedFile());


    /**
     * 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 @Nullable StoreFile createSharedFile() {
        return createFile(Environment.getDataMiscDirectory(), STORE_FILE_SHARED_GENERAL);
    }

    /**
     * Config store file for general shared store file.
     */
    public static final int STORE_FILE_SHARED_GENERAL = 0;

    /**
     * Helper method to create a store file instance for either the shared store or user store.
     * Note: The method creates the store directory if not already present. This may be needed for
     * user store files.
     *
     * @param storeBaseDir Base directory under which the store file is to be stored. The store file
     *                     will be at <storeBaseDir>/wifi/WifiConfigStore.xml.
     * @param fileId Identifier for the file. See {@link StoreFileId}.
     * @return new instance of the store file or null if the directory cannot be created.
     */
    private static @Nullable StoreFile createFile(File storeBaseDir, @StoreFileId int fileId) {
        File storeDir = new File(storeBaseDir, STORE_DIRECTORY_NAME);
        if (!storeDir.exists()) {
            if (!storeDir.mkdir()) {
                Log.w(TAG, "Could not create store directory " + storeDir);
                return null;
            }
        }
        return new StoreFile(new File(storeDir, STORE_ID_TO_FILE_NAME.get(fileId)), fileId);
    }



    /**
     * Directory to store the config store files in.
     */
    private static final String STORE_DIRECTORY_NAME = "wifi";

    /**
     * Config store file name for general shared store file.
     */
    private static final String STORE_FILE_NAME_SHARED_GENERAL = "WifiConfigStore.xml";

文件路徑保存爲data/misc/wifi/WifiConfigStore.xml

數據解析

    /**
     * Deserialize data from a {@link StoreFile} for all {@link StoreData} instances registered.
     *
     * @param dataBytes The data to parse
     * @param storeFile StoreFile that we read from. Will be used to retrieve the list of clients
     *                  who have data to deserialize from this file.
     *
     * @throws XmlPullParserException
     * @throws IOException
     */
    private void deserializeData(@NonNull byte[] dataBytes, @NonNull StoreFile storeFile)
            throws XmlPullParserException, IOException {
        List<StoreData> storeDataList = retrieveStoreDataListForStoreFile(storeFile);
        if (dataBytes == null) {
            indicateNoDataForStoreDatas(storeDataList);
            return;
        }
        final XmlPullParser in = Xml.newPullParser();
        final ByteArrayInputStream inputStream = new ByteArrayInputStream(dataBytes);
        in.setInput(inputStream, StandardCharsets.UTF_8.name());

        // Start parsing the XML stream.
        int rootTagDepth = in.getDepth() + 1;
        parseDocumentStartAndVersionFromXml(in);

        String[] headerName = new String[1];
        Set<StoreData> storeDatasInvoked = new HashSet<>();
        while (XmlUtil.gotoNextSectionOrEnd(in, headerName, rootTagDepth)) {
            // There can only be 1 store data matching the tag (O indicates a fatal
            // error).
            StoreData storeData = storeDataList.stream()
                    .filter(s -> s.getName().equals(headerName[0]))
                    .findAny()
                    .orElse(null);
            if (storeData == null) {
                throw new XmlPullParserException("Unknown store data: " + headerName[0]
                        + ". List of store data: " + storeDataList);
            }
            storeData.deserializeData(in, rootTagDepth + 1);
            storeDatasInvoked.add(storeData);
        }
        // Inform all the other registered store data clients that there is nothing in the store
        // for them.
        Set<StoreData> storeDatasNotInvoked = new HashSet<>(storeDataList);
        storeDatasNotInvoked.removeAll(storeDatasInvoked);
        indicateNoDataForStoreDatas(storeDatasNotInvoked);
    }

這邊流程丟了一點,對StoreData的stream用法有點看不懂。。。

先默認StoreData的實現類是NetworkListStoreData

 

看下解析方法

    @Override
    public void deserializeData(XmlPullParser in, int outerTagDepth)
            throws XmlPullParserException, IOException {
        // Ignore empty reads.
        if (in == null) {
            return;
        }
        mConfigurations = parseNetworkList(in, outerTagDepth);
    }

    /**
     * Parse a list of {@link WifiConfiguration} from an input stream in XML format.
     *
     * @param in The input stream to read from
     * @param outerTagDepth The XML tag depth of the outer XML block
     * @return List of {@link WifiConfiguration}
     * @throws XmlPullParserException
     * @throws IOException
     */
    private List<WifiConfiguration> parseNetworkList(XmlPullParser in, int outerTagDepth)
            throws XmlPullParserException, IOException {
        List<WifiConfiguration> networkList = new ArrayList<>();
        while (XmlUtil.gotoNextSectionWithNameOrEnd(in, XML_TAG_SECTION_HEADER_NETWORK,
                outerTagDepth)) {
            // Try/catch only runtime exceptions (like illegal args), any XML/IO exceptions are
            // fatal and should abort the entire loading process.
            try {
                WifiConfiguration config = parseNetwork(in, outerTagDepth + 1);
                networkList.add(config);
            } catch (RuntimeException e) {
                // Failed to parse this network, skip it.
                Log.e(TAG, "Failed to parse network config. Skipping...", e);
            }
        }
        return networkList;
    }

之後就是xml解析出config了

    /**
     * Parse a {@link WifiConfiguration} from an input stream in XML format.
     *
     * @param in The input stream to read from
     * @param outerTagDepth The XML tag depth of the outer XML block
     * @return {@link WifiConfiguration}
     * @throws XmlPullParserException
     * @throws IOException
     */
    private WifiConfiguration parseNetwork(XmlPullParser in, int outerTagDepth)
            throws XmlPullParserException, IOException {
        Pair<String, WifiConfiguration> parsedConfig = null;
        NetworkSelectionStatus status = null;
        IpConfiguration ipConfiguration = null;
        WifiEnterpriseConfig enterpriseConfig = null;

        String[] headerName = new String[1];
        while (XmlUtil.gotoNextSectionOrEnd(in, headerName, outerTagDepth)) {
            switch (headerName[0]) {
                case XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION:
                    if (parsedConfig != null) {
                        throw new XmlPullParserException("Detected duplicate tag for: "
                                + XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
                    }
                    parsedConfig = WifiConfigurationXmlUtil.parseFromXml(in, outerTagDepth + 1);
                    break;
                case XML_TAG_SECTION_HEADER_NETWORK_STATUS:
                    if (status != null) {
                        throw new XmlPullParserException("Detected duplicate tag for: "
                                + XML_TAG_SECTION_HEADER_NETWORK_STATUS);
                    }
                    status = NetworkSelectionStatusXmlUtil.parseFromXml(in, outerTagDepth + 1);
                    break;
                case XML_TAG_SECTION_HEADER_IP_CONFIGURATION:
                    if (ipConfiguration != null) {
                        throw new XmlPullParserException("Detected duplicate tag for: "
                                + XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
                    }
                    ipConfiguration = IpConfigurationXmlUtil.parseFromXml(in, outerTagDepth + 1);
                    break;
                case XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION:
                    if (enterpriseConfig != null) {
                        throw new XmlPullParserException("Detected duplicate tag for: "
                                + XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
                    }
                    enterpriseConfig =
                            WifiEnterpriseConfigXmlUtil.parseFromXml(in, outerTagDepth + 1);
                    break;
                default:
                    throw new XmlPullParserException("Unknown tag under "
                            + XML_TAG_SECTION_HEADER_NETWORK + ": " + headerName[0]);
            }
        }
        if (parsedConfig == null || parsedConfig.first == null || parsedConfig.second == null) {
            throw new XmlPullParserException("XML parsing of wifi configuration failed");
        }
        String configKeyParsed = parsedConfig.first;
        WifiConfiguration configuration = parsedConfig.second;
        String configKeyCalculated = configuration.configKey();
        if (!configKeyParsed.equals(configKeyCalculated)) {
            throw new XmlPullParserException(
                    "Configuration key does not match. Retrieved: " + configKeyParsed
                            + ", Calculated: " + configKeyCalculated);
        }
        // Set creatorUid/creatorName for networks which don't have it set to valid value.
        String creatorName = mContext.getPackageManager().getNameForUid(configuration.creatorUid);
        if (creatorName == null) {
            Log.e(TAG, "Invalid creatorUid for saved network " + configuration.configKey()
                    + ", creatorUid=" + configuration.creatorUid);
            configuration.creatorUid = Process.SYSTEM_UID;
            configuration.creatorName =
                    mContext.getPackageManager().getNameForUid(Process.SYSTEM_UID);
        } else if (!creatorName.equals(configuration.creatorName)) {
            Log.w(TAG, "Invalid creatorName for saved network " + configuration.configKey()
                    + ", creatorUid=" + configuration.creatorUid
                    + ", creatorName=" + configuration.creatorName);
            configuration.creatorName = creatorName;
        }

        configuration.setNetworkSelectionStatus(status);
        configuration.setIpConfiguration(ipConfiguration);
        if (enterpriseConfig != null) {
            configuration.enterpriseConfig = enterpriseConfig;
        }
        return configuration;
    }

主要看下WifiConfigurationXmlUtil怎麼解析的

這個類是./service/java/com/android/server/wifi/util/XmlUtil.java:309:    public static class WifiConfigurationXmlUtil {

XmlUtil的靜態內部類

    /**
     * Utility class to serialize and deserialize {@link WifiConfiguration} object to XML &
     * vice versa.
     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
     * {@link com.android.server.wifi.WifiBackupRestore} modules.
     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
     * The parse method is written so that any element added/deleted in future revisions can
     * be easily handled.
     */
    public static class WifiConfigurationXmlUtil {
...
        /**
         * Parses the configuration data elements from the provided XML stream to a
         * WifiConfiguration object.
         * Note: This is used for parsing both backup data and config store data. Looping through
         * the tags make it easy to add or remove elements in the future versions if needed.
         *
         * @param in            XmlPullParser instance pointing to the XML stream.
         * @param outerTagDepth depth of the outer tag in the XML document.
         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
         * null otherwise.
         */
        public static Pair<String, WifiConfiguration> parseFromXml(
                XmlPullParser in, int outerTagDepth)
                throws XmlPullParserException, IOException {
            WifiConfiguration configuration = new WifiConfiguration();
            String configKeyInData = null;
            boolean macRandomizationSettingExists = false;

            // Loop through and parse out all the elements from the stream within this section.
            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
                String[] valueName = new String[1];
                Object value = XmlUtil.readCurrentValue(in, valueName);
                if (valueName[0] == null) {
                    throw new XmlPullParserException("Missing value name");
                }
                switch (valueName[0]) {
                    case XML_TAG_CONFIG_KEY:
                        configKeyInData = (String) value;
                        break;
                    case XML_TAG_SSID:
                        configuration.SSID = (String) value;
                        break;
                    case XML_TAG_BSSID:
                        configuration.BSSID = (String) value;
                        break;
                    case XML_TAG_PRE_SHARED_KEY:
                        configuration.preSharedKey = (String) value;
                        break;
                    case XML_TAG_WEP_KEYS:
                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
                        break;
                    case XML_TAG_WEP_TX_KEY_INDEX:
                        configuration.wepTxKeyIndex = (int) value;
                        break;
                    case XML_TAG_HIDDEN_SSID:
                        configuration.hiddenSSID = (boolean) value;
                        break;
                    case XML_TAG_REQUIRE_PMF:
                        configuration.requirePMF = (boolean) value;
                        break;
                    case XML_TAG_ALLOWED_KEY_MGMT:
                        byte[] allowedKeyMgmt = (byte[]) value;
                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
                        break;
                    case XML_TAG_ALLOWED_PROTOCOLS:
                        byte[] allowedProtocols = (byte[]) value;
                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
                        break;
                    case XML_TAG_ALLOWED_AUTH_ALGOS:
                        byte[] allowedAuthAlgorithms = (byte[]) value;
                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
                        break;
                    case XML_TAG_ALLOWED_GROUP_CIPHERS:
                        byte[] allowedGroupCiphers = (byte[]) value;
                        configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
                        break;
                    case XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
                        byte[] allowedPairwiseCiphers = (byte[]) value;
                        configuration.allowedPairwiseCiphers =
                                BitSet.valueOf(allowedPairwiseCiphers);
                        break;
                    case XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS:
                        byte[] allowedGroupMgmtCiphers = (byte[]) value;
                        configuration.allowedGroupManagementCiphers =
                                BitSet.valueOf(allowedGroupMgmtCiphers);
                        break;
                    case XML_TAG_ALLOWED_SUITE_B_CIPHERS:
                        byte[] allowedSuiteBCiphers = (byte[]) value;
                        configuration.allowedSuiteBCiphers =
                                BitSet.valueOf(allowedSuiteBCiphers);
                        break;
                    case XML_TAG_SHARED:
                        configuration.shared = (boolean) value;
                        break;
                    case XML_TAG_STATUS:
                        int status = (int) value;
                        // Any network which was CURRENT before reboot needs
                        // to be restored to ENABLED.
                        if (status == WifiConfiguration.Status.CURRENT) {
                            status = WifiConfiguration.Status.ENABLED;
                        }
                        configuration.status = status;
                        break;
                    case XML_TAG_FQDN:
                        configuration.FQDN = (String) value;
                        break;
                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
                        configuration.providerFriendlyName = (String) value;
                        break;
                    case XML_TAG_LINKED_NETWORKS_LIST:
                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
                        break;
                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
                        configuration.defaultGwMacAddress = (String) value;
                        break;
                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
                        configuration.validatedInternetAccess = (boolean) value;
                        break;
                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
                        configuration.noInternetAccessExpected = (boolean) value;
                        break;
                    case XML_TAG_USER_APPROVED:
                        configuration.userApproved = (int) value;
                        break;
                    case XML_TAG_METERED_HINT:
                        configuration.meteredHint = (boolean) value;
                        break;
                    case XML_TAG_METERED_OVERRIDE:
                        configuration.meteredOverride = (int) value;
                        break;
                    case XML_TAG_USE_EXTERNAL_SCORES:
                        configuration.useExternalScores = (boolean) value;
                        break;
                    case XML_TAG_NUM_ASSOCIATION:
                        configuration.numAssociation = (int) value;
                        break;
                    case XML_TAG_CREATOR_UID:
                        configuration.creatorUid = (int) value;
                        break;
                    case XML_TAG_CREATOR_NAME:
                        configuration.creatorName = (String) value;
                        break;
                    case XML_TAG_CREATION_TIME:
                        configuration.creationTime = (String) value;
                        break;
                    case XML_TAG_LAST_UPDATE_UID:
                        configuration.lastUpdateUid = (int) value;
                        break;
                    case XML_TAG_LAST_UPDATE_NAME:
                        configuration.lastUpdateName = (String) value;
                        break;
                    case XML_TAG_LAST_CONNECT_UID:
                        configuration.lastConnectUid = (int) value;
                        break;
                    case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG:
                        configuration.isLegacyPasspointConfig = (boolean) value;
                        break;
                    case XML_TAG_ROAMING_CONSORTIUM_OIS:
                        configuration.roamingConsortiumIds = (long[]) value;
                        break;
                    case XML_TAG_RANDOMIZED_MAC_ADDRESS:
                        configuration.setRandomizedMacAddress(
                                MacAddress.fromString((String) value));
                        break;
                    case XML_TAG_MAC_RANDOMIZATION_SETTING:
                        configuration.macRandomizationSetting = (int) value;
                        macRandomizationSettingExists = true;
                        break;
                    default:
                        throw new XmlPullParserException(
                                "Unknown value name found: " + valueName[0]);
                }
            }
            if (!macRandomizationSettingExists) {
                configuration.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
            }
            return Pair.create(configKeyInData, configuration);
        }
    }

對xml中的每個字段進行解析並存儲

再回到WifiConfigManager

        loadInternalData(mNetworkListSharedStoreData.getConfigurations(),
                mNetworkListUserStoreData.getConfigurations(),
                mDeletedEphemeralSsidsStoreData.getSsidToTimeMap(),
                mRandomizedMacStoreData.getMacMapping());

將解析好的config進行加載

        // Config Manager
        mWifiConfigManager = new WifiConfigManager(mContext, mClock,
                UserManager.get(mContext), makeTelephonyManager(),
                mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
                mWifiPermissionsWrapper, this, new NetworkListSharedStoreData(mContext),
                new NetworkListUserStoreData(mContext),
                new DeletedEphemeralSsidsStoreData(mClock), new RandomizedMacStoreData(),
                mFrameworkFacade, mWifiCoreHandlerThread.getLooper());

聯繫之前的各種storeData是哪裏來的

        // Register store data for network list and deleted ephemeral SSIDs.
        mNetworkListSharedStoreData = networkListSharedStoreData;
        mNetworkListUserStoreData = networkListUserStoreData;
        mDeletedEphemeralSsidsStoreData = deletedEphemeralSsidsStoreData;
        mRandomizedMacStoreData = randomizedMacStoreData;
        mWifiConfigStore.registerStoreData(mNetworkListSharedStoreData);
        mWifiConfigStore.registerStoreData(mNetworkListUserStoreData);
        mWifiConfigStore.registerStoreData(mDeletedEphemeralSsidsStoreData);
        mWifiConfigStore.registerStoreData(mRandomizedMacStoreData);

WifiConfigStore

    /**
     * Register a {@link StoreData} to read/write data from/to a store. A {@link StoreData} is
     * responsible for a block of data in the store file, and provides serialization/deserialization
     * functions for those data.
     *
     * @param storeData The store data to be registered to the config store
     * @return true if registered successfully, false if the store file name is not valid.
     */
    public boolean registerStoreData(@NonNull StoreData storeData) {
        if (storeData == null) {
            Log.e(TAG, "Unable to register null store data");
            return false;
        }
        int storeFileId = storeData.getStoreFileId();
        if (STORE_ID_TO_FILE_NAME.get(storeFileId) == null) {
            Log.e(TAG, "Invalid shared store file specified" + storeFileId);
            return false;
        }
        mStoreDataList.add(storeData);
        return true;
    }

和之前各個storeData的實現類連起來了。

WifiConfigManager進行數據的加載

    /**
     * Helper function to populate the internal (in-memory) data from the retrieved stores (file)
     * data.
     * This method:
     * 1. Clears all existing internal data.
     * 2. Sends out the networks changed broadcast after loading all the data.
     *
     * @param sharedConfigurations list of network configurations retrieved from shared store.
     * @param userConfigurations list of network configurations retrieved from user store.
     * @param deletedEphemeralSsidsToTimeMap map of ssid's representing the ephemeral networks
     *                                       deleted by the user to the wall clock time at which
     *                                       it was deleted.
     */
    private void loadInternalData(
            List<WifiConfiguration> sharedConfigurations,
            List<WifiConfiguration> userConfigurations,
            Map<String, Long> deletedEphemeralSsidsToTimeMap,
            Map<String, String> macAddressMapping) {
        // Clear out all the existing in-memory lists and load the lists from what was retrieved
        // from the config store.
        clearInternalData();
        loadInternalDataFromSharedStore(sharedConfigurations, macAddressMapping);
        loadInternalDataFromUserStore(userConfigurations, deletedEphemeralSsidsToTimeMap);
        generateRandomizedMacAddresses();
        if (mConfiguredNetworks.sizeForAllUsers() == 0) {
            Log.w(TAG, "No stored networks found.");
        }
        // reset identity & anonymous identity for networks using SIM-based authentication
        // on load (i.e. boot) so that if the user changed SIMs while the device was powered off,
        // we do not reuse stale credentials that would lead to authentication failure.
        resetSimNetworks();
        sendConfiguredNetworksChangedBroadcast();
        mPendingStoreRead = false;
    }

將獲取的所有config塞到config集合裏去

    /**
     * Helper function to populate the internal (in-memory) data from the retrieved shared store
     * (file) data.
     *
     * @param configurations list of configurations retrieved from store.
     */
    private void loadInternalDataFromSharedStore(
            List<WifiConfiguration> configurations,
            Map<String, String> macAddressMapping) {
        for (WifiConfiguration configuration : configurations) {
            configuration.networkId = mNextNetworkId++;
            if (mVerboseLoggingEnabled) {
                Log.v(TAG, "Adding network from shared store " + configuration.configKey());
            }
            try {
                mConfiguredNetworks.put(configuration);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Failed to add network to config map", e);
            }
        }
        mRandomizedMacAddressMapping.putAll(macAddressMapping);
    }

 

3. 總結

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章