开启未连接
ClientModeImpl
service/java/com/android/server/wifi/ClientModeImpl.java
setupClientMode
3637 if (isConnectedMacRandomizationEnabled()) {
3638 mWifiNative.setMacAddress(mInterfaceName, MacAddressUtils.createRandomUnicastAddress());
3639 }
打开WLAN,但不连接,关闭再打开WiFi MAC地址会变。
连接
更新MAC地址
updateWifiConfigOnStartConnection
连接时根据设置里的配置更新MAC地址,"网络详情"-》"高级"-》"隐私",使用随机MAC(默认),使用设备MAC。
Network & internet -》WiFi -》Netowrk details -》Privacy:Use randomized MAC (default)、Use device MAC
6378 /**
6379 * Update the wifi configuration before sending connect to
6380 * supplicant/driver.
6381 *
6382 * @param config wifi configuration object.
6383 * @param bssid BSSID to assocaite with.
6384 */
6385 void updateWifiConfigOnStartConnection(WifiConfiguration config, String bssid) {
6470 if (isConnectedMacRandomizationEnabled()) {
6471 if (config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT) {
6472 configureRandomizedMacAddress(config);
6473 } else {
6474 setCurrentMacToFactoryMac(config);
6475 }
6476 }
使用随机MAC(默认)
configureRandomizedMacAddress
配置随机MAC地址。
3301 * Dynamically change the MAC address to use the locally randomized
3302 * MAC address generated for each network.
3303 * @param config WifiConfiguration with mRandomizedMacAddress to change into. If the address
3304 * is masked out or not set, it will generate a new random MAC address.
3305 */
3306 private void configureRandomizedMacAddress(WifiConfiguration config) {
3307 if (config == null) {
3308 Log.e(TAG, "No config to change MAC address to");
3309 return;
3310 }
3311 String currentMacString = mWifiNative.getMacAddress(mInterfaceName);
3312 MacAddress currentMac = currentMacString == null ? null :
3313 MacAddress.fromString(currentMacString);
3314 MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
3315 if (!WifiConfiguration.isValidMacAddressForRandomization(newMac)) {
3316 Log.wtf(TAG, "Config generated an invalid MAC address");
3317 } else if (newMac.equals(currentMac)) {
3318 Log.d(TAG, "No changes in MAC address");
3319 } else {
3320 mWifiMetrics.logStaEvent(StaEvent.TYPE_MAC_CHANGE, config);
3321 boolean setMacSuccess =
3322 mWifiNative.setMacAddress(mInterfaceName, newMac);
3323 if (setMacSuccess) {
3324 mWifiNative.removeNetworkCachedDataIfNeeded(config.networkId, newMac);
3325 }
3326 Log.d(TAG, "ConnectedMacRandomization SSID(" + config.getPrintableSsid()
3327 + "). setMacAddress(" + newMac.toString() + ") from "
3328 + currentMacString + " = " + setMacSuccess);
3329 }
3330 }
获取随机MAC地址
getRandomizedMacAndUpdateIfNeeded
enhanced_mac_randomization_force_enabled=1按需更新MAC地址。
573 /**
574 * Returns the randomized MAC address that should be used for this WifiConfiguration.
575 * This API may return a randomized MAC different from the persistent randomized MAC if
576 * the WifiConfiguration is configured for aggressive MAC randomization.
577 * @param config
578 * @return MacAddress
579 */
580 public MacAddress getRandomizedMacAndUpdateIfNeeded(WifiConfiguration config) {
581 MacAddress mac = shouldUseAggressiveRandomization(config)
582 ? updateRandomizedMacIfNeeded(config)
583 : setRandomizedMacToPersistentMac(config);
584 return mac;
585 }
保存随机MAC地址
setRandomizedMacToPersistentMac
用HMAC-SHA256计算MAC地址,并保存
537 /**
538 * Obtain the persistent MAC address by first reading from an internal database. If non exists
539 * then calculate the persistent MAC using HMAC-SHA256.
540 * Finally set the randomized MAC of the configuration to the randomized MAC obtained.
541 * @param config the WifiConfiguration to make the update
542 * @return the persistent MacAddress or null if the operation is unsuccessful
543 */
544 private MacAddress setRandomizedMacToPersistentMac(WifiConfiguration config) {
545 MacAddress persistentMac = getPersistentMacAddress(config);
546 if (persistentMac == null || persistentMac.equals(config.getRandomizedMacAddress())) {
547 return persistentMac;
548 }
549 WifiConfiguration internalConfig = getInternalConfiguredNetwork(config.networkId);
550 internalConfig.setRandomizedMacAddress(persistentMac);
551 return persistentMac;
552 }
生成随机MAC地址
会保存生成的随机MAC地址直到恢复出厂设置。
470 /**
471 * The persistent randomized MAC address is locally generated for each SSID and does not
472 * change until factory reset of the device. In the initial Q release the per-SSID randomized
473 * MAC is saved on the device, but in an update the storing of randomized MAC is removed.
474 * Instead, the randomized MAC is calculated directly from the SSID and a on device secret.
475 * For backward compatibility, this method first checks the device storage for saved
476 * randomized MAC. If it is not found or the saved MAC is invalid then it will calculate the
477 * randomized MAC directly.
478 *
479 * In the future as devices launched on Q no longer get supported, this method should get
480 * simplified to return the calculated MAC address directly.
481 * @param config the WifiConfiguration to obtain MAC address for.
482 * @return persistent MAC address for this WifiConfiguration
483 */
484 private MacAddress getPersistentMacAddress(WifiConfiguration config) {
使用设备MAC
setCurrentMacToFactoryMac
设置为厂家提供MAC地址。
3332 /**
3333 * Sets the current MAC to the factory MAC address.
3334 */
3335 private void setCurrentMacToFactoryMac(WifiConfiguration config) {
3336 MacAddress factoryMac = mWifiNative.getFactoryMacAddress(mInterfaceName);
3337 if (factoryMac == null) {
3338 Log.e(TAG, "Fail to set factory MAC address. Factory MAC is null.");
3339 return;
3340 }
3341 String currentMacStr = mWifiNative.getMacAddress(mInterfaceName);
3342 if (!TextUtils.equals(currentMacStr, factoryMac.toString())) {
3343 if (mWifiNative.setMacAddress(mInterfaceName, factoryMac)) {
3344 mWifiNative.removeNetworkCachedDataIfNeeded(config.networkId, factoryMac);
3345 mWifiMetrics.logStaEvent(StaEvent.TYPE_MAC_CHANGE, config);
3346 } else {
3347 Log.e(TAG, "Failed to set MAC address to " + "'" + factoryMac.toString() + "'");
3348 }
3349 }
3350 }
MacAddressUtil
service/java/com/android/server/wifi/MacAddressUtil.java
获取hash函数
100 private Mac obtainMacRandHashFunctionInternal(int uid, String alias) {
101 try {
102 KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(uid);
103 // tries to retrieve the secret, and generate a new one if it's unavailable.
104 Key key = keyStore.getKey(alias, null);
105 if (key == null) {
106 key = generateAndPersistNewMacRandomizationSecret(uid, alias);
107 }
108 if (key == null) {
109 Log.e(TAG, "Failed to generate secret for " + alias);
110 return null;
111 }
112 Mac result = Mac.getInstance("HmacSHA256");
113 result.init(key);
114 return result;
115 } catch (KeyStoreException | NoSuchAlgorithmException | InvalidKeyException
116 | UnrecoverableKeyException | NoSuchProviderException e) {
117 Log.e(TAG, "Failure in obtainMacRandHashFunction", e);
118 return null;
119 }
120 }
计算MAC地址
calculatePersistentMac根据key hash函数计算MAC地址。
加调试日志
--- a/service/java/com/android/server/wifi/MacAddressUtil.java
+++ b/service/java/com/android/server/wifi/MacAddressUtil.java
@@ -50,6 +50,15 @@ public class MacAddressUtil {
private static final long MAC_ADDRESS_LOCALLY_ASSIGNED_MASK = 1L << 41;
private static final long MAC_ADDRESS_MULTICAST_MASK = 1L << 40;
+ private static String bytesToHex(byte[] bytes) {
+ StringBuilder hexString = new StringBuilder();
+ for (byte b : bytes) {
+ String hex = String.format("%02X", b);
+ hexString.append(hex);
+ }
+ return hexString.toString();
+ }
+
/**
* Computes the persistent randomized MAC using the given key and hash function.
* @param key the key to compute MAC address for
@@ -82,6 +91,8 @@ public class MacAddressUtil {
// MacAddress.fromBytes requires input of length 6, which is obtained from the
// last 6 bytes from the generated long.
MacAddress macAddress = MacAddress.fromBytes(Arrays.copyOfRange(bf.array(), 2, 8));
+ String hashStr = bytesToHex(hashedBytes);
+ Log.i(TAG, "key:" + key + ",hash:" + hashStr + "," + macAddress);
return macAddress;
}
配置
config.xml
frameworks/opt/net/wifi/service/res/values/config.xml
config_wifi_connected_mac_randomization_supported
244 <!-- Indicates that connected MAC randomization is supported on this device -->
245 <bool translatable="false" name="config_wifi_connected_mac_randomization_supported">true</bool>
246
247 <!-- Indicates that p2p MAC randomization is supported on this device -->
248 <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">true</bool>
249
250 <!-- Indicates that AP mode MAC randomization is supported on this device -->
251 <bool translatable="false" name="config_wifi_ap_mac_randomization_supported">false</bool>
252
253 <!-- list of SSIDs to enable aggressive MAC randomization on -->
254 <string-array translatable="false" name="config_wifi_aggressive_randomization_ssid_allowlist">
255 <!-- SSIDs are expected in quoted format:
256 <item>\"SSID_1\"</item>
257 <item>\"SSID_2\"</item>
258 -->
259 </string-array>
260
261 <!-- list of SSIDs to disable aggressive MAC randomization on. If a SSID is in both the
262 allowlist and blocklist, then aggressive MAC randomization will still be disabled. -->
263 <string-array translatable="false" name="config_wifi_aggressive_randomization_ssid_blocklist">
264 <!-- SSIDs are expected in quoted format:
265 <item>\"SSID_1\"</item>
266 <item>\"SSID_2\"</item>
267 -->
268 </string-array>
随机MAC地址设置
配置创建
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConfigManager.java
633 /**
634 * Helper method to create a copy of the provided internal WifiConfiguration object to be
635 * passed to external modules.
636 *
637 * @param configuration provided WifiConfiguration object.
638 * @param maskPasswords Mask passwords or not.
639 * @param targetUid Target UID for MAC address reading: -1 = mask all, 0 = mask none, >0 =
640 * mask all but the targetUid (carrier app).
641 * @return Copy of the WifiConfiguration object.
642 */
643 private WifiConfiguration createExternalWifiConfiguration(
644 WifiConfiguration configuration, boolean maskPasswords, int targetUid) {
645 WifiConfiguration network = new WifiConfiguration(configuration);
646 if (maskPasswords) {
647 maskPasswordsInWifiConfiguration(network);
648 }
649 if (targetUid != Process.WIFI_UID && targetUid != Process.SYSTEM_UID
650 && targetUid != configuration.creatorUid) {
651 maskRandomizedMacAddressInWifiConfiguration(network);
652 }
653 if (!isMacRandomizationSupported()) {
654 network.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
655 }
656 return network;
657 }
默认值修改
WifiConfiguration
修改frameworks/base/wifi/java/android/net/wifi/WifiConfiguration.java无效。
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1154,7 +1154,7 @@ public class WifiConfiguration implements Parcelable {
*/
@SystemApi
@MacRandomizationSetting
- public int macRandomizationSetting = RANDOMIZATION_PERSISTENT;
+ public int macRandomizationSetting = RANDOMIZATION_NONE;
/**
* @hide
PasspointProvider
也不是
frameworks/opt/net/wifi/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
451 /**
452 * Generate a WifiConfiguration based on the provider's configuration. The generated
453 * WifiConfiguration will include all the necessary credentials for network connection except
454 * the SSID, which should be added by the caller when the config is being used for network
455 * connection.
456 *
457 * @return {@link WifiConfiguration}
458 */
459 public WifiConfiguration getWifiConfig() {
460 WifiConfiguration wifiConfig = new WifiConfiguration();
461 wifiConfig.FQDN = mConfig.getHomeSp().getFqdn();
462 wifiConfig.setPasspointUniqueId(mConfig.getUniqueId());
463 if (mConfig.getHomeSp().getRoamingConsortiumOis() != null) {
464 wifiConfig.roamingConsortiumIds = Arrays.copyOf(
465 mConfig.getHomeSp().getRoamingConsortiumOis(),
466 mConfig.getHomeSp().getRoamingConsortiumOis().length);
467 }
...
525 if (mConfig.isMacRandomizationEnabled()) {
526 wifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
527 } else {
528 wifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
529 }
MtkSettings
WifiPrivacyPreferenceController
不是
--- a/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
@@ -115,7 +115,7 @@ public class WifiPrivacyPreferenceController extends BasePreferenceController im
if (mWifiConfiguration != null) {
return mWifiConfiguration.macRandomizationSetting;
}
- return WifiConfiguration.RANDOMIZATION_PERSISTENT;
+ return WifiConfiguration.RANDOMIZATION_NONE;
}
private static final int PREF_RANDOMIZATION_PERSISTENT = 0;
src/com/android/settings/wifi/WifiConfigController2.java
initWifiConfigController2
修改PrivacySettingsSpinner,默认选择"使用设备MAC"。
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -288,6 +288,9 @@ public class WifiConfigController2 implements TextWatcher,
ViewGroup group = (ViewGroup) mView.findViewById(R.id.info);
boolean showAdvancedFields = false;
+ if (!mWifiEntry.isSaved()) {
+ mPrivacySettingsSpinner.setSelection(1);
+ }
if (mWifiEntry.isSaved()) {
WifiConfiguration config = mWifiEntry.getWifiConfiguration();
mMeteredSettingsSpinner.setSelection(config.meteredOverride);
getConfig
点击连接时,会获取PrivacySettingsSpinner的选择,保存到配置中。
839 if (mPrivacySettingsSpinner != null) {
840 int macValue;
841 if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) {
842 macValue = WifiPrivacyPreferenceController2.translatePrefValueToMacRandomizedValue(
843 mPrivacySettingsSpinner.getSelectedItemPosition());
844 } else {
845 macValue = WifiPrivacyPreferenceController.translatePrefValueToMacRandomizedValue(
846 mPrivacySettingsSpinner.getSelectedItemPosition());
847 }
848 config.macRandomizationSetting = macValue;
849 }