wifi: Adding new API to indicate randomized MAC address

Returns persistent MAC address for the SoftApConfiguration.

Returns the persistent MAC randomization, even when the SoftAp
is configured to a use non-randomized or non-persistent randomized
MAC address. This is different from the WifiConfiguration equivalent
method which returns the latest randomized MAC address -
persistent or non-persistent.

Note: Started from R, Soft AP had been supporting MAC
ramdonization. So it is fine to add this API without SDK version
check. i.e. It allows to use it from R. (first mainlined version)

Note: Add multul exclusive check between BSSID and MAC randomization
Setting. It requires to configure MAC randomization Setting to NONE when
configuring BSSID.

Bug: 209325943
Bug: 215656264
Test: atest -c FrameworksWifiTests
Test: atest -c FrameworksWifiApiTests
Test: adb shell dumpsys platform_compat
Change-Id: Ia0691bffa4facaa98c69bf221f21945dd4add1fe
diff --git a/apex/Android.bp b/apex/Android.bp
index ad1a97e..c9d7936 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -23,6 +23,7 @@
     androidManifest: ":com.android.wifi-androidManifest",
     bootclasspath_fragments: ["com.android.wifi-bootclasspath-fragment"],
     systemserverclasspath_fragments: ["com.android.wifi-systemserverclasspath-fragment"],
+    compat_configs: ["wifi-compat-config"],
     // from build rule `cacerts_wfa`
     prebuilts: [
         "target-cacert-wifi-674b5f5b.0",
diff --git a/framework/Android.bp b/framework/Android.bp
index a547f2d..4b193f2 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -100,6 +100,7 @@
         "androidx.annotation_annotation",
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
         "framework-connectivity.stubs.module_lib",
+        "app-compat-annotations",
     ],
     aidl: {
         include_dirs: [
@@ -190,3 +191,9 @@
     name: "wifi-jarjar-rules",
     srcs: ["jarjar-rules.txt"],
 }
+
+platform_compat_config
+{
+    name: "wifi-compat-config",
+    src: ":framework-wifi-pre-jarjar",
+}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 71f4ea6..bb62f96 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -282,6 +282,7 @@
     method @NonNull public android.util.SparseIntArray getChannels();
     method public int getMacRandomizationSetting();
     method public int getMaxNumberOfClients();
+    method @NonNull public android.net.MacAddress getPersistentRandomizedMacAddress();
     method public long getShutdownTimeoutMillis();
     method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getVendorElements();
     method public boolean isAutoShutdownEnabled();
diff --git a/framework/java/android/net/wifi/SoftApConfiguration.java b/framework/java/android/net/wifi/SoftApConfiguration.java
index bfbb814..0e1b5b9 100644
--- a/framework/java/android/net/wifi/SoftApConfiguration.java
+++ b/framework/java/android/net/wifi/SoftApConfiguration.java
@@ -21,6 +21,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
 import android.net.MacAddress;
 import android.net.wifi.util.HexEncoding;
 import android.os.Build;
@@ -142,7 +145,12 @@
     private static final int MIN_CH_60G_BAND = 1;
     private static final int MAX_CH_60G_BAND = 6;
 
-
+    /**
+     * Requires to configure MAC randomization setting to None when configuring BSSID.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S)
+    private static final long FORCE_MUTUAL_EXCLUSIVE_BSSID_MAC_RAMDONIZATION_SETTING = 215656264L;
 
     private static boolean isChannelBandPairValid(int channel, @BandType int band) {
         switch (band) {
@@ -316,6 +324,12 @@
     private boolean mIsUserConfiguration;
 
     /**
+     * Randomized MAC address to use with this configuration when MAC randomization setting
+     * is {@link #RANDOMIZATION_PERSISTENT}.
+     */
+    private final @Nullable MacAddress mPersistentRandomizedMacAddress;
+
+    /**
      * Delay in milliseconds before shutting down an instance in bridged AP.
      */
     private final long mBridgedModeOpportunisticShutdownTimeoutMillis;
@@ -359,7 +373,8 @@
             int macRandomizationSetting, boolean bridgedModeOpportunisticShutdownEnabled,
             boolean ieee80211axEnabled, boolean ieee80211beEnabled, boolean isUserConfiguration,
             long bridgedModeOpportunisticShutdownTimeoutMillis,
-            @NonNull List<ScanResult.InformationElement> vendorElements) {
+            @NonNull List<ScanResult.InformationElement> vendorElements,
+            @Nullable MacAddress persistentRandomizedMacAddress) {
         mWifiSsid = ssid;
         mBssid = bssid;
         mPassphrase = passphrase;
@@ -385,6 +400,7 @@
         mBridgedModeOpportunisticShutdownTimeoutMillis =
                 bridgedModeOpportunisticShutdownTimeoutMillis;
         mVendorElements = new ArrayList<>(vendorElements);
+        mPersistentRandomizedMacAddress = persistentRandomizedMacAddress;
     }
 
     @Override
