add per-connection Wi-Fi MAC address randomization option

fixup! add per-connection Wi-Fi MAC address randomization option
This commit is contained in:
Dmitry Muhomor
2024-10-16 22:45:29 +03:00
committed by Joey
parent e7273c3233
commit b45269eb32
11 changed files with 75 additions and 38 deletions

View File

@@ -713,7 +713,7 @@
android:layout_height="wrap_content"
style="@style/wifi_item_spinner"
android:prompt="@string/wifi_privacy_settings"
android:entries="@array/wifi_privacy_entries"/>
android:entries="@array/wifi_privacy_entries_ext"/>
<Spinner android:id="@+id/dhcp_settings"
android:layout_width="match_parent"

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019-2024 The Evolution X Project
SPDX-License-Identifier: Apache-2.0
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Wi-Fi MAC address randomization -->
<string-array name="wifi_privacy_entries_ext">
<item>@string/wifi_per_connection_random_mac_addr</item>
<item>@string/wifi_per_network_random_mac_addr</item>
<item>@string/wifi_device_mac_addr</item>
</string-array>
<string-array name="wifi_privacy_values_ext" translatable="false">
<item>100</item>
<item>1</item>
<item>0</item>
</string-array>
</resources>

View File

@@ -77,4 +77,9 @@
<string name="app_volume">App volume</string>
<string name="app_volume_title">Per-app volume control</string>
<string name="app_volume_summary">Show per-app volume button into volume dialog</string>
<!-- Wi-Fi MAC address randomization -->
<string name="wifi_per_connection_random_mac_addr">Use per-connection randomized MAC (default)</string>
<string name="wifi_per_network_random_mac_addr">Use per-network randomized MAC</string>
<string name="wifi_device_mac_addr">Use device MAC</string>
</resources>

View File

@@ -99,8 +99,8 @@
android:key="privacy"
android:icon="@drawable/ic_wifi_privacy_24dp"
android:title="@string/wifi_privacy_settings"
android:entries="@array/wifi_privacy_entries"
android:entryValues="@array/wifi_privacy_values"/>
android:entries="@array/wifi_privacy_entries_ext"
android:entryValues="@array/wifi_privacy_values_ext"/>
<com.android.settings.spa.preference.ComposePreference
android:key="privacy_settings"

View File

