Introduce IVibratorManager.aidl

Introduce interface for vibrator manager HAL.

A default implementation is made available to the existing
android.hardware.vibrator-service.example, which now provides a top
level devault IVibrator and a top level IVibratorManager with a
different vibrator in it.

VTS tests were also introduced for the new manager, and existing tests
for IVibrator where changed to run in all top level and managed HAL
instances found on a device.

Bug: 166586119
Test: atest VtsHalVibratorTargetTest
      atest VtsHalVibratorManagerTargetTest
Change-Id: Iec9175167e795bc03c4f3d873e2ac6682ed52512
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index 28cb4d9..d06b50e 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -9,7 +9,26 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.vibrator-cpp",
+        "android.hardware.vibrator-unstable-cpp",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalVibratorManagerTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalVibratorManagerTargetTest.cpp"],
+    shared_libs: [
+        "libbinder",
+    ],
+    static_libs: [
+        "android.hardware.vibrator-unstable-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
new file mode 100644
index 0000000..9789188
--- /dev/null
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2020 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <android/hardware/vibrator/BnVibratorCallback.h>
+#include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <cmath>
+#include <future>
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::vibrator::BnVibratorCallback;
+using android::hardware::vibrator::CompositeEffect;
+using android::hardware::vibrator::CompositePrimitive;
+using android::hardware::vibrator::Effect;
+using android::hardware::vibrator::EffectStrength;
+using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
+using std::chrono::high_resolution_clock;
+
+const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
+                                   android::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
+                                                   android::enum_range<EffectStrength>().end()};
+const std::vector<CompositePrimitive> kPrimitives{android::enum_range<CompositePrimitive>().begin(),
+                                                  android::enum_range<CompositePrimitive>().end()};
+
+class CompletionCallback : public BnVibratorCallback {
+  public:
+    CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
+    Status onComplete() override {
+        mCallback();
+        return Status::ok();
+    }
+
+  private:
+    std::function<void()> mCallback;
+};
+
+class VibratorAidl : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        manager = android::waitForDeclaredService<IVibratorManager>(String16(GetParam().c_str()));
+        ASSERT_NE(manager, nullptr);
+        ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk());
+        EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk());
+    }
+
+    sp<IVibratorManager> manager;
+    int32_t capabilities;
+    std::vector<int32_t> vibratorIds;
+};
+
+TEST_P(VibratorAidl, ValidateExistingVibrators) {
+    sp<IVibrator> vibrator;
+    for (auto& id : vibratorIds) {
+        EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+        ASSERT_NE(vibrator, nullptr);
+    }
+}
+
+TEST_P(VibratorAidl, GetVibratorWithInvalidId) {
+    int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1;
+    sp<IVibrator> vibrator;
+    EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
+              manager->getVibrator(invalidId, &vibrator).exceptionCode());
+    ASSERT_EQ(vibrator, nullptr);
+}
+
+TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (vibratorIds.empty()) return;
+    EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    std::vector<int32_t> emptyIds;
+    EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode());
+}
+
+TEST_P(VibratorAidl, PrepareSyncedNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->prepareSynced(vibratorIds).exceptionCode());
+    }
+}
+
+TEST_P(VibratorAidl, PrepareOnNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        uint32_t durationMs = 250;
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                      vibrator->on(durationMs, nullptr).exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, PreparePerformNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            int32_t lengthMs = 0;
+            Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, PrepareComposeNotSupported) {
+    if (vibratorIds.empty()) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
+        std::vector<CompositeEffect> composite;
+        CompositeEffect effect;
+        effect.delayMs = 10;
+        effect.primitive = kPrimitives[0];
+        effect.scale = 1.0f;
+        composite.emplace_back(effect);
+
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        sp<IVibrator> vibrator;
+        for (auto& id : vibratorIds) {
+            EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+            ASSERT_NE(vibrator, nullptr);
+            Status status = vibrator->compose(composite, nullptr);
+            EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
+        }
+        EXPECT_TRUE(manager->cancelSynced().isOk());
+    }
+}
+
+TEST_P(VibratorAidl, TriggerWithCallback) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) return;
+    if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> completionPromise;
+    std::future<void> completionFuture{completionPromise.get_future()};
+    sp<CompletionCallback> callback =
+            new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+    uint32_t durationMs = 250;
+    std::chrono::milliseconds timeout{durationMs * 2};
+
+    EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+    sp<IVibrator> vibrator;
+    for (auto& id : vibratorIds) {
+        EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+        ASSERT_NE(vibrator, nullptr);
+        EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk());
+    }
+
+    EXPECT_TRUE(manager->triggerSynced(callback).isOk());
+    EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
+    EXPECT_TRUE(manager->cancelSynced().isOk());
+}
+
+TEST_P(VibratorAidl, TriggerSyncNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) {
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->triggerSynced(nullptr).exceptionCode());
+    }
+}
+
+TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) {
+        sp<CompletionCallback> callback = new CompletionCallback([] {});
+        EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+        EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
+                  manager->triggerSynced(callback).exceptionCode());
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
+INSTANTIATE_TEST_SUITE_P(
+        Vibrator, VibratorAidl,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 888a403..dfd2524 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -18,6 +18,7 @@
 
 #include <android/hardware/vibrator/BnVibratorCallback.h>
 #include <android/hardware/vibrator/IVibrator.h>
+#include <android/hardware/vibrator/IVibratorManager.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
@@ -34,6 +35,7 @@
 using android::hardware::vibrator::Effect;
 using android::hardware::vibrator::EffectStrength;
 using android::hardware::vibrator::IVibrator;
+using android::hardware::vibrator::IVibratorManager;
 using std::chrono::high_resolution_clock;
 
 const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
@@ -77,10 +79,28 @@
     std::function<void()> mCallback;
 };
 
