wifi: Add WFD R2 HAL API

Bug: 179342930
Test: atest VtsHalWifiSupplicantP2pV1_4TargetTest
Change-Id: I1c991fc6c3698eab1a32f728e9d71323a0103b21
diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp
index b486687..c988fdb 100644
--- a/wifi/supplicant/1.4/Android.bp
+++ b/wifi/supplicant/1.4/Android.bp
@@ -16,6 +16,7 @@
         "types.hal",
         "ISupplicant.hal",
         "ISupplicantP2pIface.hal",
+        "ISupplicantP2pIfaceCallback.hal",
         "ISupplicantStaIface.hal",
         "ISupplicantStaNetwork.hal",
         "ISupplicantStaNetworkCallback.hal",
diff --git a/wifi/supplicant/1.4/ISupplicantP2pIface.hal b/wifi/supplicant/1.4/ISupplicantP2pIface.hal
index 65c761d..28846de 100644
--- a/wifi/supplicant/1.4/ISupplicantP2pIface.hal
+++ b/wifi/supplicant/1.4/ISupplicantP2pIface.hal
@@ -17,6 +17,7 @@
 package android.hardware.wifi.supplicant@1.4;
 
 import @1.2::ISupplicantP2pIface;
+import ISupplicantP2pIfaceCallback;
 
 /**
  * Interface exposed by the supplicant for each P2P mode network
@@ -48,4 +49,36 @@
      * @return enabled true if set, false otherwise.
      */
     getEdmg() generates (SupplicantStatus status, bool enabled);
+
+    /**
+     * Register for callbacks from this interface.
+     *
+     * These callbacks are invoked for events that are specific to this interface.
+     * Registration of multiple callback objects is supported. These objects must
+     * be automatically deleted when the corresponding client process is dead or
+     * if this interface is removed.
+     *
+     * @param callback An instance of the |ISupplicantP2pIfaceCallback| HIDL
+     *        interface object.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    registerCallback_1_4(ISupplicantP2pIfaceCallback callback)
+        generates (SupplicantStatus status);
+
+    /*
+     * Set Wifi Display R2 device info.
+     *
+     * @param info WFD R2 device info as described in section 5.1.12 of WFD technical
+     *        specification v2.1.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    setWfdR2DeviceInfo(uint8_t[4] info) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal
new file mode 100644
index 0000000..a091274
--- /dev/null
+++ b/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.4;
+
+import @1.0::ISupplicantP2pIfaceCallback;
+import @1.0::MacAddress;
+import @1.0::WpsConfigMethods;
+import @1.0::P2pGroupCapabilityMask;
+
+/**
+ * Callback Interface exposed by the supplicant service
+ * for each P2P mode interface (ISupplicantP2pIface).
+ *
+ * Clients need to host an instance of this HIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * corresponding |ISupplicantP2pIface.registerCallback| method.
+ */
+interface ISupplicantP2pIfaceCallback extends @1.0::ISupplicantP2pIfaceCallback {
+    /**
+     * Used to indicate that a P2P Wi-Fi Display R2 device has been found. Refer to
+     * Wi-Fi Display Technical Specification Version 2.0.
+     *
+     * @param srcAddress MAC address of the device found. This must either
+     *        be the P2P device address for a peer which is not in a group,
+     *        or the P2P interface address for a peer which is a Group Owner.
+     * @param p2pDeviceAddress P2P device address.
+     * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P
+     *        Technical specification v1.2.
+     * @param deviceName Name of the device.
+     * @param configMethods Mask of WPS configuration methods supported by the
+     *        device.
+     * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param groupCapabilites Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD
+     *        technical specification v1.0.0.
+     * @param wfdR2DeviceInfo WFD R2 device info as described in section 5.1.12 of WFD
+     *        technical specification v2.1.
+     */
+    oneway onR2DeviceFound(
+        MacAddress srcAddress, MacAddress p2pDeviceAddress,
+        uint8_t[8] primaryDeviceType, string deviceName,
+        bitfield<WpsConfigMethods> configMethods, uint8_t deviceCapabilities,
+        bitfield<P2pGroupCapabilityMask> groupCapabilities, uint8_t[6] wfdDeviceInfo,
+        uint8_t[2] wfdR2DeviceInfo);
+};
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index c39de6e..b72eb42 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -107,6 +107,10 @@
      * WPA3 SAE Public-Key.
      */
     SAE_PK = 1 << 2,