@@ -73,6 +73,7 @@ import com.android.settings.R;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.utils.AndroidKeystoreAliasLoader;
import com.android.settings.wifi.details2.WifiPrivacyPreferenceController;
import com.android.settings.wifi.details2.WifiPrivacyPreferenceController2;
import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settings.wifi.utils.TextInputGroup;
import com.android.settings.wifi.utils.TextInputValidator;
@@ -154,9 +155,10 @@ public class WifiConfigController implements TextWatcher,
UNDESIRED_CERTIFICATE_MACRANDSAPSECRET
};
// Should be the same index value as wifi_privacy_entries in arrays.xml
@VisibleForTesting static final int PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC = 0;
@VisibleForTesting static final int PRIVACY_SPINNER_INDEX_DEVICE_MAC = 1;
// Should be the same index value as wifi_privacy_entries_ext in arrays.xml
public static final int PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC = 0;
public static final int PRIVACY_PREF_INDEX_PER_NETWORK_RANDOMIZED_MAC = 1;
public static final int PRIVACY_PREF_INDEX_DEVICE_MAC = 2;
// Should be the same index value as wifi_dhcp_entries in arrays.xml
@VisibleForTesting static final int DHCP_SPINNER_INDEX_SEND_DHCP_HOST_NAME_ENABLE = 0;
@@ -338,9 +340,9 @@ public class WifiConfigController implements TextWatcher,
? HIDDEN_NETWORK
: NOT_HIDDEN_NETWORK);
mPrivacySettingsSpinner.setSelection(
config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT
? PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC : PRIVACY_SPINNER_INDEX_DEVICE_MAC);
int selection = WifiPrivacyPreferenceController2
.translateWifiEntryPrivacyToPrefValue(config.macRandomizationSetting);
mPrivacySettingsSpinner.setSelection(selection);
mDhcpSettingsSpinner.setSelection(
config.isSendDhcpHostnameEnabled()
@@ -819,10 +821,8 @@ public class WifiConfigController implements TextWatcher,
}
if (mPrivacySettingsSpinner != null) {
config.macRandomizationSetting = mPrivacySettingsSpinner.getSelectedItemPosition()
== PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC
? WifiConfiguration.RANDOMIZATION_PERSISTENT
: WifiConfiguration.RANDOMIZATION_NONE;
config.macRandomizationSetting = WifiPrivacyPreferenceController2
.translatePrefValueToWifiConfigSetting(mPrivacySettingsSpinner.getSelectedItemPosition());
}
if (mDhcpSettingsSpinner != null) {

View File

@@ -758,7 +758,7 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle
}
private int getMacAddressTitle() {
if (mWifiEntry.getPrivacy() == WifiEntry.PRIVACY_RANDOMIZED_MAC) {
if (mWifiEntry.getPrivacy() != WifiEntry.PRIVACY_DEVICE_MAC) {
return mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED
? R.string.wifi_advanced_randomized_mac_address_title
: R.string.wifi_advanced_randomized_mac_address_disconnected_title;

View File

@@ -90,8 +90,8 @@ fun WifiPrivacyPage(wifiEntry: WifiEntry) {
) {
Column {
val title = stringResource(id = R.string.wifi_privacy_mac_settings)
val wifiPrivacyEntries = stringArrayResource(R.array.wifi_privacy_entries)
val wifiPrivacyValues = stringArrayResource(R.array.wifi_privacy_values)
val wifiPrivacyEntries = stringArrayResource(R.array.wifi_privacy_entries_ext)
val wifiPrivacyValues = stringArrayResource(R.array.wifi_privacy_values_ext)
val textsSelectedId = rememberSaveable { mutableIntStateOf(wifiEntry.privacy) }
val dataList = remember {
wifiPrivacyEntries.mapIndexed { index, text ->

View File

@@ -19,6 +19,7 @@ package com.android.settings.wifi.details2;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -30,6 +31,10 @@ import com.android.settings.core.BasePreferenceController;
import com.android.wifi.flags.Flags;
import com.android.wifitrackerlib.WifiEntry;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_PREF_INDEX_DEVICE_MAC;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_PREF_INDEX_PER_NETWORK_RANDOMIZED_MAC;
/**
* A controller that controls whether the Wi-Fi network is mac randomized or not.
*/
@@ -95,9 +100,6 @@ public class WifiPrivacyPreferenceController2 extends BasePreferenceController i
return mWifiEntry.getPrivacy();
}
private static final int PREF_RANDOMIZATION_PERSISTENT = 0;
private static final int PREF_RANDOMIZATION_NONE = 1;
/**
* Translates a WifiEntry.Privacy value to the matching preference index value.
*
@@ -105,8 +107,13 @@ public class WifiPrivacyPreferenceController2 extends BasePreferenceController i
* @return index value of preference
*/
public static int translateWifiEntryPrivacyToPrefValue(@WifiEntry.Privacy int privacy) {
return (privacy == WifiEntry.PRIVACY_RANDOMIZED_MAC)
? PREF_RANDOMIZATION_PERSISTENT : PREF_RANDOMIZATION_NONE;
Log.d("WifiMacRnd", "translateMacRandomizedValueToPrefValue called from", new Throwable());
return switch (privacy) {
case WifiEntry.PRIVACY_RANDOMIZATION_ALWAYS -> PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC;
case WifiEntry.PRIVACY_RANDOMIZED_MAC -> PRIVACY_PREF_INDEX_PER_NETWORK_RANDOMIZED_MAC;
case WifiEntry.PRIVACY_DEVICE_MAC -> PRIVACY_PREF_INDEX_DEVICE_MAC;
default -> PRIVACY_PREF_INDEX_DEVICE_MAC;
};
}
/**
@@ -116,8 +123,13 @@ public class WifiPrivacyPreferenceController2 extends BasePreferenceController i
* @return WifiConfiguration.MacRandomizationSetting value
*/
public static int translatePrefValueToWifiConfigSetting(int prefMacRandomized) {
return (prefMacRandomized == PREF_RANDOMIZATION_PERSISTENT)
? WifiConfiguration.RANDOMIZATION_AUTO : WifiConfiguration.RANDOMIZATION_NONE;
Log.d("WifiMacRnd", "translatePrefValueToWifiConfigSetting called from", new Throwable());
return switch (prefMacRandomized) {
case PRIVACY_PREF_INDEX_DEVICE_MAC -> WifiConfiguration.RANDOMIZATION_NONE;
case PRIVACY_PREF_INDEX_PER_NETWORK_RANDOMIZED_MAC -> WifiConfiguration.RANDOMIZATION_PERSISTENT;
case PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC -> WifiConfiguration.RANDOMIZATION_ALWAYS;
default -> WifiConfiguration.RANDOMIZATION_ALWAYS;
};
}
private void updateSummary(ListPreference preference, int macRandomized) {

View File

@@ -16,11 +16,12 @@
package com.android.settings.wifi;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_SPINNER_INDEX_DEVICE_MAC;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_PREF_INDEX_DEVICE_MAC;
import static com.android.settings.wifi.WifiConfigController.PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC;
import static com.android.settings.wifi.WifiConfigController.DHCP_SPINNER_INDEX_SEND_DHCP_HOST_NAME_ENABLE;
import static com.android.settings.wifi.WifiConfigController.DHCP_SPINNER_INDEX_SEND_DHCP_HOST_NAME_DISABLE;
import static com.android.settings.wifi.details2.WifiPrivacyPreferenceController2.translateMacRandomizedValueToPrefValue;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
@@ -358,7 +359,7 @@ public class WifiConfigControllerTest {
assertThat(privacySetting.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(privacySetting.getSelectedItemPosition()).isEqualTo(
PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC);
PRIVACY_PREF_INDEX_PER_CONNECTION_RANDOMIZED_MAC);
}
@Test
@@ -383,8 +384,7 @@ public class WifiConfigControllerTest {
assertThat(privacySetting.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(privacySetting.getSelectedItemPosition()).isEqualTo(
macRandomizedValue == WifiConfiguration.RANDOMIZATION_PERSISTENT
? PRIVACY_SPINNER_INDEX_RANDOMIZED_MAC : PRIVACY_SPINNER_INDEX_DEVICE_MAC);
translateWifiEntryPrivacyToPrefValue(macRandomizedValue));
}
@Test
@@ -397,7 +397,7 @@ public class WifiConfigControllerTest {
@Test
public void saveMacRandomizedValue_ChangedToDeviceMac_shouldGetNone() {
final Spinner privacySetting = mView.findViewById(R.id.privacy_settings);
privacySetting.setSelection(PRIVACY_SPINNER_INDEX_DEVICE_MAC);
privacySetting.setSelection(PRIVACY_PREF_INDEX_DEVICE_MAC);
WifiConfiguration config = mController.getConfig();
assertThat(config.macRandomizationSetting).isEqualTo(WifiConfiguration.RANDOMIZATION_NONE);

View File

@@ -85,7 +85,7 @@ class WifiPrivacyPageProviderTest {
composeTestRule.setContent {
WifiPrivacyPage(mockWifiEntry)
}
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries)
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries_ext)
for (entry in wifiPrivacyEntries) {
composeTestRule.onNodeWithText(
entry
@@ -98,7 +98,7 @@ class WifiPrivacyPageProviderTest {
composeTestRule.setContent {
WifiPrivacyPage(mockWifiEntry)
}
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries)
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries_ext)
for (entry in wifiPrivacyEntries) {
composeTestRule.onNodeWithText(
entry
@@ -111,8 +111,8 @@ class WifiPrivacyPageProviderTest {
composeTestRule.setContent {
WifiPrivacyPage(mockWifiEntry)
}
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries)
val wifiPrivacyValues = context.resources.getStringArray(R.array.wifi_privacy_values)
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries_ext)
val wifiPrivacyValues = context.resources.getStringArray(R.array.wifi_privacy_values_ext)
composeTestRule.onNodeWithText(
wifiPrivacyEntries[wifiPrivacyValues.indexOf("0")]
).assertIsSelected()
@@ -126,7 +126,7 @@ class WifiPrivacyPageProviderTest {
composeTestRule.setContent {
WifiPrivacyPage(mockWifiEntry)
}
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries)
val wifiPrivacyEntries = context.resources.getStringArray(R.array.wifi_privacy_entries_ext)
for (entry in wifiPrivacyEntries) {
composeTestRule.onNodeWithText(entry).assertIsNotEnabled()
}
@@ -176,4 +176,4 @@ class WifiPrivacyPageProviderTest {
context.getString(R.string.wifi_privacy_send_device_name_toggle_title)
).assertIsOff()
}
}
}

View File

@@ -45,11 +45,11 @@ class WifiPrivacyPreferenceController2Test {
})
private var preference = ListPreference(context).apply {
setEntries(R.array.wifi_privacy_entries)
setEntryValues(R.array.wifi_privacy_values)
setEntries(R.array.wifi_privacy_entries_ext)
setEntryValues(R.array.wifi_privacy_values_ext)
}
private var preferenceStrings = context.resources.getStringArray(R.array.wifi_privacy_entries)
private var preferenceStrings = context.resources.getStringArray(R.array.wifi_privacy_entries_ext)
@Test
fun updateState_wifiPrivacy_setCorrectValue() {