@@ -416,7 +432,9 @@
                 && mIsUserConfiguration == other.mIsUserConfiguration
                 && mBridgedModeOpportunisticShutdownTimeoutMillis
                         == other.mBridgedModeOpportunisticShutdownTimeoutMillis
-                && Objects.equals(mVendorElements, other.mVendorElements);
+                && Objects.equals(mVendorElements, other.mVendorElements)
+                && Objects.equals(mPersistentRandomizedMacAddress,
+                        other.mPersistentRandomizedMacAddress);
     }
 
     @Override
@@ -427,7 +445,7 @@
                 mAllowedClientList, mMacRandomizationSetting,
                 mBridgedModeOpportunisticShutdownEnabled, mIeee80211axEnabled, mIeee80211beEnabled,
                 mIsUserConfiguration, mBridgedModeOpportunisticShutdownTimeoutMillis,
-                mVendorElements);
+                mVendorElements, mPersistentRandomizedMacAddress);
     }
 
     @Override
@@ -455,6 +473,8 @@
         sbuf.append(" \n Ieee80211beEnabled = ").append(mIeee80211beEnabled);
         sbuf.append(" \n isUserConfiguration = ").append(mIsUserConfiguration);
         sbuf.append(" \n vendorElements = ").append(mVendorElements);
+        sbuf.append(" \n mPersistentRandomizedMacAddress = ")
+                .append(mPersistentRandomizedMacAddress);
         return sbuf.toString();
     }
 
@@ -479,6 +499,7 @@
         dest.writeBoolean(mIsUserConfiguration);
         dest.writeLong(mBridgedModeOpportunisticShutdownTimeoutMillis);
         dest.writeTypedList(mVendorElements);
+        dest.writeParcelable(mPersistentRandomizedMacAddress, flags);
     }
 
     /* Reference from frameworks/base/core/java/android/os/Parcel.java */
@@ -534,7 +555,8 @@
                     in.createTypedArrayList(MacAddress.CREATOR),
                     in.createTypedArrayList(MacAddress.CREATOR), in.readInt(), in.readBoolean(),
                     in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readLong(),
-                    in.createTypedArrayList(ScanResult.InformationElement.CREATOR));
+                    in.createTypedArrayList(ScanResult.InformationElement.CREATOR),
+                    in.readParcelable(MacAddress.class.getClassLoader()));
         }
 
         @Override
