Audio HAL: Add new HAL for sound dose

The new HAL is running as part of the HIDL audio HAL process. It is
meant as a workaround for HAL implementors that can not switch to the
audio AIDL yet and need to certify with IEC62368-1 3rd edition or
EN50332-3. Note that this HAL will be deprecated in the future.

Test: atest VtsHalSoundDoseFactoryTargetTest & flash bluejay-userdebug
Bug: 257937004
Change-Id: Ifbbf235bab58c1ee2f1ea246cf98c9e8966893c0
diff --git a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
new file mode 100644
index 0000000..7448c1f
--- /dev/null
+++ b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "VtsHalSoundDose.Factory"
+#include <android-base/logging.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/sounddose/ISoundDoseFactory.h>
+#include <android/binder_manager.h>
+
+#include <memory>
+
+namespace android::hardware::audio::common::testing {
+
+namespace detail {
+
+inline ::testing::AssertionResult assertIsOk(const char* expr, const ::ndk::ScopedAStatus& status) {
+    if (status.isOk()) {
+        return ::testing::AssertionSuccess();
+    }
+    return ::testing::AssertionFailure()
+           << "Expected the transaction \'" << expr << "\' to succeed\n"
+           << "  but it has failed with: " << status;
+}
+
+}  // namespace detail
+
+}  // namespace android::hardware::audio::common::testing
+
+// Test that the transaction status 'isOk'
+#define EXPECT_IS_OK(ret) \
+    EXPECT_PRED_FORMAT1(::android::hardware::audio::common::testing::detail::assertIsOk, ret)
+
+using namespace android;
+
+using aidl::android::hardware::audio::core::ISoundDose;
+using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
+
+class SoundDoseFactory : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(ConnectToService(GetParam())); }
+
+    void TearDown() override {}
+
+    void ConnectToService(const std::string& interfaceName) {
+        ndk::SpAIBinder binder =
+                ndk::SpAIBinder(AServiceManager_waitForService(interfaceName.c_str()));
+        if (binder == nullptr) {
+            LOG(ERROR) << "Failed to get service " << interfaceName;
+        } else {
+            LOG(DEBUG) << "Succeeded to get service " << interfaceName;
+        }
+        soundDoseFactory = ISoundDoseFactory::fromBinder(binder);
+        ASSERT_NE(soundDoseFactory, nullptr);
+    }
+
+    std::shared_ptr<ISoundDoseFactory> soundDoseFactory;
+};
+
+TEST_P(SoundDoseFactory, GetSoundDoseForSameModule) {
+    const std::string module = "primary";
+
+    std::shared_ptr<ISoundDose> soundDose1;
+    EXPECT_IS_OK(soundDoseFactory->getSoundDose(module, &soundDose1));
+
+    if (soundDose1 == nullptr) {
+        LOG(WARNING) << "Primary module does not support sound dose";
+        return;
+    }
+
+    std::shared_ptr<ISoundDose> soundDose2;
+    EXPECT_IS_OK(soundDoseFactory->getSoundDose(module, &soundDose2));
+    EXPECT_NE(nullptr, soundDose2);
+    EXPECT_EQ(soundDose1->asBinder(), soundDose2->asBinder())
+            << "getSoundDose must return the same interface for the same module";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        SoundDoseFactoryTest, SoundDoseFactory,
+        testing::ValuesIn(android::getAidlHalInstanceNames(ISoundDoseFactory::descriptor)),
+        android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundDoseFactory);