android11 wifi 自动连接流程分析


android11 wifi 自动连接流程分析

\frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiConnectivityManager.java

	// wifi扫描回调
	onResults(WifiScanner.ScanData[] results)
	
	
	// wifi扫描回调
	handleScanResults(List<ScanDetail> scanDetails, String listenerName,
            boolean isFullScan) 
			
			//获取可自动连接wifi
			List<WifiCandidates.Candidate> candidates = mNetworkSelector.getCandidatesFromScan(
			
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiNetworkSelector.java

	public List<WifiCandidates.Candidate> getCandidatesFromScan(
            List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
            boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) {
			...
			//遍历历史连接wifi列表,推荐连接列表,并返回相关的wifi信息
			for (NetworkNominator registeredNominator : mNominators) {
            localLog("About to run " + registeredNominator.getName() + " :");
            Log.i(TAG,"registeredNominator.getName():" + registeredNominator.getName());
            registeredNominator.nominateNetworks(
                    new ArrayList<>(mFilteredNetworks), currentNetwork, currentBssid, connected,
                    untrustedNetworkAllowed,
                    (scanDetail, config) -> {
                        
                        WifiCandidates.Key key = wifiCandidates.keyFromScanDetailAndConfig(
                                scanDetail, config);
                        if (key != null) {
                            Log.i(TAG,"registeredNominator.getName():" + registeredNominator.getName() + 
                        scanDetail.getSSID());
                            boolean metered = isEverMetered(config, wifiInfo, scanDetail);
                            // TODO(b/151981920) Saved passpoint candidates are marked ephemeral
                            boolean added = wifiCandidates.add(key, config,
                                    registeredNominator.getId(),
                                    scanDetail.getScanResult().level,
                                    scanDetail.getScanResult().frequency,
                                    calculateLastSelectionWeight(config.networkId),
                                    metered,
                                    isFromCarrierOrPrivilegedApp(config),
                                    predictThroughput(scanDetail));
                            if (added) {
                                mConnectableNetworks.add(Pair.create(scanDetail, config));
                                mWifiConfigManager.updateScanDetailForNetwork(
                                        config.networkId, scanDetail);
                                mWifiMetrics.setNominatorForNetwork(config.networkId,
                                        toProtoNominatorId(registeredNominator.getId()));
                            }
                        }
                    });
        }
			...
			
			}
			
//wifi 各模块相关的初始化		
\frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiInjector.java

		//缓存类初始化
		mWifiConfigStore = new WifiConfigStore(mContext, wifiHandler, mClock, mWifiMetrics,
		        //创建连接缓存文件/data/misc/apexdata/com.android.wifi/WifiConfigStore.xml
                WifiConfigStore.createSharedFiles(mFrameworkFacade.isNiapModeOn(mContext)));
        ...
        // Config Manager
        mWifiConfigManager = new WifiConfigManager(mContext, mClock,
                mUserManager, mWifiCarrierInfoManager,
                mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
                mWifiPermissionsWrapper, this,
                new NetworkListSharedStoreData(mContext),
                new NetworkListUserStoreData(mContext),
                new RandomizedMacStoreData(), mFrameworkFacade, wifiHandler, mDeviceConfigFacade,
                mWifiScoreCard, mLruConnectionTracker);
				
		...
		//这里初始化了链接缓存数据列表
		mSavedNetworkNominator = new SavedNetworkNominator(
                mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager,
                mWifiPermissionsUtil, mWifiNetworkSuggestionsManager);
        mNetworkSuggestionNominator = new NetworkSuggestionNominator(mWifiNetworkSuggestionsManager,
                mWifiConfigManager, nominateHelper, mConnectivityLocalLog, mWifiCarrierInfoManager);
        mScoredNetworkNominator = new ScoredNetworkNominator(mContext, wifiHandler,
                mFrameworkFacade, mNetworkScoreManager, mContext.getPackageManager(),
                mWifiConfigManager, mConnectivityLocalLog,
                mWifiNetworkScoreCache, mWifiPermissionsUtil);
		...
		//注册了WifiNetworkSelector 中的mNominators 数组对象
		mWifiNetworkSelector.registerNetworkNominator(mSavedNetworkNominator);
        mWifiNetworkSelector.registerNetworkNominator(mNetworkSuggestionNominator);
        mWifiNetworkSelector.registerNetworkNominator(mScoredNetworkNominator);
		
		
frameworks\opt\net\wifi\service\java\com\android\server\wifi\SavedNetworkNominator.java

	//WifiNetworkSelector 中遍历监听回调查询缓存列表
		@Override
     public void nominateNetworks(List<ScanDetail> scanDetails,
                     WifiConfiguration currentNetwork, String currentBssid, boolean connected,
                     boolean untrustedNetworkAllowed,
                     @NonNull OnConnectableListener onConnectableListener) {
         findMatchedSavedNetworks(scanDetails, onConnectableListener);
         findMatchedPasspointNetworks(scanDetails, onConnectableListener);
     }
 
     private void findMatchedSavedNetworks(List<ScanDetail> scanDetails,
             OnConnectableListener onConnectableListener) {
			  for (ScanDetail scanDetail : scanDetails) {
             ScanResult scanResult = scanDetail.getScanResult();
 
             // One ScanResult can be associated with more than one network, hence we calculate all
             // the scores and use the highest one as the ScanResult's score.
             WifiConfiguration network =
					//在WifiConfigManager的 getConfiguredNetworkForScanDetailAndCache中获取
                     mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail);
					 }
			 ...
			 }
			 
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiConfigManager.java

		public WifiConfiguration getConfiguredNetworkForScanDetailAndCache(ScanDetail scanDetail) {
        //在getConfiguredNetworkForScanDetail中获取
        WifiConfiguration network = getConfiguredNetworkForScanDetail(scanDetail);
		...
		}
		
		public WifiConfiguration getConfiguredNetworkForScanDetail(ScanDetail scanDetail) {
        ScanResult scanResult = scanDetail.getScanResult();
        if (scanResult == null) {
            Log.e(TAG, "No scan result found in scan detail");
            return null;
        }
        WifiConfiguration config = null;
        try {
			//在这里获取并返回
            config = mConfiguredNetworks.getByScanResultForCurrentUser(scanResult);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Failed to lookup network from config map", e);
        }
        if (config != null) {
            if (mVerboseLoggingEnabled) {
                Log.v(TAG, "getSavedNetworkFromScanDetail Found " + config.getKey()
                        + " for " + scanResult.SSID + "[" + scanResult.capabilities + "]");
            }
        } else {
            Log.i(TAG," getConfiguredNetworkForScanDetail is null");
        }
        return config;
    }
	
	