@@ -897,6 +919,20 @@
     }
 
     /**
+     * Returns the randomized MAC address to be used by this configuration.
+     *
+     * The Soft AP may be configured to use a persistent randomized MAC address with
+     * {@link Builder#setMacRandomizationSetting(int)}. This method returns the persistent
+     * randomized MAC address which will be used for the Soft AP controlled by this configuration.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @NonNull MacAddress getPersistentRandomizedMacAddress() {
+        return mPersistentRandomizedMacAddress;
+    }
+
+    /**
      * @hide
      */
     public boolean isUserConfigurationInternal() {
@@ -1017,6 +1053,7 @@
         private boolean mIsUserConfiguration;
         private long mBridgedModeOpportunisticShutdownTimeoutMillis;
         private List<ScanResult.InformationElement> mVendorElements;
+        private MacAddress mPersistentRandomizedMacAddress;
 
         /**
          * Constructs a Builder with default values (see {@link Builder}).
@@ -1046,6 +1083,7 @@
             mIsUserConfiguration = true;
             mBridgedModeOpportunisticShutdownTimeoutMillis = 0;
             mVendorElements = new ArrayList<>();
+            mPersistentRandomizedMacAddress = null;
         }
 
         /**
@@ -1075,6 +1113,7 @@
             mBridgedModeOpportunisticShutdownTimeoutMillis =
                     other.mBridgedModeOpportunisticShutdownTimeoutMillis;
             mVendorElements = new ArrayList<>(other.mVendorElements);
+            mPersistentRandomizedMacAddress = other.mPersistentRandomizedMacAddress;
         }
 
         /**
@@ -1089,13 +1128,22 @@
                     throw new IllegalArgumentException("A MacAddress exist in both client list");
                 }
             }
+
+            // mMacRandomizationSetting supported from S.
+            if (SdkLevel.isAtLeastS() && Compatibility.isChangeEnabled(
+                    FORCE_MUTUAL_EXCLUSIVE_BSSID_MAC_RAMDONIZATION_SETTING)
+                    && mBssid != null && mMacRandomizationSetting != RANDOMIZATION_NONE) {
+                throw new IllegalArgumentException("A BSSID had configured but MAC randomization"
+                        + " setting is not NONE");
+            }
             return new SoftApConfiguration(mWifiSsid, mBssid, mPassphrase,
                     mHiddenSsid, mChannels, mSecurityType, mMaxNumberOfClients,
                     mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser,
                     mBlockedClientList, mAllowedClientList, mMacRandomizationSetting,
                     mBridgedModeOpportunisticShutdownEnabled, mIeee80211axEnabled,
                     mIeee80211beEnabled, mIsUserConfiguration,
-                    mBridgedModeOpportunisticShutdownTimeoutMillis, mVendorElements);
+                    mBridgedModeOpportunisticShutdownTimeoutMillis, mVendorElements,
+                    mPersistentRandomizedMacAddress);
         }
 
         /**
@@ -1185,6 +1233,9 @@
          * <p>
          * <li>If not set, defaults to null.</li>
          *
+         * When this method is called, the caller needs to configure MAC randomization settings to
+         * {@link #RANDOMIZATION_NONE}. See {@link #setMacRandomizationSetting(int)} for details.
+         *
          * If multiple bands are requested via {@link #setBands(int[])} or
          * {@link #setChannels(SparseIntArray)}, HAL will derive 2 MAC addresses since framework
          * only sends down 1 MAC address.
@@ -1633,7 +1684,9 @@
          * The Soft AP BSSID will be randomized only if the BSSID isn't set
          * {@link #setBssid(MacAddress)} and this method is either uncalled
          * or called with {@link #RANDOMIZATION_PERSISTENT} or
-         * {@link #RANDOMIZATION_NON_PERSISTENT}.
+         * {@link #RANDOMIZATION_NON_PERSISTENT}. When this method is called with
+         * {@link #RANDOMIZATION_PERSISTENT} or {@link #RANDOMIZATION_NON_PERSISTENT}, the caller
+         * the caller must not call {@link #setBssid(MacAddress)}.
          *
          * <p>
          * <li>If not set, defaults to {@link #RANDOMIZATION_NON_PERSISTENT}</li>
@@ -1804,5 +1857,19 @@
             mBridgedModeOpportunisticShutdownTimeoutMillis = timeoutMillis;
             return this;
         }
+
+        /**
+         * @param mac persistent randomized MacAddress generated by the frameworks.
+         * @hide
+         */
+        @NonNull
+        public Builder setRandomizedMacAddress(@NonNull MacAddress mac) {
+            if (mac == null) {
+                throw new IllegalArgumentException("setRandomizedMacAddress received"
+                        + " null MacAddress.");
+            }
+            mPersistentRandomizedMacAddress = mac;
+            return this;
+        }
     }
 }
