Merge "wifi: add enable SAE PK only mode API"
diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp
index 68c2929..1784fad 100644
--- a/wifi/supplicant/1.3/vts/functional/Android.bp
+++ b/wifi/supplicant/1.3/vts/functional/Android.bp
@@ -54,6 +54,7 @@
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant@1.2",
         "android.hardware.wifi.supplicant@1.3",
+        "android.hardware.wifi.supplicant@1.4",
         "android.hardware.wifi@1.0",
         "android.hardware.wifi@1.1",
         "libgmock",
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 6dc267c..189e2b9 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -23,6 +23,8 @@
 #include <android/hardware/wifi/supplicant/1.3/ISupplicantStaIfaceCallback.h>
 #include <android/hardware/wifi/supplicant/1.3/ISupplicantStaNetwork.h>
 #include <android/hardware/wifi/supplicant/1.3/types.h>
+#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIface.h>
+#include <android/hardware/wifi/supplicant/1.4/types.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/HidlSupport.h>
@@ -61,6 +63,10 @@
         SupplicantHidlTestBaseV1_3::SetUp();
         sta_iface_ = getSupplicantStaIface_1_3(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
+
+        /* Variable used to check the underlying HAL version. */
+        sta_iface_v1_4_ = ::android::hardware::wifi::supplicant::V1_4::
+            ISupplicantStaIface::castFrom(sta_iface_);
     }
 
     int64_t pmkCacheExpirationTimeInSec;
@@ -108,6 +114,8 @@
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
+    sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface>
+        sta_iface_v1_4_ = nullptr;
 
     bool isDppSupported() {
         uint32_t keyMgmtMask = 0;
@@ -342,9 +350,12 @@
  * GetWpaDriverCapabilities
  */
 TEST_P(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) {
+    SupplicantStatusCode expectedCode =
+        (nullptr != sta_iface_v1_4_) ? SupplicantStatusCode::FAILURE_UNKNOWN
+                                     : SupplicantStatusCode::SUCCESS;
     sta_iface_->getWpaDriverCapabilities(
         [&](const SupplicantStatus& status, uint32_t) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+            EXPECT_EQ(expectedCode, status.code);
         });
 }
 
@@ -355,12 +366,26 @@
     uint32_t driverCapMask = 0;
 
     // Get MBO support from the device.
-    sta_iface_->getWpaDriverCapabilities(
-        [&](const SupplicantStatus& status, uint32_t driverCapMaskInternal) {
-            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+    if (nullptr != sta_iface_v1_4_) {
+        sta_iface_v1_4_->getWpaDriverCapabilities_1_4(
+            [&](const ::android::hardware::wifi::supplicant::V1_4::
+                    SupplicantStatus& status,
+                uint32_t driverCapMaskInternal) {
+                EXPECT_EQ(::android::hardware::wifi::supplicant::V1_4::
+                              SupplicantStatusCode::SUCCESS,
+                          status.code);
 
-            driverCapMask = driverCapMaskInternal;
-        });
+                driverCapMask = driverCapMaskInternal;
+            });
+    } else {
+        sta_iface_->getWpaDriverCapabilities(
+            [&](const SupplicantStatus& status,
+                uint32_t driverCapMaskInternal) {
+                EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+
+                driverCapMask = driverCapMaskInternal;
+            });
+    }
 
     SupplicantStatusCode expectedStatusCode =
         (driverCapMask & WpaDriverCapabilitiesMask::MBO)
diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal
index db9a35b..f9e4c9b 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal
@@ -73,4 +73,15 @@
      */
     initiateVenueUrlAnqpQuery(MacAddress macAddress)
         generates (SupplicantStatus status);
