Interface for configureRpcThreadpool tests

Test: links, compiles
Change-Id: I58996c4eeba5889c73407b1d71f03638b23d73d1
diff --git a/tests/multithread/1.0/default/Android.bp b/tests/multithread/1.0/default/Android.bp
new file mode 100644
index 0000000..72b9e91
--- /dev/null
+++ b/tests/multithread/1.0/default/Android.bp
@@ -0,0 +1,17 @@
+cc_library_shared {
+    name: "android.hardware.tests.multithread@1.0-impl",
+    defaults: ["hidl_defaults"],
+    relative_install_path: "hw",
+    proprietary: true,
+    srcs: [
+        "Multithread.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.tests.multithread@1.0",
+    ],
+}
diff --git a/tests/multithread/1.0/default/Multithread.cpp b/tests/multithread/1.0/default/Multithread.cpp
new file mode 100644
index 0000000..1fb267c
--- /dev/null
+++ b/tests/multithread/1.0/default/Multithread.cpp
@@ -0,0 +1,63 @@
+#define LOG_TAG "hidl_test"
+
+#include <android-base/logging.h>
+#include "Multithread.h"
+#include <inttypes.h>
+#include <thread>
+
+#include <hidl/HidlTransportSupport.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace multithread {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::tests::multithread::V1_0::IMultithread follow.
+Return<void> Multithread::setNumThreads(int32_t maxThreads, int32_t numThreads) {
+    LOG(INFO) << "SERVER(Multithread) setNumThreads("
+              << maxThreads << ", " << numThreads << ")";
+
+    LOG(INFO) << "SERVER(Multithread) call configureRpcThreadpool("
+              << maxThreads << ")";
+    ::android::hardware::configureRpcThreadpool(maxThreads, /*willjoin*/ false);
+
+    mNumThreads = numThreads;
+    mNoTimeout = true;
+
+    return Void();
+}
+
+Return<bool> Multithread::runNewThread() {
+    LOG(INFO) << "SERVER(Multithread) runNewThread()";
+
+    std::unique_lock<std::mutex> lk(mCvMutex);
+    --mNumThreads;
+
+    LOG(INFO) << "SERVER(Multithread) runNewThread()";
+    LOG(INFO) << mNumThreads << "threads left";
+
+    mCv.notify_all();
+    bool noTimeout = mCv.wait_for(lk, kTimeoutDuration,
+        [&] { return mNumThreads <= 0 || !mNoTimeout; });
+
+    if (!noTimeout) {
+        mNoTimeout = false;
+        mCv.notify_all();
+    }
+    return mNoTimeout;
+}
+
+IMultithread* HIDL_FETCH_IMultithread(const char* /* name */) {
+    return new Multithread();
+}
+
+decltype(Multithread::kTimeoutDuration) Multithread::kTimeoutDuration;
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace multithread
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
diff --git a/tests/multithread/1.0/default/Multithread.h b/tests/multithread/1.0/default/Multithread.h
new file mode 100644
index 0000000..0d4a007
--- /dev/null
+++ b/tests/multithread/1.0/default/Multithread.h
@@ -0,0 +1,48 @@
+#ifndef ANDROID_HARDWARE_TESTS_MULTITHREAD_V1_0_MULTITHREAD_H
+#define ANDROID_HARDWARE_TESTS_MULTITHREAD_V1_0_MULTITHREAD_H
+
+#include <android/hardware/tests/multithread/1.0/IMultithread.h>
+#include <hidl/Status.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace multithread {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tests::multithread::V1_0::IMultithread;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using namespace std::chrono_literals;
+
+struct Multithread : public IMultithread {
+    // Methods from ::android::hardware::tests::multithread::V1_0::IMultithread follow.
+    virtual Return<void> setNumThreads(int32_t maxThreads, int32_t numThreads) override;
+    virtual Return<bool> runNewThread() override;
+
+   private:
+    int32_t mNumThreads;
+    bool mNoTimeout;
+
+    std::condition_variable mCv;
+    std::mutex mCvMutex;
+
+    static constexpr auto kTimeoutDuration = 100ms;
+};
+
+extern "C" IMultithread* HIDL_FETCH_IMultithread(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace multithread
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TESTS_MULTITHREAD_V1_0_MULTITHREAD_H