diff --git a/framework/tests/src/android/net/wifi/SoftApConfigurationTest.java b/framework/tests/src/android/net/wifi/SoftApConfigurationTest.java
index 59e06a9..b801219 100644
--- a/framework/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/framework/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -20,6 +20,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
@@ -95,17 +96,16 @@
         String utf8Ssid = "ssid";
         SoftApConfiguration original = new SoftApConfiguration.Builder()
                 .setSsid(utf8Ssid)
-                .setBssid(testBssid)
                 .build();
         assertThat(original.getSsid()).isEqualTo(utf8Ssid);
         assertThat(original.getWifiSsid()).isEqualTo(WifiSsid.fromUtf8Text(utf8Ssid));
-        assertThat(original.getBssid()).isEqualTo(testBssid);
         assertThat(original.getPassphrase()).isNull();
         assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN);
         assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ);
         assertThat(original.getChannel()).isEqualTo(0);
         assertThat(original.isHiddenSsid()).isEqualTo(false);
         assertThat(original.getMaxNumberOfClients()).isEqualTo(0);
+        assertThat(original.getPersistentRandomizedMacAddress()).isNull();
         if (SdkLevel.isAtLeastS()) {
             assertThat(original.isBridgedModeOpportunisticShutdownEnabled())
                     .isEqualTo(true);
@@ -195,6 +195,7 @@
 
     @Test
     public void testWpa2WithAllFieldCustomized() {
+        MacAddress testRandomizedMacAddress = MacAddress.fromString(TEST_BSSID);
         List<MacAddress> testBlockedClientList = new ArrayList<>();
         List<MacAddress> testAllowedClientList = new ArrayList<>();
         testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66"));
@@ -208,7 +209,8 @@
                 .setShutdownTimeoutMillis(500000)
                 .setClientControlByUserEnabled(true)
                 .setBlockedClientList(testBlockedClientList)
-                .setAllowedClientList(testAllowedClientList);
+                .setAllowedClientList(testAllowedClientList)
+                .setRandomizedMacAddress(testRandomizedMacAddress);
         if (SdkLevel.isAtLeastS()) {
             originalBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
             originalBuilder.setBridgedModeOpportunisticShutdownEnabled(false);
@@ -234,6 +236,8 @@
         assertThat(original.isClientControlByUserEnabled()).isEqualTo(true);
         assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList);
         assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList);
+        assertThat(original.getPersistentRandomizedMacAddress())
+                .isEqualTo(testRandomizedMacAddress);
         if (SdkLevel.isAtLeastS()) {
             assertThat(original.getMacRandomizationSetting())
                     .isEqualTo(SoftApConfiguration.RANDOMIZATION_NONE);
@@ -636,4 +640,43 @@
                 .setVendorElements(dupElements)
                 .build();
     }
+
+    @Test
+    // TODO: b/216875688 enable it after updating target SDK build version
+    // (expected = IllegalArgumentException.class)
+    public void testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsPersistent() {
+        assumeTrue(SdkLevel.isAtLeastS());
+        MacAddress testBssid = MacAddress.fromString(TEST_BSSID);
+        SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToPersistent =
+                new SoftApConfiguration.Builder()
+                .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_PERSISTENT)
+                .setBssid(testBssid)
+                .build();
+    }
+
+    @Test
+    // TODO: b/216875688 enable it after updating target SDK build version
+    // (expected = IllegalArgumentException.class)
+    public void testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsNonPersistent() {
+        assumeTrue(SdkLevel.isAtLeastS());
+        MacAddress testBssid = MacAddress.fromString(TEST_BSSID);
+        SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToNonPersistent =
+                new SoftApConfiguration.Builder()
+                .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NON_PERSISTENT)
+                .setBssid(testBssid)
+                .build();
+    }
+
+    @Test
+    public void testSetBssidSucceededWWithDisableMacRandomizationSetting() {
+        assumeTrue(SdkLevel.isAtLeastS());
+        MacAddress testBssid = MacAddress.fromString(TEST_BSSID);
+        SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToNone =
+                new SoftApConfiguration.Builder()
+                .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE)
+                .setBssid(testBssid)
+                .build();
+        assertEquals(config_setBssidAfterSetMacRandomizationSettingToNone.getBssid(),
+                testBssid);
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 4c65ab9..fde0f76 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -142,6 +142,7 @@
             Log.d(TAG, "persisted config was converted, need to resave it");
             persistConfigAndTriggerBackupManagerProxy(sanitizedPersistentconfig);
         }