+
+    /**
+     * Get wpa driver capabilities.
+     *
+     * @return status Status of the operation, and a bitmap of wpa driver features.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     */
+    getWpaDriverCapabilities_1_4() generates (SupplicantStatus status,
+        bitfield<WpaDriverCapabilitiesMask> driverCapabilitiesMask);
 };
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 4295879..80beedf 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -25,6 +25,16 @@
  */
 interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork {
     /**
+     * Possible mask of values for KeyMgmt param.
+     */
+    enum KeyMgmtMask : @1.3::ISupplicantStaNetwork.KeyMgmtMask {
+        /**
+         * SAE PK mode
+         */
+        SAE_PK,
+    };
+
+    /**
      * Possible mask of values for PairwiseCipher param.
      */
     enum PairwiseCipherMask : @1.3::ISupplicantStaNetwork.PairwiseCipherMask {
@@ -160,4 +170,22 @@
      *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
      */
     enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status);
+
+    /**
+     * Set whether to enable SAE PK (Public Key) only mode to enable public AP validation.
+     * When enabled, only SAE PK network is allowed; otherwise PK is optional.
+     * If this API is not called before connecting to an SAE
+     * network, SAE PK mode depends on SAE PK config in wpa_supplicant configuration.
+     * If SAE PK config of wpa_supplicant configuration is not set,
+     * the default mode is optional (support for both PK and standard mode).
+     *
+     * @param enable true to set, false otherwise.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    enableSaePkOnlyMode(bool enable) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index b4b6a36..18af8fe 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -18,6 +18,7 @@
 
 import @1.0::SupplicantStatusCode;
 import @1.3::ConnectionCapabilities;
+import @1.3::WpaDriverCapabilitiesMask;
 
 /**
  * Detailed network mode for legacy network
@@ -71,3 +72,13 @@
    */
   string debugMessage;
 };
+
+/**
+ * WPA Driver capability.
+ */
+enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask {
+    /**
+     *
+     */
+    SAE_PK = 1 << 2,
+};
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
index e079abc..c0b5a70 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -245,6 +245,16 @@
         });
 }
 
+/*
+ * GetWpaDriverCapabilities
+ */
+TEST_P(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) {
+    sta_iface_->getWpaDriverCapabilities_1_4(
+        [&](const SupplicantStatusV1_4& status, uint32_t) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+        });
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest);
 INSTANTIATE_TEST_CASE_P(
     PerInstance, SupplicantStaIfaceHidlTest,
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
index 86314e2..0e38c4b 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -46,11 +46,15 @@
     ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus;
 using SupplicantStatusCodeV1_4 =
     ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode;
+using WpaDriverCapabilitiesMaskV1_4 =
+    ::android::hardware::wifi::supplicant::V1_4::WpaDriverCapabilitiesMask;
 
 class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 {
    public:
     virtual void SetUp() override {
         SupplicantHidlTestBaseV1_4::SetUp();
+        sta_iface_ = getSupplicantStaIface_1_4(supplicant_);
+        ASSERT_NE(nullptr, sta_iface_.get());
         sta_network_ = createSupplicantStaNetwork(supplicant_);
         ASSERT_NE(sta_network_.get(), nullptr);
         /* variable used to check if the underlying HAL version is 1.4 or
@@ -61,10 +65,21 @@
     }
 
    protected:
+    sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface>
+        sta_iface_;
     sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork>
         v1_4 = nullptr;
     // ISupplicantStaNetwork object used for all tests in this fixture.
     sp<ISupplicantStaNetwork> sta_network_;
+    bool isSaePkSupported() {
+        uint32_t caps;
+        sta_iface_->getWpaDriverCapabilities_1_4(
+            [&](const SupplicantStatusV1_4& status, uint32_t capsInternal) {
+                EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+                caps = capsInternal;
+            });
+        return !!(caps & WpaDriverCapabilitiesMaskV1_4::SAE_PK);
+    }
 };
 
 class NetworkCallback : public ISupplicantStaNetworkCallback {
@@ -106,6 +121,22 @@
     });
 }
 
+/*
+ * enable SAE PK only mode
+ */
+TEST_P(SupplicantStaNetworkHidlTest, EnableSaePkOnlyMode) {
+    LOG(INFO) << "SAE-PK Supported: " << isSaePkSupported();
+    SupplicantStatusCodeV1_4 expectedCode =
+        isSaePkSupported() ? SupplicantStatusCodeV1_4::SUCCESS
+                           : SupplicantStatusCodeV1_4::FAILURE_UNSUPPORTED;
+    v1_4->enableSaePkOnlyMode(true, [&](const SupplicantStatusV1_4& status) {
+        EXPECT_EQ(expectedCode, status.code);
+    });
+    v1_4->enableSaePkOnlyMode(false, [&](const SupplicantStatusV1_4& status) {
+        EXPECT_EQ(expectedCode, status.code);
+    });
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest);
 INSTANTIATE_TEST_CASE_P(
     PerInstance, SupplicantStaNetworkHidlTest,