frameworks\opt\net\wifi\service\java\com\android\server\wifi\ConfigurationMap.java

	public WifiConfiguration getByScanResultForCurrentUser(ScanResult scanResult) {
        return mScanResultMatchInfoMapForCurrentUser.get(
                ScanResultMatchInfo.fromScanResult(scanResult));
    }
	
	// RW methods:
    public WifiConfiguration put(WifiConfiguration config) {
        mConfig = config;
        final WifiConfiguration current = mPerID.put(config.networkId, config);
        final UserHandle currentUser = UserHandle.of(mCurrentUserId);
        final UserHandle creatorUser = UserHandle.getUserHandleForUid(config.creatorUid);
        if (config.shared || currentUser.equals(creatorUser)
                || mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
            mPerIDForCurrentUser.put(config.networkId, config);
            // TODO (b/142035508): Add a more generic fix. This cache should only hold saved
            // networks.
            if (!config.fromWifiNetworkSpecifier) {
                Log.i("WifiConfiguration","fromWifiNetworkSpecifier put:");
                mScanResultMatchInfoMapForCurrentUser.put(
                        ScanResultMatchInfo.fromWifiConfiguration(config), config);
            }
        }
		//mPerIDForCurrentUser 数据在这里添加
        mPerIDForCurrentUser.put(config.networkId, config);
        mScanResultMatchInfoMapForCurrentUser.put(
                        ScanResultMatchInfo.fromWifiConfiguration(config), config);
        return current;
    }
	
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiConfigManager.java

	loadFromStore()->loadInternalData()->loadInternalDataFromSharedStore()->ConfigurationMap.put()
	
	private void loadInternalDataFromSharedStore(
            List<WifiConfiguration> configurations,
            Map<String, String> macAddressMapping) {
			//configurations传入的参数
        for (WifiConfiguration configuration : configurations) {
            configuration.networkId = mNextNetworkId++;
            if (mVerboseLoggingEnabled) {
                Log.v(TAG, "Adding network from shared store " + configuration.getKey());
            }
            try {
			//这里设置了缓存值
                mConfiguredNetworks.put(configuration);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Failed to add network to config map", e);
            }
        }
        mRandomizedMacAddressMapping.putAll(macAddressMapping);
    }
	
	//也是由传入的参数影响
	private void loadInternalData(
            List<WifiConfiguration> sharedConfigurations,
            List<WifiConfiguration> userConfigurations,
            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);
        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();
        sendConfiguredNetworkChangedBroadcast(WifiManager.CHANGE_REASON_ADDED);
        mPendingStoreRead = false;
    }
	
	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.
        ...
		//最后是一个全局参数mNetworkListSharedStoreData 决定
        loadInternalData(mNetworkListSharedStoreData.getConfigurations(),
                mNetworkListUserStoreData.getConfigurations(),
                mRandomizedMacStoreData.getMacMapping());
        return true;
    }
	
	WifiConfigManager(
            Context context, Clock clock, UserManager userManager,
            WifiCarrierInfoManager wifiCarrierInfoManager, WifiKeyStore wifiKeyStore,
            WifiConfigStore wifiConfigStore,
            WifiPermissionsUtil wifiPermissionsUtil,
            WifiPermissionsWrapper wifiPermissionsWrapper,
            WifiInjector wifiInjector,
            NetworkListSharedStoreData networkListSharedStoreData,
            NetworkListUserStoreData networkListUserStoreData,
            RandomizedMacStoreData randomizedMacStoreData,
            FrameworkFacade frameworkFacade, Handler handler,
            DeviceConfigFacade deviceConfigFacade, WifiScoreCard wifiScoreCard,
            LruConnectionTracker lruConnectionTracker) {
        ...
        // Register store data for network list and deleted ephemeral SSIDs.
		//在WifiConfigManager 初始化的时候进行了设置
        mNetworkListSharedStoreData = networkListSharedStoreData;
        mNetworkListUserStoreData = networkListUserStoreData;
        mRandomizedMacStoreData = randomizedMacStoreData;
        mWifiConfigStore.registerStoreData(mNetworkListSharedStoreData);
        mWifiConfigStore.registerStoreData(mNetworkListUserStoreData);
        mWifiConfigStore.registerStoreData(mRandomizedMacStoreData);
        ...        
		}
		
		
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiInjector.java
		
		再次的回到WifiInjector中
		public WifiInjector(WifiContext context) {
		...
		mWifiConfigManager = new WifiConfigManager(mContext, mClock,
                mUserManager, mWifiCarrierInfoManager,
                mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
                mWifiPermissionsWrapper, this,
				//在这里通过初始化对象传入
                new NetworkListSharedStoreData(mContext),
                new NetworkListUserStoreData(mContext),
                new RandomizedMacStoreData(), mFrameworkFacade, wifiHandler, mDeviceConfigFacade,
                mWifiScoreCard, mLruConnectionTracker);
		...
		}
	
	