+    /**
+     * Wi-Fi Display R2
+     */
+    WFD_R2 = 1 << 3,
 };
 
 /**
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 9185279..4427c390 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -28,16 +28,23 @@
 #include "supplicant_hidl_test_utils_1_4.h"
 
 using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface;
+using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIfaceCallback;
 
 using SupplicantStatusV1_4 =
     ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus;
 using SupplicantStatusCodeV1_4 =
     ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode;
 
+constexpr uint8_t kTestWfdR2DeviceInfo[] = {[0 ... 3] = 0x01};
+
 class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 {
    public:
     virtual void SetUp() override {
@@ -51,6 +58,100 @@
     sp<ISupplicantP2pIface> p2p_iface_;
 };
 
+class IfaceCallback : public ISupplicantP2pIfaceCallback {
+    Return<void> onNetworkAdded(uint32_t /* id */) override { return Void(); }
+    Return<void> onNetworkRemoved(uint32_t /* id */) override { return Void(); }
+    Return<void> onDeviceFound(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+        const hidl_array<uint8_t, 8>& /* primaryDeviceType */,
+        const hidl_string& /* deviceName */, uint16_t /* configMethods */,
+        uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */,
+        const hidl_array<uint8_t, 6>& /* wfdDeviceInfo */) override {
+        return Void();
+    }
+    Return<void> onDeviceLost(
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+    Return<void> onFindStopped() override { return Void(); }
+    Return<void> onGoNegotiationRequest(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        ISupplicantP2pIfaceCallback::WpsDevPasswordId /* passwordId */)
+        override {
+        return Void();
+    }
+    Return<void> onGoNegotiationCompleted(
+        ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+        return Void();
+    }
+    Return<void> onGroupFormationSuccess() override { return Void(); }
+    Return<void> onGroupFormationFailure(
+        const hidl_string& /* failureReason */) override {
+        return Void();
+    }
+    Return<void> onGroupStarted(
+        const hidl_string& /* groupIfname */, bool /* isGo */,
+        const hidl_vec<uint8_t>& /* ssid */, uint32_t /* frequency */,
+        const hidl_array<uint8_t, 32>& /* psk */,
+        const hidl_string& /* passphrase */,
+        const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+        bool /* isPersistent */) override {
+        return Void();
+    }
+    Return<void> onGroupRemoved(const hidl_string& /* groupIfname */,
+                                bool /* isGo */) override {
+        return Void();
+    }
+    Return<void> onInvitationReceived(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* goDeviceAddress */,
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        uint32_t /* persistentNetworkId */,
+        uint32_t /* operatingFrequency */) override {
+        return Void();
+    }
+    Return<void> onInvitationResult(
+        const hidl_array<uint8_t, 6>& /* bssid */,
+        ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override {
+        return Void();
+    }
+    Return<void> onProvisionDiscoveryCompleted(
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+        bool /* isRequest */,
+        ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode /* status */,
+        uint16_t /* configMethods */,
+        const hidl_string& /* generatedPin */) override {
+        return Void();
+    }
+    Return<void> onServiceDiscoveryResponse(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        uint16_t /* updateIndicator */,
+        const hidl_vec<uint8_t>& /* tlvs */) override {
+        return Void();
+    }
+    Return<void> onStaAuthorized(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+    Return<void> onStaDeauthorized(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */) override {
+        return Void();
+    }
+    Return<void> onR2DeviceFound(
+        const hidl_array<uint8_t, 6>& /* srcAddress */,
+        const hidl_array<uint8_t, 6>& /* p2pDeviceAddress */,
+        const hidl_array<uint8_t, 8>& /* primaryDeviceType */,
+        const hidl_string& /* deviceName */, uint16_t /* configMethods */,
+        uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */,
+        const hidl_array<uint8_t, 6>& /* wfdDeviceInfo */,
+        const hidl_array<uint8_t, 2>& /* wfdR2DeviceInfo */) override {
+        return Void();
+    }
+};
+
 /*
  * SetGetEdmg
  */
@@ -71,6 +172,26 @@
     });
 }
 
+/*
+ * RegisterCallback_1_4
+ */
+TEST_P(SupplicantP2pIfaceHidlTest, RegisterCallback_1_4) {
+    p2p_iface_->registerCallback_1_4(
+        new IfaceCallback(), [](const SupplicantStatusV1_4& status) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetWfdR2DeviceInfo
+ */
+TEST_P(SupplicantP2pIfaceHidlTest, SetWfdR2DeviceInfo) {
+    p2p_iface_->setWfdR2DeviceInfo(
+        kTestWfdR2DeviceInfo, [&](const SupplicantStatusV1_4& status) {
+            EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
+        });
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest);
 INSTANTIATE_TEST_CASE_P(
     PerInstance, SupplicantP2pIfaceHidlTest,