Merge changes from topic "lohs_sap_config"

* changes:
  wifi: Fix java doc error, use @code instead of @link
  softap: Update LOHS API usage
  SoftAp: Public SoftApConfiguration to replace WifiConfiguration
diff --git a/api/current.txt b/api/current.txt
index 1210d62..7469299 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30508,6 +30508,21 @@
     field public CharSequence venueName;
   }
 
+  public final class SoftApConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.net.MacAddress getBssid();
+    method @Nullable public String getPassphrase();
+    method public int getSecurityType();
+    method @Nullable public String getSsid();
+    method public boolean isHiddenSsid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
+    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
+    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
+    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
+    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
+  }
+
   public enum SupplicantState implements android.os.Parcelable {
     method public int describeContents();
     method public static boolean isValidState(android.net.wifi.SupplicantState);
@@ -30842,7 +30857,8 @@
 
   public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
     method public void close();
-    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
+    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
+    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
   }
 
   public class WifiManager.MulticastLock {
diff --git a/api/system-current.txt b/api/system-current.txt
index 9c53f80..cb4c4b7 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6113,29 +6113,17 @@
   }
 
   public final class SoftApConfiguration implements android.os.Parcelable {
-    method public int describeContents();
     method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
     method public int getBand();
     method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
-    method @Nullable public android.net.MacAddress getBssid();
     method public int getChannel();
     method public int getMaxNumberOfClients();
-    method @Nullable public String getPassphrase();
-    method public int getSecurityType();
     method public int getShutdownTimeoutMillis();
-    method @Nullable public String getSsid();
     method public boolean isClientControlByUserEnabled();
-    method public boolean isHiddenSsid();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int BAND_2GHZ = 1; // 0x1
     field public static final int BAND_5GHZ = 2; // 0x2
     field public static final int BAND_6GHZ = 4; // 0x4
     field public static final int BAND_ANY = 7; // 0x7
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
-    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
-    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
-    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
-    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
   }
 
   public static final class SoftApConfiguration.Builder {
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
index b83b594..b567f29 100644
--- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
+++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
@@ -16,7 +16,7 @@
 
 package android.net.wifi;
 
-import android.net.wifi.WifiConfiguration;
+import android.net.wifi.SoftApConfiguration;
 
 /**
  * Communicates LOHS status back to the application process.
@@ -24,7 +24,7 @@
  * @hide
  */
 oneway interface ILocalOnlyHotspotCallback {
-    void onHotspotStarted(in WifiConfiguration config);
+    void onHotspotStarted(in SoftApConfiguration config);
     void onHotspotStopped();
     void onHotspotFailed(int reason);
 }
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index a77d30a..49fb5a3 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -36,7 +36,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
-import java.util.concurrent.Executor;
 
 /**
  * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot).
@@ -45,22 +44,21 @@
  * framework how it should configure a hotspot.
  *
  * System apps can use this to configure a tethered hotspot using
- * {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} and
- * {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)}
+ * {@code WifiManager#startTetheredHotspot(SoftApConfiguration)} and
+ * {@code WifiManager#setSoftApConfiguration(SoftApConfiguration)}
  * or local-only hotspot using
- * {@link WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
+ * {@code WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
  * WifiManager.LocalOnlyHotspotCallback)}.
  *
  * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to
  * create a new instance.
  *
- * @hide
  */
-@SystemApi
 public final class SoftApConfiguration implements Parcelable {
 
     @VisibleForTesting
     static final int PSK_MIN_LEN = 8;
+
     @VisibleForTesting
     static final int PSK_MAX_LEN = 63;
 
@@ -207,22 +205,24 @@
     private final int mShutdownTimeoutMillis;
 
     /**
-     * Security types we support.
+     * THe definition of security type OPEN.
      */
-    /** @hide */
-    @SystemApi
     public static final int SECURITY_TYPE_OPEN = 0;
 
-    /** @hide */
-    @SystemApi
+
+    /**
+     * The definition of security type WPA2-PSK.
+     */
     public static final int SECURITY_TYPE_WPA2_PSK = 1;
 
-    /** @hide */
-    @SystemApi
+    /**
+     * The definition of security type WPA3-SAE Transition mode.
+     */
     public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2;
 
-    /** @hide */
-    @SystemApi
+    /**
+     * The definition of security type WPA3-SAE.
+     */
     public static final int SECURITY_TYPE_WPA3_SAE = 3;
 
     /** @hide */
@@ -346,7 +346,7 @@
 
     /**
      * Return String set to be the SSID for the AP.
-     * {@link #setSsid(String)}.
+     * {@link Builder#setSsid(String)}.
      */
     @Nullable
     public String getSsid() {
@@ -364,7 +364,7 @@
 
     /**
      * Returns String set to be passphrase for current AP.
-     * {@link #setPassphrase(String, @SecurityType int)}.
+     * {@link Builder#setPassphrase(String, int)}.
      */
     @Nullable
     public String getPassphrase() {
@@ -383,7 +383,10 @@
     /**
      * Returns {@link BandType} set to be the band for the AP.
      * {@link Builder#setBand(@BandType int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public @BandType int getBand() {
         return mBand;
     }
@@ -391,7 +394,10 @@
     /**
      * Returns Integer set to be the channel for the AP.
      * {@link Builder#setChannel(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getChannel() {
         return mChannel;
     }
@@ -408,7 +414,10 @@
     /**
      * Returns the maximum number of clients that can associate to the AP.
      * {@link Builder#setMaxNumberOfClients(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getMaxNumberOfClients() {
         return mMaxNumberOfClients;
     }
@@ -417,7 +426,10 @@
      * Returns the shutdown timeout in milliseconds.
      * The Soft AP will shutdown when there are no devices associated to it for
      * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(int)}.
+     *
+     * @hide
      */
+    @SystemApi
     public int getShutdownTimeoutMillis() {
         return mShutdownTimeoutMillis;
     }
@@ -426,7 +438,10 @@
      * Returns a flag indicating whether clients need to be pre-approved by the user.
      * (true: authorization required) or not (false: not required).
      * {@link Builder#enableClientControlByUser(Boolean)}.
+     *
+     * @hide
      */
+    @SystemApi
     public boolean isClientControlByUserEnabled() {
         return mClientControlByUser;
     }
@@ -435,8 +450,11 @@
      * Returns List of clients which aren't allowed to associate to the AP.
      *
      * Clients are configured using {@link Builder#setClientList(List, List)}
+     *
+     * @hide
      */
     @NonNull
+    @SystemApi
     public List<MacAddress> getBlockedClientList() {
         return mBlockedClientList;
     }
@@ -444,8 +462,11 @@
     /**
      * List of clients which are allowed to associate to the AP.
      * Clients are configured using {@link Builder#setClientList(List, List)}
+     *
+     * @hide
      */
     @NonNull
+    @SystemApi
     public List<MacAddress> getAllowedClientList() {
         return mAllowedClientList;
     }
@@ -456,7 +477,10 @@
      *
      * All fields are optional. By default, SSID and BSSID are automatically chosen by the
      * framework, and an open network is created.
+     *
+     * @hide
      */
+    @SystemApi
     public static final class Builder {
         private String mSsid;
         private MacAddress mBssid;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 64d4eaf..64e6135 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2971,7 +2971,7 @@
      * Each application can make a single active call to this method. The {@link
      * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
      * requestor with a {@link LocalOnlyHotspotReservation} that contains a
-     * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect
+     * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
      * to the hotspot.  Communicating this information is up to the application.
      * <p>
      * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
@@ -3136,7 +3136,7 @@
      * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes.  Callers will
      * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
      * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
-     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and
+     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
      * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
      * <p>
      * Applications should have the
@@ -3711,13 +3711,13 @@
     }
 
     /**
-     * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active
+     * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
      * LocalOnlyHotspot request.
      * <p>
      * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
      * LocalOnlyHotspotReservation in the
      * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call.  This
-     * reservation contains the relevant {@link WifiConfiguration}.
+     * reservation contains the relevant {@link SoftApConfiguration}.
      * When an application is done with the LocalOnlyHotspot, they should call {@link
      * LocalOnlyHotspotReservation#close()}.  Once this happens, the application will not receive
      * any further callbacks. If the LocalOnlyHotspot is stopped due to a
@@ -3727,20 +3727,71 @@
     public class LocalOnlyHotspotReservation implements AutoCloseable {
 
         private final CloseGuard mCloseGuard = new CloseGuard();
-        private final WifiConfiguration mConfig;
+        private final SoftApConfiguration mConfig;
         private boolean mClosed = false;
 
         /** @hide */
         @VisibleForTesting
-        public LocalOnlyHotspotReservation(WifiConfiguration config) {
+        public LocalOnlyHotspotReservation(SoftApConfiguration config) {
             mConfig = config;
             mCloseGuard.open("close");
         }
 
+        /**
+         * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
+         * May be null if hotspot enabled and security type is not
+         * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}.
+         *
+         * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the
+         * LOHS configuration.
+         */
+        @Deprecated
+        @Nullable
         public WifiConfiguration getWifiConfiguration() {
+            return convertToWifiConfiguration(mConfig);
+        }
+
+        /**
+         * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS).
+         */
+        @NonNull
+        public SoftApConfiguration getSoftApConfiguration() {
             return mConfig;
         }
 
+        /**
+         * Convert to WifiConfiguration from SoftApConfuration.
+         *
+         * Copy to the filed which is public and used by SoftAp.
+         */
+        private WifiConfiguration convertToWifiConfiguration(SoftApConfiguration softApConfig) {
+            if (softApConfig == null) return null;
+
+            WifiConfiguration wifiConfig = new WifiConfiguration();
+            wifiConfig.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID;
+            wifiConfig.SSID = softApConfig.getSsid();
+            if (softApConfig.getBssid() != null) {
+                wifiConfig.BSSID = softApConfig.getBssid().toString();
+            }
+            wifiConfig.preSharedKey = softApConfig.getPassphrase();
+            wifiConfig.hiddenSSID = softApConfig.isHiddenSsid();
+            int authType = softApConfig.getSecurityType();
+            switch (authType) {
+                case SoftApConfiguration.SECURITY_TYPE_OPEN:
+                    authType = WifiConfiguration.KeyMgmt.NONE;
+                    wifiConfig.allowedKeyManagement.set(authType);
+                    break;
+                case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
+                    authType = WifiConfiguration.KeyMgmt.WPA2_PSK;
+                    wifiConfig.allowedKeyManagement.set(authType);
+                    break;
+                default:
+                    wifiConfig = null;
+                    break;
+            }
+            return wifiConfig;
+        }
+
         @Override
         public void close() {
             try {
@@ -3835,7 +3886,7 @@
         }
 
         @Override
-        public void onHotspotStarted(WifiConfiguration config) {
+        public void onHotspotStarted(SoftApConfiguration config) {
             WifiManager manager = mWifiManager.get();
             if (manager == null) return;
 
@@ -3927,7 +3978,7 @@
         /**
          * LocalOnlyHotspot started with the supplied config.
          */
-        public void onStarted(WifiConfiguration config) {};
+        public void onStarted(SoftApConfiguration config) {};
 
         /**
          * LocalOnlyHotspot stopped.
@@ -3967,7 +4018,7 @@
         }
 
         @Override
-        public void onHotspotStarted(WifiConfiguration config) {
+        public void onHotspotStarted(SoftApConfiguration config) {
             WifiManager manager = mWifiManager.get();
             if (manager == null) return;
 
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 1ee5374..738c633 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -106,6 +106,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -148,6 +149,50 @@
     private ScanResultsCallback mScanResultsCallback;
     private WifiActivityEnergyInfo mWifiActivityEnergyInfo;
 
+    /**
+     * Util function to check public field which used for softap  in WifiConfiguration
+     * same as the value in SoftApConfiguration.
+     *
+     */
+    private boolean compareWifiAndSoftApConfiguration(
+            SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
+        if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
+            return false;
+        }
+        if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
+            return false;
+        }
+        if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
+            return false;
+        }
+
+        if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
+            return false;
+        }
+        switch (softApConfig.getSecurityType()) {
+            case SoftApConfiguration.SECURITY_TYPE_OPEN:
+                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
+                    return false;
+                }
+                break;
+            case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
+                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
+                    return false;
+                }
+                break;
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    private SoftApConfiguration generatorTestSoftApConfig() {
+        return new SoftApConfiguration.Builder()
+                .setSsid("TestSSID")
+                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                .build();
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -212,12 +257,12 @@
      */
     @Test
     public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
-        SoftApConfiguration mSoftApConfig = new SoftApConfiguration.Builder().build();
-        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(true);
-        assertTrue(mWifiManager.startTetheredHotspot(mSoftApConfig));
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
+        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
+        assertTrue(mWifiManager.startTetheredHotspot(softApConfig));
 
-        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(false);
-        assertFalse(mWifiManager.startTetheredHotspot(mSoftApConfig));
+        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
+        assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
     }
 
     /**
@@ -239,14 +284,18 @@
      */
     @Test
     public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                 nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
+        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
 
-        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
+
         callback.mRes.close();
         verify(mWifiService).stopLocalOnlyHotspot();
     }
@@ -257,15 +306,18 @@
     @Test
     public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
             throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                 nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
 
-        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
+        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));
 
         try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
-            assertEquals(mApConfig, res.getWifiConfiguration());
+            assertEquals(softApConfig, res.getSoftApConfiguration());
+            WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+            assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
         }
 
         verify(mWifiService).stopLocalOnlyHotspot();
@@ -315,6 +367,7 @@
      */
     @Test
     public void testLocalOnlyHotspotCallback() {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         assertFalse(callback.mOnStartedCalled);
         assertFalse(callback.mOnStoppedCalled);
@@ -323,7 +376,7 @@
 
         // test onStarted
         WifiManager.LocalOnlyHotspotReservation res =
-                mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
+                mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
         callback.onStarted(res);
         assertEquals(res, callback.mRes);
         assertTrue(callback.mOnStartedCalled);
@@ -349,7 +402,7 @@
         public boolean mOnRegistered = false;
         public boolean mOnStartedCalled = false;
         public boolean mOnStoppedCalled = false;
-        public WifiConfiguration mConfig = null;
+        public SoftApConfiguration mConfig = null;
         public LocalOnlyHotspotSubscription mSub = null;
         public long mCallingThreadId = -1;
 
@@ -361,7 +414,7 @@
         }
 
         @Override
-        public void onStarted(WifiConfiguration config) {
+        public void onStarted(SoftApConfiguration config) {
             mOnStartedCalled = true;
             mConfig = config;
             mCallingThreadId = Thread.currentThread().getId();
@@ -380,6 +433,7 @@
     @Test
     public void testLocalOnlyHotspotObserver() {
         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         assertFalse(observer.mOnRegistered);
         assertFalse(observer.mOnStartedCalled);
         assertFalse(observer.mOnStoppedCalled);
@@ -395,18 +449,18 @@
         assertEquals(null, observer.mConfig);
         assertEquals(sub, observer.mSub);
 
-        observer.onStarted(mApConfig);
+        observer.onStarted(softApConfig);
         assertTrue(observer.mOnRegistered);
         assertTrue(observer.mOnStartedCalled);
         assertFalse(observer.mOnStoppedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
         assertEquals(sub, observer.mSub);
 
         observer.onStopped();
         assertTrue(observer.mOnRegistered);
         assertTrue(observer.mOnStartedCalled);
         assertTrue(observer.mOnStoppedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
         assertEquals(sub, observer.mSub);
     }
 
@@ -488,6 +542,7 @@
      */
     @Test
     public void testOnStartedIsCalledWithReservation() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         TestLooper callbackLooper = new TestLooper();
         Handler callbackHandler = new Handler(callbackLooper.getLooper());
@@ -501,11 +556,44 @@
         assertFalse(callback.mOnStartedCalled);
         assertEquals(null, callback.mRes);
         // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(mApConfig);
+        internalCallback.getValue().onHotspotStarted(softApConfig);
         mLooper.dispatchAll();
         callbackLooper.dispatchAll();
         assertTrue(callback.mOnStartedCalled);
-        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
+        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
+    }
+
+    /**
+     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
+     * message from WifiServiceImpl when softap enabled with SAE security type.
+     */
+    @Test
+    public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
+        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
+                .setSsid("TestSSID")
+                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
+                .build();
+        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
+        TestLooper callbackLooper = new TestLooper();
+        Handler callbackHandler = new Handler(callbackLooper.getLooper());
+        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
+                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
+        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
+        callbackLooper.dispatchAll();
+        mLooper.dispatchAll();
+        assertFalse(callback.mOnStartedCalled);
+        assertEquals(null, callback.mRes);
+        // now trigger the callback
+        internalCallback.getValue().onHotspotStarted(softApConfig);
+        mLooper.dispatchAll();
+        callbackLooper.dispatchAll();
+        assertTrue(callback.mOnStartedCalled);
+        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
+        assertEquals(null, callback.mRes.getWifiConfiguration());
     }
 
     /**
@@ -1037,6 +1125,7 @@
      */
     @Test
     public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
+        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
         TestLooper observerLooper = new TestLooper();
         Handler observerHandler = new Handler(observerLooper.getLooper());
@@ -1048,11 +1137,11 @@
         mLooper.dispatchAll();
         assertFalse(observer.mOnStartedCalled);
         // now trigger the callback
-        internalCallback.getValue().onHotspotStarted(mApConfig);
+        internalCallback.getValue().onHotspotStarted(softApConfig);
         mLooper.dispatchAll();
         observerLooper.dispatchAll();
         assertTrue(observer.mOnStartedCalled);
-        assertEquals(mApConfig, observer.mConfig);
+        assertEquals(softApConfig, observer.mConfig);
     }
 
     /**
@@ -1248,7 +1337,7 @@
      */
     @Test
     public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
-        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
+        SoftApConfiguration apConfig = generatorTestSoftApConfig();
 
         when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                 .thenReturn(true);
@@ -1260,7 +1349,7 @@
      */
     @Test
     public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
-        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
+        SoftApConfiguration apConfig = generatorTestSoftApConfig();
 
         when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                 .thenReturn(false);
@@ -1275,7 +1364,7 @@
         doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());
 
         try {
-            mWifiManager.setSoftApConfiguration(new SoftApConfiguration.Builder().build());
+            mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
             fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
         } catch (SecurityException e) { }
     }