Notify scan-only mode to driver for power saving

If Wi-Fi driver knows it's in scan-only mode, it can save more power
than connect mode.

This change adds setScanMode in IWifiStaIface to allow Wi-Fi framework
to notify scan-only mode change to Wi-Fi driver.

Bug: 177811719
Test: atest VtsHalWifiV1_5TargetTest

Change-Id: I1dfbc24a0a3272c1341223aff36656be4a6fd21b
diff --git a/wifi/1.5/IWifiStaIface.hal b/wifi/1.5/IWifiStaIface.hal
index e9d411e..daf545e 100644
--- a/wifi/1.5/IWifiStaIface.hal
+++ b/wifi/1.5/IWifiStaIface.hal
@@ -41,4 +41,17 @@
      * @return stats Instance of |LinkLayerStats|.
      */
     getLinkLayerStats_1_5() generates (WifiStatus status, StaLinkLayerStats stats);
+
+    /**
+     * Turn on/off scan only mode for the interface.
+     *
+     * @param enable Indicate if scan only mode is to be turned on/off.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    setScanMode(bool enable) generates (WifiStatus status);
 };
diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp
index 82bfcf1..92c9fe4 100644
--- a/wifi/1.5/default/wifi_sta_iface.cpp
+++ b/wifi/1.5/default/wifi_sta_iface.cpp
@@ -273,6 +273,13 @@
                            hidl_status_cb);
 }
 
+Return<void> WifiStaIface::setScanMode(bool enable,
+                                       setScanMode_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setScanModeInternal, hidl_status_cb,
+                           enable);
+}
+
 std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
     return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
 }
@@ -655,6 +662,12 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
 }
 
+WifiStatus WifiStaIface::setScanModeInternal(bool enable) {
+    // OEM's need to implement this on their devices if needed.
+    LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
 }  // namespace implementation
 }  // namespace V1_5
 }  // namespace wifi
diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h
index 94873c9..f9058b8 100644
--- a/wifi/1.5/default/wifi_sta_iface.h
+++ b/wifi/1.5/default/wifi_sta_iface.h
@@ -114,6 +114,8 @@
                                setMacAddress_cb hidl_status_cb) override;
     Return<void> getFactoryMacAddress(
         getFactoryMacAddress_cb hidl_status_cb) override;
+    Return<void> setScanMode(bool enable,
+                             setScanMode_cb hidl_status_cb) override;
 
    private:
     // Corresponding worker functions for the HIDL methods.
@@ -164,6 +166,7 @@
     WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
     std::pair<WifiStatus, std::array<uint8_t, 6>>
     getFactoryMacAddressInternal();
+    WifiStatus setScanModeInternal(bool enable);
 
     std::string ifname_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
diff --git a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp
index 8cc3300..399307e 100644
--- a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp
+++ b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -108,6 +108,19 @@
         WifiStatusCode::SUCCESS,
         HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
 }
+/**
+ * SetScanMode
+ */
+TEST_P(WifiStaIfaceHidlTest, SetScanMode) {
+    auto statusCode =
+        HIDL_INVOKE(wifi_sta_iface_, setScanMode, true).code;
+    EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS ||
+                statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED);
+
+    statusCode = HIDL_INVOKE(wifi_sta_iface_, setScanMode, false).code;
+    EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS ||
+                statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest);
 INSTANTIATE_TEST_SUITE_P(