+
         if (mForceApChannel) {
             Log.d(TAG, "getApConfiguration: Band force to " + mForcedApBand
                     + ", and channel force to " + mForcedApChannel);
@@ -151,7 +152,7 @@
                     : new SoftApConfiguration.Builder(mPersistentWifiApConfig)
                             .setChannel(mForcedApChannel, mForcedApBand).build();
         }
-        return mPersistentWifiApConfig;
+        return updatePersistentRandomizedMacAddress(mPersistentWifiApConfig);
     }
 
     /**
@@ -451,12 +452,11 @@
                 configBuilder.setBand(SoftApConfiguration.BAND_5GHZ);
             }
         }
-
         if (customConfig == null || customConfig.getSsid() == null) {
             configBuilder.setSsid(generateLohsSsid(context));
         }
 
-        return configBuilder.build();
+        return updatePersistentRandomizedMacAddress(configBuilder.build());
     }
 
     /**
@@ -484,6 +484,9 @@
                 macAddress = MacAddressUtils.createRandomUnicastAddress();
             }
             configBuilder.setBssid(macAddress);
+            if (macAddress != null && SdkLevel.isAtLeastS()) {
+                configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+            }
         }
         return configBuilder.build();
     }
@@ -643,4 +646,14 @@
     public void disableForceSoftApBandOrChannel() {
         mForceApChannel = false;
     }
+
+    private SoftApConfiguration updatePersistentRandomizedMacAddress(SoftApConfiguration config) {
+        // Update randomized MacAddress
+        WifiSsid ssid = config.getWifiSsid();
+        MacAddress randomizedMacAddress = mMacAddressUtil.calculatePersistentMac(
+                ssid != null ? ssid.toString() : null,
+                mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID));
+        return new SoftApConfiguration.Builder(config)
+                .setRandomizedMacAddress(randomizedMacAddress).build();
+    }
 }
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index afd9e31..7b954fd 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -2072,6 +2072,11 @@
                                 migrationData.isSoftApTimeoutEnabled());
                     }
                 }
+                if (bssid != null && SdkLevel.isAtLeastS()) {
+                    // Force MAC randomization setting to none when BSSID is configured
+                    softApConfigBuilder.setMacRandomizationSetting(
+                            SoftApConfiguration.RANDOMIZATION_NONE);
+                }
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "Failed to parse configuration " + e);
                 return null;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index c00bede..dd97dec 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -1846,6 +1846,9 @@
         configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
         configBuilder.setSsid(TEST_SSID);
         configBuilder.setBssid(TEST_CLIENT_MAC_ADDRESS);
+        if (SdkLevel.isAtLeastS()) {
+            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
         SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
                 IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability);
         ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
@@ -1863,6 +1866,9 @@
         configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
         configBuilder.setSsid(TEST_SSID);
         configBuilder.setBssid(TEST_CLIENT_MAC_ADDRESS);
+        if (SdkLevel.isAtLeastS()) {
+            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
         SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
                 IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability);
         ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
@@ -1881,6 +1887,9 @@
         configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
         configBuilder.setSsid(TEST_SSID);
         configBuilder.setBssid(TEST_CLIENT_MAC_ADDRESS);
+        if (SdkLevel.isAtLeastS()) {
+            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
         SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
                 IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability);
         ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
@@ -1896,9 +1905,14 @@
 
     @Test
     public void setMacFailureWhenRandomMac() throws Exception {
-        SoftApConfiguration randomizedBssidConfig =
+        SoftApConfiguration.Builder randomizedBssidConfigBuilder =
                 new SoftApConfiguration.Builder(mDefaultApConfig)
-                .setBssid(TEST_CLIENT_MAC_ADDRESS).build();
+                .setBssid(TEST_CLIENT_MAC_ADDRESS);
+        if (SdkLevel.isAtLeastS()) {
+            randomizedBssidConfigBuilder.setMacRandomizationSetting(
+                    SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        SoftApConfiguration randomizedBssidConfig = randomizedBssidConfigBuilder.build();
         when(mWifiApConfigStore.randomizeBssidIfUnset(any(), any())).thenReturn(
                 randomizedBssidConfig);
         SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
@@ -2029,9 +2043,14 @@
         if (expectedConfig == null) {
             if (config == null) {
                 // Only generate randomized mac for default config since test case doesn't care it.
-                randomizedBssidConfig =
+                SoftApConfiguration.Builder randomizedBssidConfigBuilder =
                         new SoftApConfiguration.Builder(mDefaultApConfig)
-                        .setBssid(TEST_INTERFACE_MAC_ADDRESS).build();
+                        .setBssid(TEST_INTERFACE_MAC_ADDRESS);
+                if (SdkLevel.isAtLeastS()) {
+                    randomizedBssidConfigBuilder.setMacRandomizationSetting(
+                            SoftApConfiguration.RANDOMIZATION_NONE);
+                }
+                randomizedBssidConfig = randomizedBssidConfigBuilder.build();
                 when(mWifiApConfigStore.randomizeBssidIfUnset(any(), any())).thenReturn(
                         randomizedBssidConfig);
                 expectedConfig = new SoftApConfiguration.Builder(randomizedBssidConfig)
@@ -2415,8 +2434,13 @@
     @Test
     public void testBssidUpdatedWhenSoftApInfoUpdate() throws Exception {
         MacAddress testBssid = MacAddress.fromString("aa:bb:cc:11:22:33");
-        SoftApConfiguration customizedBssidConfig = new SoftApConfiguration
-                .Builder(mDefaultApConfig).setBssid(testBssid).build();
+        SoftApConfiguration.Builder customizedBssidConfigBuilder = new SoftApConfiguration
+                .Builder(mDefaultApConfig).setBssid(testBssid);
+        if (SdkLevel.isAtLeastS()) {
+            customizedBssidConfigBuilder.setMacRandomizationSetting(
+                    SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        SoftApConfiguration customizedBssidConfig = customizedBssidConfigBuilder.build();
         when(mWifiNative.setApMacAddress(eq(TEST_INTERFACE_NAME), eq(testBssid))).thenReturn(true);
         mTestSoftApInfo.setBssid(testBssid);
         InOrder order = inOrder(mCallback, mWifiMetrics);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 198eb35..0eba844 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -636,9 +636,13 @@
     @Test
     public void generateLohsConfig_forwardsCustomMac() throws Exception {
         WifiApConfigStore store = createWifiApConfigStore();
-        SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
-                .setBssid(TEST_SAP_BSSID_MAC)
-                .build();
+        SoftApConfiguration.Builder customConfigBuilder = new SoftApConfiguration.Builder()
+                .setBssid(TEST_SAP_BSSID_MAC);
+        if (SdkLevel.isAtLeastS()) {
+            customConfigBuilder.setMacRandomizationSetting(
+                    SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        SoftApConfiguration customConfig = customConfigBuilder.build();
         SoftApConfiguration softApConfig = store.generateLocalOnlyHotspotConfig(
                 mContext, customConfig, mSoftApCapability);
         assertThat(softApConfig.getBssid().toString()).isNotEmpty();
@@ -716,6 +720,9 @@
         mResources.setBoolean(R.bool.config_wifi_ap_mac_randomization_supported, true);
         Builder baseConfigBuilder = new SoftApConfiguration.Builder();
         baseConfigBuilder.setBssid(TEST_SAP_BSSID_MAC);
+        if (SdkLevel.isAtLeastS()) {
+            baseConfigBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
 
         WifiApConfigStore store = createWifiApConfigStore();
         SoftApConfiguration config = store.randomizeBssidIfUnset(mContext,
@@ -1104,9 +1111,14 @@
     @Test
     public void testBssidDenyIfCallerWithoutPrivileged() throws Exception {
         WifiApConfigStore store = createWifiApConfigStore();
-        SoftApConfiguration config = new SoftApConfiguration.Builder(store.getApConfiguration())
-                .setBssid(TEST_SAP_BSSID_MAC).build();
-        assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, false, mContext));
+        SoftApConfiguration.Builder configBuilder =
+                new SoftApConfiguration.Builder(store.getApConfiguration())
+                .setBssid(TEST_SAP_BSSID_MAC);
+        if (SdkLevel.isAtLeastS()) {
+            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        assertFalse(WifiApConfigStore.validateApWifiConfiguration(configBuilder.build(),
+                false, mContext));
     }
 
     /**
@@ -1115,9 +1127,14 @@
     @Test
     public void testBssidAllowIfCallerOwnPrivileged() throws Exception {
         WifiApConfigStore store = createWifiApConfigStore();
-        SoftApConfiguration config = new SoftApConfiguration.Builder(store.getApConfiguration())
-                .setBssid(TEST_SAP_BSSID_MAC).build();
-        assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+        SoftApConfiguration.Builder configBuilder =
+                new SoftApConfiguration.Builder(store.getApConfiguration())
+                .setBssid(TEST_SAP_BSSID_MAC);
+        if (SdkLevel.isAtLeastS()) {
+            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        assertTrue(WifiApConfigStore.validateApWifiConfiguration(configBuilder.build(),
+                true, mContext));
     }
 
     @Test
@@ -1273,4 +1290,13 @@
         verifyUpgradeConfiguration(store, true, false);
         verifyUpgradeConfiguration(store, false, false);
     }
+
+    @Test
+    public void testRandomizedMacAddress() throws Exception {
+        WifiApConfigStore store = createWifiApConfigStore();
+        assertNotNull(store.getApConfiguration().getPersistentRandomizedMacAddress());
+        assertNotNull(store.generateLocalOnlyHotspotConfig(mContext, null, mSoftApCapability));
+        assertNotNull(store.generateLocalOnlyHotspotConfig(mContext, store.getApConfiguration(),
+                mSoftApCapability));
+    }
 }
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 86980d0..6889787 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -3430,9 +3430,14 @@
     public void testCustomLohs_ForwardsBssid() {
         mLooper.startAutoDispatch();
         SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
-        SoftApConfiguration customizedConfig = new SoftApConfiguration.Builder(lohsConfig)
-                .setBssid(MacAddress.fromString("aa:bb:cc:dd:ee:ff"))
-                .build();
+        SoftApConfiguration.Builder customizedConfigBuilder =
+                new SoftApConfiguration.Builder(lohsConfig)
+                .setBssid(MacAddress.fromString("aa:bb:cc:dd:ee:ff"));
+        if (SdkLevel.isAtLeastS()) {
+            customizedConfigBuilder.setMacRandomizationSetting(
+                    SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        SoftApConfiguration customizedConfig = customizedConfigBuilder.build();
         when(mWifiApConfigStore.generateLocalOnlyHotspotConfig(
                 eq(mContext), eq(customizedConfig), any()))
                 .thenReturn(customizedConfig);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
index acdbbb2..5145f24 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
@@ -660,9 +660,15 @@
         assertTrue(ApConfigUtil.checkConfigurationChangeNeedToRestart(currentConfig,
                 newConfig_ssidChanged));
         // Test BSSID changed
-        SoftApConfiguration newConfig_bssidChanged = new SoftApConfiguration
+        SoftApConfiguration.Builder newConfig_bssidChangedBuilder = new SoftApConfiguration
                 .Builder(newConfig_noChange)
-                .setBssid(testBssid).build();
+                .setBssid(testBssid);
+
+        if (SdkLevel.isAtLeastS()) {
+            newConfig_bssidChangedBuilder.setMacRandomizationSetting(
+                    SoftApConfiguration.RANDOMIZATION_NONE);
+        }
+        SoftApConfiguration newConfig_bssidChanged = newConfig_bssidChangedBuilder.build();
         assertTrue(ApConfigUtil.checkConfigurationChangeNeedToRestart(currentConfig,
                 newConfig_bssidChanged));
         // Test Passphrase Changed