frameworks\opt\net\wifi\service\java\com\android\server\wifi\NetworkListStoreData.java

		//NetworkListSharedStoreData真正的实现对象是NetworkListStoreData
		
		//WifiConfigManager 中的 getConfigurations获取的就是这里的mConfigurations值
		public List<WifiConfiguration> getConfigurations() {
        if (mConfigurations == null) {
            return new ArrayList<WifiConfiguration>();
        }
        return mConfigurations;
		}
		
		//在这里设置了值
		 @Override
		public void deserializeData(XmlPullParser in, int outerTagDepth,
				@WifiConfigStore.Version int version,
				@Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
				throws XmlPullParserException, IOException {
					try {
						throw new Exception("NetworkListStoreData deserializeData");
					} catch (Exception e) {
						e.printStackTrace();
					}
			// Ignore empty reads.
			if (in == null) {
				return;
			}
			mConfigurations = parseNetworkList(in, outerTagDepth, version, encryptionUtil);
		}
		
		

frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiConfigStore.java

		//这里是主要的调用流程
		read()->readFromSharedStoreFiles(WifiConfigStore.java:611)->deserializeData(WifiConfigStore.java:769)->NetworkListStoreData.deserializeData(NetworkListStoreData.java:87)
		//我们主要看readFromSharedStoreFiles
		
		private void readFromSharedStoreFiles() throws XmlPullParserException, IOException {
		//通过这里的mSharedStores获取值
        for (StoreFile sharedStoreFile : mSharedStores) {
            byte[] sharedDataBytes =
                    readDataFromMigrationSharedStoreFile(sharedStoreFile.getFileId());
            if (sharedDataBytes == null) {
                // nothing to migrate, do normal read.
                sharedDataBytes = sharedStoreFile.readRawData();
            } else {
                Log.i(TAG, "Read data out of shared migration store file: "
                        + sharedStoreFile.getName());
                // Save the migrated file contents to the regular store file and delete the
                // migrated stored file.
                sharedStoreFile.storeRawDataToWrite(sharedDataBytes);
                sharedStoreFile.writeBufferedRawData();
                // Note: If the migrated store file is at the same location as the store file,
                // then the OEM implementation should ignore this remove.
                WifiMigration.removeSharedConfigStoreFile(
                        getMigrationStoreFileId(sharedStoreFile.getFileId()));
            }
            deserializeData(sharedDataBytes, sharedStoreFile);
        }
		}
		
		public WifiConfigStore(Context context, Handler handler, Clock clock, WifiMetrics wifiMetrics,
            List<StoreFile> sharedStores) {

        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        mEventHandler = handler;
        mClock = clock;
        mWifiMetrics = wifiMetrics;
        mStoreDataList = new ArrayList<>();

        // Initialize the store files.
		//这里初始化的时候传入
        mSharedStores = sharedStores;
        // The user store is initialized to null, this will be set when the user unlocks and
        // CE storage is accessible via |switchUserStoresAndRead|.
        mUserStores = null;
		}
		
		
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiInjector.java

		public WifiInjector(WifiContext context) {
		...
		mWifiConfigStore = new WifiConfigStore(mContext, wifiHandler, mClock, mWifiMetrics,
				//在这里创建传入
                WifiConfigStore.createSharedFiles(mFrameworkFacade.isNiapModeOn(mContext)));
		...
		}


frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiConfigStore.java

		//这里创建的是/data/misc/apexdata/com.android.wifi 下的  WifiConfigStore.xml  和  WifiConfigStoreSoftAp.xml 文件,也就是读取这里面的值
		public static @NonNull List<StoreFile> createSharedFiles(boolean shouldEncryptCredentials) {
        return createFiles(
                Environment.getWifiSharedDirectory(),
                Arrays.asList(STORE_FILE_SHARED_GENERAL, STORE_FILE_SHARED_SOFTAP),
                UserHandle.ALL,
                shouldEncryptCredentials);
    }




所以,如果需要进行预置链接wifi的话,可以通过在/data/misc/apexdata/com.android.wifi 下预置 WifiConfigStore.xml 达到目的

参考文件内容

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<WifiConfigStoreData>
<int name="Version" value="3" />
<NetworkList>
<Network>
<WifiConfiguration>
<string name="ConfigKey">&quot;AndroidWifi&quot;NONE</string>
<string name="SSID">&quot;AndroidWifi&quot;</string>
<null name="PreSharedKey" />
<null name="WEPKeys" />
<int name="WEPTxKeyIndex" value="0" />
<boolean name="HiddenSSID" value="false" />
<boolean name="RequirePMF" value="false" />
<byte-array name="AllowedKeyMgmt" num="1">01</byte-array>
<byte-array name="AllowedProtocols" num="1">03</byte-array>
<byte-array name="AllowedAuthAlgos" num="1">01</byte-array>
<byte-array name="AllowedGroupCiphers" num="1">0f</byte-array>
<byte-array name="AllowedPairwiseCiphers" num="1">06</byte-array>
<byte-array name="AllowedGroupMgmtCiphers" num="0"></byte-array>
<byte-array name="AllowedSuiteBCiphers" num="0"></byte-array>
<boolean name="Shared" value="true" />
<boolean name="AutoJoinEnabled" value="true" />
<boolean name="Trusted" value="true" />
<null name="BSSID" />
<int name="Status" value="2" />
<null name="FQDN" />
<null name="ProviderFriendlyName" />
<null name="LinkedNetworksList" />
<null name="DefaultGwMacAddress" />
<boolean name="ValidatedInternetAccess" value="true" />
<boolean name="NoInternetAccessExpected" value="false" />
<boolean name="MeteredHint" value="false" />
<int name="MeteredOverride" value="0" />
<boolean name="UseExternalScores" value="false" />
<int name="CreatorUid" value="1000" />
<string name="CreatorName">android.uid.system:1000</string>
<int name="LastUpdateUid" value="-1" />
<null name="LastUpdateName" />
<int name="LastConnectUid" value="0" />
<boolean name="IsLegacyPasspointConfig" value="false" />
<long-array name="RoamingConsortiumOIs" num="0" />
<string name="RandomizedMacAddress">8a:aa:f9:e0:5b:bb</string>
<int name="MacRandomizationSetting" value="0" />
<int name="CarrierId" value="-1" />
<boolean name="IsMostRecentlyConnected" value="true" />
</WifiConfiguration>
<NetworkStatus>
<string name="SelectionStatus">NETWORK_SELECTION_ENABLED</string>
<string name="DisableReason">NETWORK_SELECTION_ENABLE</string>
<null name="ConnectChoice" />
<boolean name="HasEverConnected" value="true" />
</NetworkStatus>
<IpConfiguration>
<string name="IpAssignment">DHCP</string>
<string name="ProxySettings">NONE</string>
</IpConfiguration>
</Network>
</NetworkList>
<MacAddressMap>
<map name="MacMapEntry" />
</MacAddressMap>
<Settings>
<map name="Values">
<boolean name="wifi_p2p_pending_factory_reset" value="false" />
<null name="wifi_p2p_device_name" />
<boolean name="wifi_scan_always_enabled" value="true" />
<boolean name="wifi_scan_throttle_enabled" value="true" />
<boolean name="wifi_verbose_logging_enabled" value="false" />
</map>
</Settings>
<PasspointConfigData>
<long name="ProviderIndex" value="0" />
</PasspointConfigData>
</WifiConfigStoreData>



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值