-class VibratorAidl : public testing::TestWithParam<std::string> {
+class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>> {
   public:
     virtual void SetUp() override {
-        vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
+        int32_t managerIdx = std::get<0>(GetParam());
+        int32_t vibratorId = std::get<1>(GetParam());
+        auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+
+        if (managerIdx < 0) {
+            // Testing a unmanaged vibrator, using vibratorId as index from registered HALs
+            auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+            ASSERT_LT(vibratorId, vibratorAidlNames.size());
+            auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
+            vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
+        } else {
+            // Testing a managed vibrator, using vibratorId to retrieve it from the manager
+            ASSERT_LT(managerIdx, managerAidlNames.size());
+            auto managerName = String16(managerAidlNames[managerIdx].c_str());
+            auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+            auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
+            ASSERT_TRUE(vibratorResult.isOk());
+        }
+
         ASSERT_NE(vibrator, nullptr);
         ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
     }
@@ -518,10 +538,41 @@
     }
 }
 
+std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
+    std::vector<std::tuple<int32_t, int32_t>> tuples;
+    auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
+    std::vector<int32_t> vibratorIds;
+
+    for (int i = 0; i < managerAidlNames.size(); i++) {
+        auto managerName = String16(managerAidlNames[i].c_str());
+        auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+        if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
+            for (auto& vibratorId : vibratorIds) {
+                tuples.push_back(std::make_tuple(i, vibratorId));
+            }
+        }
+    }
+
+    auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
+    for (int i = 0; i < vibratorAidlNames.size(); i++) {
+        tuples.push_back(std::make_tuple(-1, i));
+    }
+
+    return tuples;
+}
+
+std::string PrintGeneratedTest(const testing::TestParamInfo<VibratorAidl::ParamType>& info) {
+    const auto& [managerIdx, vibratorId] = info.param;
+    if (managerIdx < 0) {
+        return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId);
+    }
+    return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" +
+           std::to_string(vibratorId);
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
-INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
-                         testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
-                         android::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()),
+                         PrintGeneratedTest);
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);