wpa_supplicant(interface): Support add/remove interfaces

Add HIDL API's for adding/removing interfaces dynamically.

Bug: 65673678
Test: VTS tests
Test: Manual test modifying framework to add wlan0 dynamically.
Change-Id: Ifebfc9e8848e3388f5c4829bb225e3cb0bd82b05
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index 24b9f6f..f742ecd 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -14,19 +14,37 @@
 // limitations under the License.
 //
 
+cc_library_static {
+    name: "VtsHalWifiSupplicantV1_0TargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["supplicant_hidl_test_utils.cpp"],
+    export_include_dirs: [
+        "."
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
+
 cc_test {
     name: "VtsHalWifiSupplicantV1_0TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "VtsHalWifiSupplicantV1_0TargetTest.cpp",
         "supplicant_hidl_test.cpp",
-        "supplicant_hidl_test_utils.cpp",
         "supplicant_p2p_iface_hidl_test.cpp",
         "supplicant_sta_iface_hidl_test.cpp",
         "supplicant_sta_network_hidl_test.cpp",
     ],
     static_libs: [
         "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi@1.0",
         "libcrypto",
diff --git a/wifi/supplicant/1.1/ISupplicant.hal b/wifi/supplicant/1.1/ISupplicant.hal
index 5c60b35..508a545 100644
--- a/wifi/supplicant/1.1/ISupplicant.hal
+++ b/wifi/supplicant/1.1/ISupplicant.hal
@@ -17,6 +17,8 @@
 package android.hardware.wifi.supplicant@1.1;
 
 import @1.0::ISupplicant;
+import @1.0::ISupplicantIface;
+import @1.0::SupplicantStatus;
 
 /**
  * Interface exposed by the supplicant HIDL service registered
@@ -24,4 +26,32 @@
  * This is the root level object for any the supplicant interactions.
  */
 interface ISupplicant extends @1.0::ISupplicant {
+    /**
+     * Registers a wireless interface in supplicant.
+     *
+     * @param ifaceInfo Combination of the interface type and name(e.g wlan0).
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_EXISTS|
+     * @return iface HIDL interface object representing the interface if
+     *         successful, null otherwise.
+     */
+    addInterface(IfaceInfo ifaceInfo)
+        generates (SupplicantStatus status, ISupplicantIface iface);
+
+    /**
+     * Deregisters a wireless interface from supplicant.
+     *
+     * @param ifaceInfo Combination of the interface type and name(e.g wlan0).
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_UNKOWN|
+     */
+    removeInterface(IfaceInfo ifaceInfo) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.1/vts/Android.mk b/wifi/supplicant/1.1/vts/Android.mk
new file mode 100644
index 0000000..6361f9b
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..9375cf5
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_library_static {
+    name: "VtsHalWifiSupplicantV1_1TargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["supplicant_hidl_test_utils_1_1.cpp"],
+    export_include_dirs: [
+        "."
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiSupplicantV1_1TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalWifiSupplicantV1_1TargetTest.cpp",
+        "supplicant_hidl_test.cpp",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiSupplicantV1_0TargetTestUtil",
+        "VtsHalWifiSupplicantV1_1TargetTestUtil",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi.supplicant@1.1",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
diff --git a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp
new file mode 100644
index 0000000..81893e5
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "supplicant_hidl_test_utils.h"
+
+class SupplicantHidlEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() override { stopSupplicant(); }
+    virtual void TearDown() override {}
+};
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new SupplicantHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
new file mode 100644
index 0000000..c29fd0a
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include <android/hardware/wifi/supplicant/1.0/types.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
+
+#include "supplicant_hidl_test_utils.h"
+#include "supplicant_hidl_test_utils_1_1.h"
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
+using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
+using ::android::hardware::wifi::supplicant::V1_1::ISupplicant;
+using ::android::sp;
+
+class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startSupplicantAndWaitForHidlService();
+        supplicant_ = getSupplicant_1_1();
+        ASSERT_NE(supplicant_.get(), nullptr);
+    }
+
+    virtual void TearDown() override { stopSupplicant(); }
+
+   protected:
+    // ISupplicant object used for all tests in this fixture.
+    sp<ISupplicant> supplicant_;
+
+    std::string getWlan0IfaceName() {
+        std::array<char, PROPERTY_VALUE_MAX> buffer;
+        property_get("wifi.interface", buffer.data(), "wlan0");
+        return buffer.data();
+    }
+
+    std::string getP2pIfaceName() {
+        std::array<char, PROPERTY_VALUE_MAX> buffer;
+        property_get("wifi.direct.interface", buffer.data(), "p2p0");
+        return buffer.data();
+    }
+};
+
+/*
+ * AddStaInterface
+ */
+TEST_F(SupplicantHidlTest, AddStaInterface) {
+    ISupplicant::IfaceInfo iface_info;
+    iface_info.name = getWlan0IfaceName();
+    iface_info.type = IfaceType::STA;
+    supplicant_->addInterface(
+        iface_info,
+        [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+            EXPECT_TRUE(
+                (status.code == SupplicantStatusCode::SUCCESS) ||
+                (status.code == SupplicantStatusCode::FAILURE_IFACE_EXISTS));
+            EXPECT_NE(nullptr, iface.get());
+        });
+}
+
+/*
+ * AddP2pInterface
+ */
+TEST_F(SupplicantHidlTest, AddP2pInterface) {
+    ISupplicant::IfaceInfo iface_info;
+    iface_info.name = getP2pIfaceName();
+    iface_info.type = IfaceType::P2P;
+    supplicant_->addInterface(
+        iface_info,
+        [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+            EXPECT_TRUE(
+                (status.code == SupplicantStatusCode::SUCCESS) ||
+                (status.code == SupplicantStatusCode::FAILURE_IFACE_EXISTS));
+            EXPECT_NE(nullptr, iface.get());
+        });
+}
+
+/*
+ * RemoveStaInterface
+ */
+TEST_F(SupplicantHidlTest, RemoveStaInterface) {
+    ISupplicant::IfaceInfo iface_info;
+    iface_info.name = getWlan0IfaceName();
+    iface_info.type = IfaceType::STA;
+
+    supplicant_->addInterface(
+        iface_info,
+        [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+            EXPECT_TRUE(
+                (status.code == SupplicantStatusCode::SUCCESS) ||
+                (status.code == SupplicantStatusCode::FAILURE_IFACE_EXISTS));
+            EXPECT_NE(nullptr, iface.get());
+        });
+    supplicant_->removeInterface(
+        iface_info, [&](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * RemoveP2pInterface
+ */
+TEST_F(SupplicantHidlTest, RemoveP2pInterface) {
+    ISupplicant::IfaceInfo iface_info;
+    iface_info.name = getP2pIfaceName();
+    iface_info.type = IfaceType::P2P;
+
+    supplicant_->addInterface(
+        iface_info,
+        [&](const SupplicantStatus& status, const sp<ISupplicantIface>& iface) {
+            EXPECT_TRUE(
+                (status.code == SupplicantStatusCode::SUCCESS) ||
+                (status.code == SupplicantStatusCode::FAILURE_IFACE_EXISTS));
+            EXPECT_NE(nullptr, iface.get());
+        });
+    supplicant_->removeInterface(
+        iface_info, [&](const SupplicantStatus& status) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp
new file mode 100644
index 0000000..8cc4a9f
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+
+#include "supplicant_hidl_test_utils.h"
+#include "supplicant_hidl_test_utils_1_1.h"
+
+using ::android::hardware::wifi::supplicant::V1_1::ISupplicant;
+using ::android::sp;
+
+sp<ISupplicant> getSupplicant_1_1() {
+    return ISupplicant::castFrom(getSupplicant());
+}
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
new file mode 100644
index 0000000..c42a35b
--- /dev/null
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef SUPPLICANT_HIDL_TEST_UTILS_1_1_H
+#define SUPPLICANT_HIDL_TEST_UTILS_1_1_H
+
+#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
+
+android::sp<android::hardware::wifi::supplicant::V1_1::ISupplicant>
+    getSupplicant_1_1();
+
+#endif /* SUPPLICANT_HIDL_TEST_UTILS_1_1_H */