1f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/*
2f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Copyright (C) 2017 The Android Open Source Project
3f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard *
4f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Licensed under the Apache License, Version 2.0 (the "License");
5f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * you may not use this file except in compliance with the License.
6f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * You may obtain a copy of the License at
7f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard *
8f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard *      http://www.apache.org/licenses/LICENSE-2.0
9f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard *
10f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Unless required by applicable law or agreed to in writing, software
11f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * distributed under the License is distributed on an "AS IS" BASIS,
12f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * See the License for the specific language governing permissions and
14f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * limitations under the License.
15f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard */
16f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
17f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#define LOG_TAG "VtsHalAudioV2_0TargetTest"
18f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
19f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <algorithm>
20f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cmath>
21f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cstddef>
22f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cstdio>
23f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <limits>
24f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <list>
25f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <string>
26f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <type_traits>
27f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <vector>
28f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
29161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Ma#include <VtsHalHidlTargetTestBase.h>
30f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
31f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android-base/logging.h>
32f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
33f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/IDevice.h>
34f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/IDevicesFactory.h>
353c405a7acf443a5910601763616275f21bb91a41Kevin Rocard#include <android/hardware/audio/2.0/IPrimaryDevice.h>
36f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/types.h>
37f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/common/2.0/types.h>
38f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
39f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/AssertOk.h"
40f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/PrettyPrintAudioTypes.h"
4172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard#include "utility/ReturnIn.h"
42f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
43f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::string;
44f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::to_string;
45f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::vector;
46f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
47f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::sp;
48f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::Return;
49f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_handle;
50f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_string;
51f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_vec;
52c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ::android::hardware::MQDescriptorSync;
53624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::AudioDrain;
54f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::DeviceAddress;
55f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevice;
563c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::V2_0::IPrimaryDevice;
573c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode;
58f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevicesFactory;
59f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStream;
60f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamIn;
61624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::TimeSpec;
6272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardusing ReadParameters =
6372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
64c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
65f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamOut;
66624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamOutCallback;
678878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardusing ::android::hardware::audio::V2_0::MmapBufferInfo;
688878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardusing ::android::hardware::audio::V2_0::MmapPosition;
69f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::ParameterValue;
70f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::Result;
71f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioChannelMask;
72f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioConfig;
73f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioDevice;
74f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioFormat;
75f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioHandleConsts;
76f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioInputFlag;
77f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioIoHandle;
783c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioMode;
79f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
80f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOutputFlag;
81f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioSource;
82c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ::android::hardware::audio::common::V2_0::ThreadInfo;
83f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
84f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing utility::returnIn;
85f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
8696f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocardconst char* getTestName() {
8796f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard    return ::testing::UnitTest::GetInstance()->current_test_info()->name();
8896f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard}
8996f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard
90f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardnamespace doc {
91f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Document the current test case.
9272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test
9372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * will output:
9472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard *   <testcase name="debugDump" status="run" time="6"
9572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard *             classname="AudioPrimaryHidlTest"
9672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               description="Dump the state of the hal." />
9772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * see
9872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
99f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard */
100f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid test(const std::string& testCaseDocumentation) {
101f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::Test::RecordProperty("description", testCaseDocumentation);
102f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
103f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
10472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard/** Document why a test was not fully run. Usually due to an optional feature
10572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * not implemented. */
106f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid partialTest(const std::string& reason) {
10796f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard    LOG(INFO) << "Test " << getTestName() << " partially run: " << reason;
108f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::Test::RecordProperty("partialyRunTest", reason);
109f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
1105e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard
1115e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard/** Add a note to the test. */
1125e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocardvoid note(const std::string& note) {
11396f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard    LOG(INFO) << "Test " << getTestName() << " noted: " << note;
1145e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    ::testing::Test::RecordProperty("note", note);
1155e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard}
116f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
117f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
118f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Register callback for static object destruction
119f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Avoid destroying static objects after main return.
12072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Post main return destruction leads to incorrect gtest timing measurements as
12172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// well as harder
122f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// debuging if anything goes wrong during destruction.
123f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass Environment : public ::testing::Environment {
12472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   public:
12572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    using TearDownFunc = std::function<void()>;
12672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    void registerTearDown(TearDownFunc&& tearDown) {
12772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        tearDowns.push_back(std::move(tearDown));
128f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
129f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
13072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   private:
131f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void TearDown() override {
132f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // Call the tear downs in reverse order of insertion
133f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        for (auto& tearDown : tearDowns) {
134f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            tearDown();
135f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
136f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
137f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    std::list<TearDownFunc> tearDowns;
138f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
139f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Instance to register global tearDown
140f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic Environment* environment;
141f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
142161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Maclass HidlTest : public ::testing::VtsHalHidlTargetTestBase {
14372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
144f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Convenient member to store results
145f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    Result res;
146f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
147f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
148f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
149f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////// getService audio_devices_factory //////////////////////
150f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
151f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
152f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test all audio devices
153f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioHidlTest : public HidlTest {
15472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   public:
155f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void SetUp() override {
15672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
157f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
158f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (devicesFactory == nullptr) {
15972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            environment->registerTearDown([] { devicesFactory.clear(); });
16072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<
16172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                IDevicesFactory>();
162f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
163f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(devicesFactory != nullptr);
164f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
165f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
16672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
167f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache the devicesFactory retrieval to speed up each test by ~0.5s
168f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static sp<IDevicesFactory> devicesFactory;
169f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
170f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardsp<IDevicesFactory> AudioHidlTest::devicesFactory;
171f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
172f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
173f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("test the getService (called in SetUp)");
174f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
175f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
1768604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail NaganovTEST_F(AudioHidlTest, OpenDeviceInvalidParameter) {
1778604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    doc::test("test passing an invalid parameter to openDevice");
1788604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    IDevicesFactory::Result result;
1798604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    sp<IDevice> device;
1808604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device(-1),
1818604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov                                         returnIn(result, device)));
1828604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    ASSERT_EQ(IDevicesFactory::Result::INVALID_ARGUMENTS, result);
1838604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov    ASSERT_TRUE(device == nullptr);
1848604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov}
1858604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov
186f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
187f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// openDevice primary ///////////////////////////
188f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
189f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
190f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test the primary device
191f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioPrimaryHidlTest : public AudioHidlTest {
19272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   public:
193f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    /** Primary HAL test are NOT thread safe. */
194f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void SetUp() override {
19572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
196f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
197f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (device == nullptr) {
198f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            IDevicesFactory::Result result;
1993c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            sp<IDevice> baseDevice;
20072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            ASSERT_OK(
20172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
20272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                           returnIn(result, baseDevice)));
203fba442a60d199441d06bf03375cb7904768403daKevin Rocard            ASSERT_OK(result);
2043c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_TRUE(baseDevice != nullptr);
2053c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
20672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            environment->registerTearDown([] { device.clear(); });
2073c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            device = IPrimaryDevice::castFrom(baseDevice);
2083c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_TRUE(device != nullptr);
209f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
210f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
211f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
21272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
213f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache the device opening to speed up each test by ~0.5s
2143c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    static sp<IPrimaryDevice> device;
215f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
2163c405a7acf443a5910601763616275f21bb91a41Kevin Rocardsp<IPrimaryDevice> AudioPrimaryHidlTest::device;
217f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
218f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
219f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test the openDevice (called in SetUp)");
220f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
221f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
222f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, Init) {
223f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test that the audio primary hal initialized correctly");
224f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->initCheck());
225f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
226f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
227f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
22892ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
229f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
230f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
2313c405a7acf443a5910601763616275f21bb91a41Kevin Rocardtemplate <class Property>
2323c405a7acf443a5910601763616275f21bb91a41Kevin Rocardclass AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
23372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
2343c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    /** Test a property getter and setter. */
235f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    template <class Getter, class Setter>
23672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    void testAccessors(const string& propertyName,
23772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                       const vector<Property>& valuesToTest, Setter setter,
23872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                       Getter getter,
23992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                       const vector<Property>& invalidValues = {}) {
24072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        Property initialValue;  // Save initial value to restore it at the end
24172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                // of the test
2423c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
2433c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK(res);
2443c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2453c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        for (Property setValue : valuesToTest) {
24692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard            SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
24792ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                         testing::PrintToString(setValue));
2483c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*setter)(setValue));
2493c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            Property getValue;
2503c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            // Make sure the getter returns the same value just set
2513c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
252f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_OK(res);
2533c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            EXPECT_EQ(setValue, getValue);
2543c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        }
2553c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
25692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard        for (Property invalidValue : invalidValues) {
25772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            SCOPED_TRACE("Try to set " + propertyName +
25872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                         " with the invalid value " +
25992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                         testing::PrintToString(invalidValue));
26072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            EXPECT_RESULT(Result::INVALID_ARGUMENTS,
26172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          (device.get()->*setter)(invalidValue));
26292ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard        }
26392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard
26472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_OK(
26572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            (device.get()->*setter)(initialValue));  // restore initial value
2663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
2673c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    /** Test the getter and setter of an optional feature. */
2693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    template <class Getter, class Setter>
27072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    void testOptionalAccessors(const string& propertyName,
27172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                               const vector<Property>& valuesToTest,
27292ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                               Setter setter, Getter getter,
27392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                               const vector<Property>& invalidValues = {}) {
2743c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        doc::test("Test the optional " + propertyName + " getters and setter");
2753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        {
2763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            SCOPED_TRACE("Test feature support by calling the getter");
2773c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            Property initialValue;
2783c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
2793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            if (res == Result::NOT_SUPPORTED) {
2803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                doc::partialTest(propertyName + " getter is not supported");
2813c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                return;
2823c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            }
28372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            ASSERT_OK(res);  // If it is supported it must succeed
284f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
2853c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        // The feature is supported, test it
28672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        testAccessors(propertyName, valuesToTest, setter, getter,
28772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                      invalidValues);
288f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
289f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
290f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
2913c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
2923c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
293f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
294f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the mic can be muted and unmuted");
29572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute,
29672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                  &IDevice::getMicMute);
297f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: check that the mic is really muted (all sample are 0)
298f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
299f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
300f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
30172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
30272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If master mute is supported, try to mute and unmute the master "
30372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "output");
3043c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("master mute", {true, false, true},
3053c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                          &IDevice::setMasterMute, &IDevice::getMasterMute);
306f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: check that the master volume is really muted
307f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
308f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
30992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocardusing FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
31092ce35df946b0514e1e73a4f976cccff9e49823bKevin RocardTEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
31192ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard    doc::test("Test the master volume if supported");
31272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testOptionalAccessors("master volume", {0, 0.5, 1},
31392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                          &IDevice::setMasterVolume, &IDevice::getMasterVolume,
31492ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                          {-0.1, 1.1, NAN, INFINITY, -INFINITY,
31592ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard                           1 + std::numeric_limits<float>::epsilon()});
31692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard    // TODO: check that the master volume is really changed
31792ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard}
31892ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard
319f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
3208878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////// AudioPatches ////////////////////////////////
3218878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////////////////////////////////////////////////////
3228878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
3238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardclass AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
32472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
3258878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    bool areAudioPatchesSupported() {
3268878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        auto result = device->supportsAudioPatches();
327f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        EXPECT_IS_OK(result);
3288878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        return result;
3298878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    }
3308878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard};
3318878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
3328878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
3338878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    doc::test("Test if audio patches are supported");
3348878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    if (!areAudioPatchesSupported()) {
3358878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        doc::partialTest("Audio patches are not supported");
3368878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        return;
3378878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    }
3388878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    // TODO: test audio patches
3398878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
3408878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
3418878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////////////////////////////////////////////////////
342f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////// Required and recommended audio format support ///////////////
34372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// From:
34472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
34572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// From:
34672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
347f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////// TODO: move to the beginning of the file for easier update ////////
348f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
349f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
3508878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardclass AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
35172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   public:
352f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache result ?
353f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
35472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        return combineAudioConfig(
35572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
35672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            {8000, 11025, 16000, 22050, 32000, 44100},
35772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            {AudioFormat::PCM_16_BIT});
358f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
359f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
36072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    static const vector<AudioConfig>
36172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    getRecommendedSupportPlaybackAudioConfig() {
36272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        return combineAudioConfig(
36372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
36472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            {24000, 48000}, {AudioFormat::PCM_16_BIT});
365f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
366f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
367f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
368f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: retrieve audio config supported by the platform
369f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // as declared in the policy configuration
370f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return {};
371f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
372f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
373f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
374f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return combineAudioConfig({AudioChannelMask::IN_MONO},
375f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {8000, 11025, 16000, 44100},
376f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
377f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
378f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
37972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
380f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
381f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
382f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
383f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: retrieve audio config supported by the platform
384f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // as declared in the policy configuration
385f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return {};
386f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
38772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard
38872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   private:
389f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> combineAudioConfig(
39072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        vector<AudioChannelMask> channelMasks, vector<uint32_t> sampleRates,
39172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        vector<AudioFormat> formats) {
392f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        vector<AudioConfig> configs;
39372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        for (auto channelMask : channelMasks) {
394f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            for (auto sampleRate : sampleRates) {
395f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                for (auto format : formats) {
396f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    AudioConfig config{};
397f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    // leave offloadInfo to 0
398f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.channelMask = channelMask;
399f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.sampleRateHz = sampleRate;
400f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.format = format;
401f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    // FIXME: leave frameCount to 0 ?
402f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    configs.push_back(config);
403f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                }
404f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            }
405f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
406f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return configs;
407f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
408f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
409f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
4109c369149837baf173401b5033b5ec96214362631Kevin Rocard/** Generate a test name based on an audio config.
4119c369149837baf173401b5033b5ec96214362631Kevin Rocard *
4129c369149837baf173401b5033b5ec96214362631Kevin Rocard * As the only parameter changing are channel mask and sample rate,
4139c369149837baf173401b5033b5ec96214362631Kevin Rocard * only print those ones in the test name.
4149c369149837baf173401b5033b5ec96214362631Kevin Rocard */
41572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic string generateTestName(
41672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    const testing::TestParamInfo<AudioConfig>& info) {
4179c369149837baf173401b5033b5ec96214362631Kevin Rocard    const AudioConfig& config = info.param;
41872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
41972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard           // "MONO" is more clear than "FRONT_LEFT"
42072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard           ((config.channelMask == AudioChannelMask::OUT_MONO ||
42172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard             config.channelMask == AudioChannelMask::IN_MONO)
42272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                ? "MONO"
42372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                : toString(config.channelMask));
4249c369149837baf173401b5033b5ec96214362631Kevin Rocard}
4259c369149837baf173401b5033b5ec96214362631Kevin Rocard
426f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
427f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard///////////////////////////// getInputBufferSize /////////////////////////////
428f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
429f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
43072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// FIXME: execute input test only if platform declares
43172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// android.hardware.microphone
432f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//        how to get this value ? is it a property ???
433f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
43472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardclass AudioCaptureConfigPrimaryTest
43572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    : public AudioConfigPrimaryTest,
43672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard      public ::testing::WithParamInterface<AudioConfig> {
43772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
43872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    void inputBufferSizeTest(const AudioConfig& audioConfig,
43972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                             bool supportRequired) {
440f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        uint64_t bufferSize;
44172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_OK(
44272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
443f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
444f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        switch (res) {
445f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::INVALID_ARGUMENTS:
446f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                EXPECT_FALSE(supportRequired);
447f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
448f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::OK:
449f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // Check that the buffer is of a sane size
450f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // For now only that it is > 0
451f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                EXPECT_GT(bufferSize, uint64_t(0));
452f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
453f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            default:
45472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                FAIL() << "Invalid return status: "
45572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                       << ::testing::PrintToString(res);
456f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
457f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
458f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
459f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
46072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Test that the required capture config and those declared in the policy are
46172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// indeed supported
462f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
463f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
46472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
46572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Input buffer size must be retrievable for a format with required "
46672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "support.");
467f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    inputBufferSizeTest(GetParam(), true);
468f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
469f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
47072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RequiredInputBufferSize, RequiredInputBufferSizeTest,
47172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
47272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
47372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
474f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
47572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    SupportedInputBufferSize, RequiredInputBufferSizeTest,
47672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
47772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
47872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
479f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
48072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Test that the recommended capture config are supported or lead to a
48172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// INVALID_ARGUMENTS return
482f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
483f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
48472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
48572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Input buffer size should be retrievable for a format with recommended "
48672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "support.");
487f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    inputBufferSizeTest(GetParam(), false);
488f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
489f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
49072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
49172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
49272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
49372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
494f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
495f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
496f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// setScreenState ///////////////////////////////
497f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
498f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
499f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, setScreenState) {
500f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the hal can receive the screen state");
501f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    for (bool turnedOn : {false, true, true, false, false}) {
502f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        auto ret = device->setScreenState(turnedOn);
503f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        ASSERT_IS_OK(ret);
504f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        Result result = ret;
505f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
506f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        ASSERT_RESULT(okOrNotSupported, result);
507f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
508f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
509f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
510f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
511f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////// {get,set}Parameters /////////////////////////////
512f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
513f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
514f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, getParameters) {
515f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the hal can set and get parameters");
516f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<hidl_string> keys;
517f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<ParameterValue> values;
518f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
519f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->setParameters(values));
520f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    values.resize(0);
521f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->setParameters(values));
522f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
523f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
524f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
525f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////// debugDebug //////////////////////////////////
526f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
527f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
528b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocardtemplate <class DebugDump>
529b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocardstatic void testDebugDump(DebugDump debugDump) {
5305e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    // Dump in a temporary file
5315e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    // Note that SELinux must be deactivate for this test to work
532f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    FILE* file = tmpfile();
533f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_NE(nullptr, file) << errno;
534f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
5355e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    // Wrap the temporary file file descriptor in a native handle
536f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto* nativeHandle = native_handle_create(1, 0);
537f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_NE(nullptr, nativeHandle);
538f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    nativeHandle->data[0] = fileno(file);
539f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
5405e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    // Wrap this native handle in a hidl handle
541f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_handle handle;
542f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    handle.setTo(nativeHandle, true /*take ownership*/);
543f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
5445e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    ASSERT_OK(debugDump(handle));
5455e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard
5465e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    // Check that at least one bit was written by the hal
547ee771e9cfac6d0ec1d930ef9e71b1c7bd9b91fa9Kevin Rocard    // TODO: debugDump does not return a Result.
54872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // This mean that the hal can not report that it not implementing the
54972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // function.
55072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    rewind(file);  // can not fail
551f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    char buff;
5525e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    if (fread(&buff, sizeof(buff), 1, file) != 1) {
5535e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard        doc::note("debugDump does not seem implemented");
5545e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard    }
555f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    EXPECT_EQ(0, fclose(file)) << errno;
556f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
557f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
5585e5783daef84deecd53bfb1e94a0177e667b71dbKevin RocardTEST_F(AudioPrimaryHidlTest, DebugDump) {
559b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard    doc::test("Check that the hal can dump its state without error");
56072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testDebugDump(
56172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        [this](const auto& handle) { return device->debugDump(handle); });
562b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard}
563b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard
5645e5783daef84deecd53bfb1e94a0177e667b71dbKevin RocardTEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
5653e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov    doc::test("Check that the hal dump doesn't crash on invalid arguments");
5663e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov    ASSERT_OK(device->debugDump(hidl_handle()));
5673e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov}
5683e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov
569f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
570f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////// open{Output,Input}Stream //////////////////////////
571f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
572f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
573f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Stream>
574f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OpenStreamTest : public AudioConfigPrimaryTest,
575f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                       public ::testing::WithParamInterface<AudioConfig> {
57672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
577f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    template <class Open>
578f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void testOpen(Open openStream, const AudioConfig& config) {
579f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // FIXME: Open a stream without an IOHandle
580f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        //        This is not required to be accepted by hal implementations
58172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioIoHandle ioHandle =
58272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
583f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioConfig suggestedConfig{};
58472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_OK(openStream(ioHandle, config,
58572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                             returnIn(res, stream, suggestedConfig)));
586f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
587f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: only allow failure for RecommendedPlaybackAudioConfig
588f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        switch (res) {
589f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::OK:
590f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_TRUE(stream != nullptr);
591f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                audioConfig = config;
592f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
593f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::INVALID_ARGUMENTS:
594f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_TRUE(stream == nullptr);
595f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                AudioConfig suggestedConfigRetry;
59672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                // Could not open stream with config, try again with the
59772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                // suggested one
59872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                ASSERT_OK(
59972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                    openStream(ioHandle, suggestedConfig,
60072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                               returnIn(res, stream, suggestedConfigRetry)));
601f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // This time it must succeed
602f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_OK(res);
6034aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard                ASSERT_TRUE(stream != nullptr);
604f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                audioConfig = suggestedConfig;
605f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
606f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            default:
60772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                FAIL() << "Invalid return status: "
60872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                       << ::testing::PrintToString(res);
609f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
610f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        open = true;
611f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
612f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
6138878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    Return<Result> closeStream() {
6148878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        open = false;
6158878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        return stream->close();
6168878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    }
61772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard
61872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   private:
619f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void TearDown() override {
620f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (open) {
621f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_OK(stream->close());
622f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
623f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
624f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
62572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard   protected:
626f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioConfig audioConfig;
6278878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    DeviceAddress address = {};
628f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    sp<Stream> stream;
629f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    bool open = false;
630f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
631f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
632f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openOutputStream //////////////////////////////
633f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
634f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OutputStreamTest : public OpenStreamTest<IStreamOut> {
635f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    virtual void SetUp() override {
63672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
6378878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        address.device = AudioDevice::OUT_DEFAULT;
638f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        const AudioConfig& config = GetParam();
63972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioOutputFlag flags =
64072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            AudioOutputFlag::NONE;  // TODO: test all flag combination
64172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        testOpen(
64272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            [&](AudioIoHandle handle, AudioConfig config, auto cb) {
64372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                return device->openOutputStream(handle, address, config, flags,
64472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                                cb);
64572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            },
64672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            config);
647f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
648f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
649f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OutputStreamTest, OpenOutputStreamTest) {
65072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
65172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Check that output streams can be open with the required and "
65272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "recommended config");
653f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Open done in SetUp
654f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
655f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
65672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RequiredOutputStreamConfigSupport, OutputStreamTest,
65772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
65872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
65972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
660f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
66172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    SupportedOutputStreamConfig, OutputStreamTest,
66272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
66372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
66472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
665f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
666f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
66772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RecommendedOutputStreamConfigSupport, OutputStreamTest,
66872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
66972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
67072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
671f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
672f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openInputStream //////////////////////////////
673f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
674f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass InputStreamTest : public OpenStreamTest<IStreamIn> {
675f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    virtual void SetUp() override {
67672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
6778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        address.device = AudioDevice::IN_DEFAULT;
678f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        const AudioConfig& config = GetParam();
67972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioInputFlag flags =
68072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            AudioInputFlag::NONE;  // TODO: test all flag combination
68172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioSource source =
68272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            AudioSource::DEFAULT;  // TODO: test all flag combination
68372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        testOpen(
68472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            [&](AudioIoHandle handle, AudioConfig config, auto cb) {
68572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                return device->openInputStream(handle, address, config, flags,
68672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                               source, cb);
68772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            },
68872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard            config);
689f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
690f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
691f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
692f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(InputStreamTest, OpenInputStreamTest) {
69372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
69472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Check that input streams can be open with the required and "
69572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "recommended config");
696f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Open done in setup
697f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
698f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
69972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RequiredInputStreamConfigSupport, InputStreamTest,
70072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
70172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
70272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
703f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
70472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    SupportedInputStreamConfig, InputStreamTest,
70572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
70672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
70772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
708f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
709f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
71072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    RecommendedInputStreamConfigSupport, InputStreamTest,
71172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ::testing::ValuesIn(
71272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
71372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    &generateTestName);
714f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
715f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
716f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// IStream getters ///////////////////////////////
717f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
718f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
719f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Unpack the provided result.
720f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * If the result is not OK, register a failure and return an undefined value. */
721f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class R>
722f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic R extract(Return<R> ret) {
723f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (!ret.isOk()) {
724f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        EXPECT_IS_OK(ret);
725f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return R{};
726f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
727f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    return ret;
728f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
729f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
730a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard/* Could not find a way to write a test for two parametrized class fixure
731a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard * thus use this macro do duplicate tests for Input and Output stream */
732a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard#define TEST_IO_STREAM(test_name, documentation, code) \
73372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    TEST_P(InputStreamTest, test_name) {               \
73472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        doc::test(documentation);                      \
73572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        code;                                          \
73672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    }                                                  \
73772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    TEST_P(OutputStreamTest, test_name) {              \
73872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        doc::test(documentation);                      \
73972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        code;                                          \
740a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard    }
741a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
74272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
74372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    GetFrameCount,
74472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Check that the stream frame count == the one it was opened with",
74572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
746a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
74772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
74872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    GetSampleRate,
74972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Check that the stream sample rate == the one it was opened with",
750fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard    stream->getSampleRate())
751a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
75272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
75372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    GetChannelMask,
75472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Check that the stream channel mask == the one it was opened with",
755fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard    stream->getChannelMask())
756a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
75772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetFormat,
75872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream format == the one it was opened with",
759a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard               ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
760a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
761a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard// TODO: for now only check that the framesize is not incoherent
76272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetFrameSize,
76372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream frame size == the one it was opened with",
764a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard               ASSERT_GT(extract(stream->getFrameSize()), 0U))
765a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
76672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetBufferSize,
76772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream buffer size== the one it was opened with",
76872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               ASSERT_GE(extract(stream->getBufferSize()),
76972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                         extract(stream->getFrameSize())));
770a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
771f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Property, class CapabilityGetter, class Getter, class Setter>
77272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testCapabilityGetter(const string& name, IStream* stream,
77372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                 Property currentValue,
77472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                 CapabilityGetter capablityGetter,
77572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                 Getter getter, Setter setter) {
776f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<Property> capabilities;
777f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
778f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (capabilities.size() == 0) {
77972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        // The default hal should probably return a NOT_SUPPORTED if the hal
78072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        // does not expose
78172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        // capability retrieval. For now it returns an empty list if not
78272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        // implemented
783f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        doc::partialTest(name + " is not supported");
784f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return;
785f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    };
78672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // TODO: This code has never been tested on a hal that supports
78772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // getSupportedSampleRates
788f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
78972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard              capabilities.end())
790f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        << "current " << name << " is not in the list of the supported ones "
791f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        << toString(capabilities);
792f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
793f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Check that all declared supported values are indeed supported
794f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    for (auto capability : capabilities) {
795f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK((stream->*setter)(capability));
796f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_EQ(capability, extract((stream->*getter)()));
797f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
798f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
799f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
80072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedSampleRate,
80172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream sample rate is declared as supported",
80272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               testCapabilityGetter("getSupportedSampleRate", stream.get(),
80372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    extract(stream->getSampleRate()),
80472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::getSupportedSampleRates,
80572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::getSampleRate,
80672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::setSampleRate))
80772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard
80872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedChannelMask,
80972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream channel mask is declared as supported",
81072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               testCapabilityGetter("getSupportedChannelMask", stream.get(),
81172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    extract(stream->getChannelMask()),
81272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::getSupportedChannelMasks,
81372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::getChannelMask,
81472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::setChannelMask))
81572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard
81672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedFormat,
81772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream format is declared as supported",
81872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               testCapabilityGetter("getSupportedFormat", stream.get(),
81972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    extract(stream->getFormat()),
82072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                    &IStream::getSupportedFormats,
821a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard                                    &IStream::getFormat, &IStream::setFormat))
822a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard
8238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
8248f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard    // Unfortunately the interface does not allow the implementation to return
8258f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard    // NOT_SUPPORTED
8268f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard    // Thus allow NONE as signaling that the call is not supported.
8278878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    auto ret = stream->getDevice();
828f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard    ASSERT_IS_OK(ret);
8298878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    AudioDevice device = ret;
8308f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard    ASSERT_TRUE(device == expectedDevice || device == AudioDevice::NONE)
8318f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard        << "Expected: " << ::testing::PrintToString(expectedDevice)
8328f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard        << "\n  Actual: " << ::testing::PrintToString(device);
8338878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
8348878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
83572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetDevice,
83672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream device == the one it was opened with",
83772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               areAudioPatchesSupported()
83872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                   ? doc::partialTest("Audio patches are supported")
83972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                   : testGetDevice(stream.get(), address.device))
8408878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
8418878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testSetDevice(IStream* stream, const DeviceAddress& address) {
8428878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    DeviceAddress otherAddress = address;
84372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0
84472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                              ? AudioDevice::OUT_SPEAKER
84572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                              : AudioDevice::IN_BUILTIN_MIC;
8468878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    EXPECT_OK(stream->setDevice(otherAddress));
8478878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
84872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ASSERT_OK(stream->setDevice(address));  // Go back to the original value
8498878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
8508878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
85172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
85272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    SetDevice,
85372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
85472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
85572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                               : testSetDevice(stream.get(), address))
8568878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
857fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocardstatic void testGetAudioProperties(IStream* stream) {
858f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    uint32_t sampleRateHz;
859f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioChannelMask mask;
860f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioFormat format;
861f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
862f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
863f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
86472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
86572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    GetAudioProperties,
86672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Check that the stream audio properties == the ones it was opened with",
867fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard    testGetAudioProperties(stream.get()))
868f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
8698878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testConnectedState(IStream* stream) {
8708878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    DeviceAddress address = {};
8718878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    using AD = AudioDevice;
87272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    for (auto device :
87372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard         {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
8748878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        address.device = device;
8758878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
8768878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        ASSERT_OK(stream->setConnectedState(address, true));
8778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard        ASSERT_OK(stream->setConnectedState(address, false));
8788878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    }
8798878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
8808878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(SetConnectedState,
88172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Check that the stream can be notified of device connection and "
88272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "deconnection",
8838878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               testConnectedState(stream.get()))
8848878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
885f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocardstatic auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS,
886f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard                                             Result::NOT_SUPPORTED, Result::OK};
8878878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
888f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard               ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
88972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                             stream->setHwAvSync(666)))
8908878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
891e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin RocardTEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
892f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard               ASSERT_IS_OK(device->getHwAvSync()));
893e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard
894fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocardstatic void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
895fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard                                vector<Result> expectedResults) {
8968878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    hidl_vec<ParameterValue> parameters;
8978878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    Result res;
8988878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
8998878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_RESULT(expectedResults, res);
9008878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    if (res == Result::OK) {
9014aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard        for (auto& parameter : parameters) {
9024aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard            ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
9034aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard        }
9048878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    }
9058878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
9068878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
90772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard/* Get/Set parameter is intended to be an opaque channel between vendors app and
90872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * their HALs.
9098878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard * Thus can not be meaningfully tested.
9108878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard */
9118878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
912fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard               checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
9138878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
91472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(getNonExistingParameter,
91572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Retrieve the values of an non existing parameter",
916fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard               checkGetNoParameter(stream.get(),
917fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard                                   {"Non existing key"} /* keys */,
918fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard                                   {Result::NOT_SUPPORTED}))
9198878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
92072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(setEmptySetParameter,
92172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Set the values of an empty set of parameters",
922f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard               ASSERT_RESULT(Result::OK, stream->setParameters({})))
9238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
92472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
92572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    setNonExistingParameter, "Set the values of an non existing parameter",
926f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard    // Unfortunately, the set_parameter legacy interface did not return any
927f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard    // error code when a key is not supported.
928f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard    // To allow implementation to just wrapped the legacy one, consider OK as a
929f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard    // valid result for setting a non existing parameter.
930f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard    ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
93172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                  stream->setParameters({{"non existing key", "0"}})))
9328878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
933b903124b365a095b56cce6ac4345fc1166d937c7Kevin RocardTEST_IO_STREAM(DebugDump,
934b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard               "Check that a stream can dump its state without error",
93572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               testDebugDump([this](const auto& handle) {
93672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                   return stream->debugDump(handle);
93772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               }))
938b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard
9393e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail NaganovTEST_IO_STREAM(DebugDumpInvalidArguments,
9403e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov               "Check that the stream dump doesn't crash on invalid arguments",
9413e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov               ASSERT_OK(stream->debugDump(hidl_handle())))
9423e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov
943f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
9448878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////// addRemoveEffect ///////////////////////////////
945f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
946f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
9478878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
9488878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
94972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(RemoveNonExistingEffect,
95072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Removing a non existing effect should fail",
95172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               ASSERT_RESULT(Result::INVALID_ARGUMENTS,
95272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                             stream->removeEffect(666)))
953f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
95472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// TODO: positive tests
9558878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
9568878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////////////////////////////////////////////////////
9578878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard/////////////////////////////// Control ////////////////////////////////
9588878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////////////////////////////////////////////////////
9598878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
9608878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
96172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               ASSERT_OK(stream->standby()))  // can not fail
9628878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
96372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE,
96472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                                    Result::NOT_SUPPORTED};
9658878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
96672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(startNoMmap,
96772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Starting a mmaped stream before mapping it should fail",
9688878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
9698878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
97072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(stopNoMmap,
97172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Stopping a mmaped stream before mapping it should fail",
9728878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
9738878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
97472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(getMmapPositionNoMmap,
97572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               "Get a stream Mmap position before mapping it should fail",
9768878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
9778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
97872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(close, "Make sure a stream can be closed",
97972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               ASSERT_OK(closeStream()))
9808878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
98172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard               ASSERT_OK(closeStream());
9828878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
9838878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
984f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocardstatic auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS,
985f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard                                         Result::NOT_SUPPORTED};
9868878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testCreateTooBigMmapBuffer(IStream* stream) {
9878878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    MmapBufferInfo info;
9888878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    Result res;
9898878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    // Assume that int max is a value too big to be allocated
99072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // This is true currently with a 32bit media server, but might not when it
99172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    // will run in 64 bit
9928878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    auto minSizeFrames = std::numeric_limits<int32_t>::max();
9938878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
9948878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_RESULT(invalidArgsOrNotSupported, res);
9958878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}
9968878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
9978878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
9988878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard               testCreateTooBigMmapBuffer(stream.get()))
9998878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
10008878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
10018878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    Result res;
10028878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    MmapPosition position;
10038878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
10048878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard    ASSERT_RESULT(invalidArgsOrNotSupported, res);
1005f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
1006f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
100772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(
100872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    GetMmapPositionOfNonMmapedStream,
100972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    "Retrieving the mmap position of a non mmaped stream should fail",
101072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testGetMmapPositionOfNonMmapedStream(stream.get()))
10118878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard
1012f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
1013c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard///////////////////////////////// StreamIn ///////////////////////////////////
10143c405a7acf443a5910601763616275f21bb91a41Kevin Rocard//////////////////////////////////////////////////////////////////////////////
10153c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
1016c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, GetAudioSource) {
101772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
101872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Retrieving the audio source of an input stream should always succeed");
1019c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    AudioSource source;
1020c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
102198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    if (res == Result::NOT_SUPPORTED) {
102298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        doc::partialTest("getAudioSource is not supported");
102398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        return;
102498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    }
1025c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    ASSERT_OK(res);
1026c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    ASSERT_EQ(AudioSource::DEFAULT, source);
1027c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1028c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
102972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
1030c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard    for (float value :
1031c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard         (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(),
1032c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard                   2.0, INFINITY, NAN}) {
1033a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard        EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value="
1034a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard                                                                 << value;
10353c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
1036c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard    // Do not consider -0.0 as an invalid value as it is == with 0.0
1037c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard    for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
1038a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard        EXPECT_OK(setGain(value)) << "value=" << value;
1039c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard    }
10403c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
10413c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
104298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocardstatic void testOptionalUnitaryGain(
104398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    std::function<Return<Result>(float)> setGain, string debugName) {
104498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    auto result = setGain(1);
1045f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard    ASSERT_IS_OK(result);
104698390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    if (result == Result::NOT_SUPPORTED) {
104798390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        doc::partialTest(debugName + " is not supported");
104898390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        return;
104998390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    }
105098390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    testUnitaryGain(setGain);
105198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard}
105298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard
1053c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, SetGain) {
1054c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    doc::test("The gain of an input stream should only be set between [0,1]");
105598390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    testOptionalUnitaryGain(
105698390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        [this](float volume) { return stream->setGain(volume); },
105798390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        "InputStream::setGain");
1058c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1059c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
106072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testPrepareForReading(IStreamIn* stream, uint32_t frameSize,
106172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                  uint32_t framesCount) {
1062c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    Result res;
1063c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    // Ignore output parameters as the call should fail
106472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ASSERT_OK(stream->prepareForReading(
106572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        frameSize, framesCount,
106672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1067fcf186bd5949f3bbb4274f8f7bf4ab9e4497d541Kevin Rocard    EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1068c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1069c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
1070195205b323b7d93cf4d477445469759b27371f45Kevin RocardTEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
1071195205b323b7d93cf4d477445469759b27371f45Kevin Rocard    doc::test(
1072195205b323b7d93cf4d477445469759b27371f45Kevin Rocard        "Preparing a stream for reading with a 0 sized buffer should fail");
1073195205b323b7d93cf4d477445469759b27371f45Kevin Rocard    testPrepareForReading(stream.get(), 0, 0);
1074195205b323b7d93cf4d477445469759b27371f45Kevin Rocard}
1075195205b323b7d93cf4d477445469759b27371f45Kevin Rocard
1076c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
107772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
107872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Preparing a stream for reading with a 2^32 sized buffer should fail");
107972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testPrepareForReading(stream.get(), 1,
108072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          std::numeric_limits<uint32_t>::max());
1081c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1082c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
1083c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
108472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
108572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Preparing a stream for reading with a overflowing sized buffer should "
108672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "fail");
1087c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    auto uintMax = std::numeric_limits<uint32_t>::max();
1088c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    testPrepareForReading(stream.get(), uintMax, uintMax);
1089c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1090c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
1091e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin RocardTEST_P(InputStreamTest, GetInputFramesLost) {
109272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
109372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "The number of frames lost on a never started stream should be 0");
1094e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    auto ret = stream->getInputFramesLost();
1095f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard    ASSERT_IS_OK(ret);
1096e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    uint32_t framesLost{ret};
1097e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    ASSERT_EQ(0U, framesLost);
1098e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard}
1099e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard
1100c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, getCapturePosition) {
110172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
110272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "The capture position of a non prepared stream should not be "
110372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "retrievable");
1104c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    uint64_t frames;
1105c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    uint64_t time;
1106c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
1107c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    ASSERT_RESULT(invalidStateOrNotSupported, res);
1108c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1109c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
1110c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard//////////////////////////////////////////////////////////////////////////////
1111624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard///////////////////////////////// StreamIn ///////////////////////////////////
1112624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard//////////////////////////////////////////////////////////////////////////////
1113624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1114624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, getLatency) {
1115624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    doc::test("Make sure latency is over 0");
1116624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    auto result = stream->getLatency();
1117f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard    ASSERT_IS_OK(result);
1118624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_GT(result, 0U);
1119624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1120624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1121624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, setVolume) {
1122624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    doc::test("Try to set the output volume");
112398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    testOptionalUnitaryGain(
112498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        [this](float volume) { return stream->setVolume(volume, volume); },
112598390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard        "setVolume");
1126624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1127624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
112872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize,
112972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                                  uint32_t framesCount) {
1130624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Result res;
1131624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    // Ignore output parameters as the call should fail
113272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ASSERT_OK(stream->prepareForWriting(
113372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        frameSize, framesCount,
113472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1135fcf186bd5949f3bbb4274f8f7bf4ab9e4497d541Kevin Rocard    EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1136624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1137624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1138195205b323b7d93cf4d477445469759b27371f45Kevin RocardTEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
1139195205b323b7d93cf4d477445469759b27371f45Kevin Rocard    doc::test(
1140195205b323b7d93cf4d477445469759b27371f45Kevin Rocard        "Preparing a stream for writing with a 0 sized buffer should fail");
1141195205b323b7d93cf4d477445469759b27371f45Kevin Rocard    testPrepareForWriting(stream.get(), 0, 0);
1142195205b323b7d93cf4d477445469759b27371f45Kevin Rocard}
1143195205b323b7d93cf4d477445469759b27371f45Kevin Rocard
1144624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
114572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
114672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Preparing a stream for writing with a 2^32 sized buffer should fail");
114772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testPrepareForWriting(stream.get(), 1,
114872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          std::numeric_limits<uint32_t>::max());
1149624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1150624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1151624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
115272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
115372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Preparing a stream for writing with a overflowing sized buffer should "
115472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "fail");
1155624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    auto uintMax = std::numeric_limits<uint32_t>::max();
1156624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    testPrepareForWriting(stream.get(), uintMax, uintMax);
1157624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1158624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1159624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardstruct Capability {
1160624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Capability(IStreamOut* stream) {
1161624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
1162624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        auto ret = stream->supportsDrain();
1163f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard        EXPECT_IS_OK(ret);
1164624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        if (ret.isOk()) {
1165624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard            drain = ret;
1166624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        }
1167624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1168624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    bool pause = false;
1169624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    bool resume = false;
1170624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    bool drain = false;
1171624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard};
1172624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1173624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
117472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
117572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "Implementation must expose pause, resume and drain capabilities");
1176624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Capability(stream.get());
1177624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1178624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1179304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocardtemplate <class Value>
1180304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocardstatic void checkInvalidStateOr0(Result res, Value value) {
1181304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    switch (res) {
1182304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard        case Result::INVALID_STATE:
1183304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard            break;
1184304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard        case Result::OK:
1185304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard            ASSERT_EQ(0U, value);
1186304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard            break;
1187304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard        default:
1188304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard            FAIL() << "Unexpected result " << toString(res);
1189304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    }
1190304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard}
1191304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard
1192624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetRenderPosition) {
1193304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    doc::test("A new stream render position should be 0 or INVALID_STATE");
1194624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    uint32_t dspFrames;
1195624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
1196624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (res == Result::NOT_SUPPORTED) {
1197624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("getRenderPosition is not supported");
1198624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1199624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1200304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    checkInvalidStateOr0(res, dspFrames);
1201624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1202624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1203624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetNextWriteTimestamp) {
1204304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
1205624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    uint64_t timestampUs;
1206e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
1207624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (res == Result::NOT_SUPPORTED) {
1208e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard        doc::partialTest("getNextWriteTimestamp is not supported");
1209624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1210624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1211304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard    checkInvalidStateOr0(res, timestampUs);
1212624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1213624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1214624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard/** Stub implementation of out stream callback. */
1215624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardclass MockOutCallbacks : public IStreamOutCallback {
1216624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Return<void> onWriteReady() override { return {}; }
1217624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Return<void> onDrainReady() override { return {}; }
1218624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    Return<void> onError() override { return {}; }
1219624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard};
1220624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
122172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic bool isAsyncModeSupported(IStreamOut* stream) {
1222624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    auto res = stream->setCallback(new MockOutCallbacks);
122372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    stream->clearCallback();  // try to restore the no callback state, ignore
122472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                              // any error
122572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
1226624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    EXPECT_RESULT(okOrNotSupported, res);
1227624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    return res.isOk() ? res == Result::OK : false;
1228624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1229624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1230624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, SetCallback) {
123172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
123272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If supported, registering callback for async operation should never "
123372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "fail");
1234624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (!isAsyncModeSupported(stream.get())) {
1235624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("The stream does not support async operations");
1236624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1237624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1238624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1239624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1240624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1241624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1242624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, clearCallback) {
124372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
124472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If supported, clearing a callback to go back to sync operation should "
124572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "not fail");
1246624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (!isAsyncModeSupported(stream.get())) {
1247624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("The stream does not support async operations");
1248624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1249624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1250624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    // TODO: Clarify if clearing a non existing callback should fail
1251624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1252624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->clearCallback());
1253624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1254624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1255624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, Resume) {
125672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
125772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If supported, a stream should fail to resume if not previously "
125872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "paused");
1259624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (!Capability(stream.get()).resume) {
1260624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("The output stream does not support resume");
1261624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1262624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1263624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1264624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1265624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1266624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, Pause) {
126772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
126872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If supported, a stream should fail to pause if not previously "
126972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "started");
1270624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (!Capability(stream.get()).pause) {
1271624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("The output stream does not support pause");
1272624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1273624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1274624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1275624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1276624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
127772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testDrain(IStreamOut* stream, AudioDrain type) {
1278624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (!Capability(stream).drain) {
12796f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard        doc::partialTest("The output stream does not support drain");
1280624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1281624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1282624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_RESULT(Result::OK, stream->drain(type));
1283624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1284624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1285624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, DrainAll) {
12866f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard    doc::test("If supported, a stream should always succeed to drain");
1287624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    testDrain(stream.get(), AudioDrain::ALL);
1288624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1289624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1290624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, DrainEarlyNotify) {
12916f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard    doc::test("If supported, a stream should always succeed to drain");
1292624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
1293624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1294624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1295624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, FlushStop) {
12966f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard    doc::test("If supported, a stream should always succeed to flush");
1297e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    auto ret = stream->flush();
1298f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard    ASSERT_IS_OK(ret);
1299e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    if (ret == Result::NOT_SUPPORTED) {
1300e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard        doc::partialTest("Flush is not supported");
1301e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard        return;
1302e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    }
1303e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard    ASSERT_OK(ret);
1304624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1305624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1306624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetPresentationPositionStop) {
130772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    doc::test(
130872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "If supported, a stream should always succeed to retrieve the "
130972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "presentation position");
1310624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    uint64_t frames;
1311624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    TimeSpec mesureTS;
1312624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
1313624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    if (res == Result::NOT_SUPPORTED) {
1314624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        doc::partialTest("getpresentationPosition is not supported");
1315624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard        return;
1316624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    }
1317624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_EQ(0U, frames);
1318624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1319476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard    if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) {
1320476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard        // As the stream has never written a frame yet,
1321476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard        // the timestamp does not really have a meaning, allow to return 0
1322476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard        return;
1323476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard    }
1324476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard
1325476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard    // Make sure the return measure is not more than 1s old.
1326624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    struct timespec currentTS;
1327624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
1328624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
132972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    auto toMicroSec = [](uint64_t sec, auto nsec) {
133072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        return sec * 1e+6 + nsec / 1e+3;
133172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    };
1332624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
1333624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard    auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
133472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime,
133572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                 mesureTime);
1336624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}
1337624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard
1338624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard//////////////////////////////////////////////////////////////////////////////
1339c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard/////////////////////////////// PrimaryDevice ////////////////////////////////
1340c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard//////////////////////////////////////////////////////////////////////////////
1341c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
1342c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
1343c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard    doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
134472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testUnitaryGain(
134572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        [this](float volume) { return device->setVoiceVolume(volume); });
1346c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard}
1347c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard
13483c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(AudioPrimaryHidlTest, setMode) {
134904364edefcc39a5f620156a35209b760eb66a916Kevin Rocard    doc::test(
135004364edefcc39a5f620156a35209b760eb66a916Kevin Rocard        "Make sure setMode always succeeds if mode is valid "
135104364edefcc39a5f620156a35209b760eb66a916Kevin Rocard        "and fails otherwise");
135204364edefcc39a5f620156a35209b760eb66a916Kevin Rocard    // Test Invalid values
135304364edefcc39a5f620156a35209b760eb66a916Kevin Rocard    for (AudioMode mode :
135404364edefcc39a5f620156a35209b760eb66a916Kevin Rocard         {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
135504364edefcc39a5f620156a35209b760eb66a916Kevin Rocard        SCOPED_TRACE("mode=" + toString(mode));
135604364edefcc39a5f620156a35209b760eb66a916Kevin Rocard        ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
135704364edefcc39a5f620156a35209b760eb66a916Kevin Rocard    }
135804364edefcc39a5f620156a35209b760eb66a916Kevin Rocard    // Test valid values
135972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    for (AudioMode mode :
136072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard         {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
136172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard          AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
13623c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        SCOPED_TRACE("mode=" + toString(mode));
13633c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK(device->setMode(mode));
13643c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
13653c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
13663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
13673c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
13683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the BT SCO NR&EC state");
13693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
137072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          &IPrimaryDevice::setBtScoNrecEnabled,
137172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          &IPrimaryDevice::getBtScoNrecEnabled);
13723c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
13733c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
13743c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
13753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the SCO whideband state");
13763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("BtScoWideband", {true, false, true},
137772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          &IPrimaryDevice::setBtScoWidebandEnabled,
137872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard                          &IPrimaryDevice::getBtScoWidebandEnabled);
13793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
13803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
13813c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
13823c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
13833c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the TTY mode state");
138472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    testOptionalAccessors(
138572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        "TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
138672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard        &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
13873c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
13883c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
13893c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
13903c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the HAC state");
139198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard    testOptionalAccessors("HAC", {true, false, true},
139298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard                          &IPrimaryDevice::setHacEnabled,
139398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard                          &IPrimaryDevice::getHacEnabled);
13943c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
13953c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
13963c405a7acf443a5910601763616275f21bb91a41Kevin Rocard//////////////////////////////////////////////////////////////////////////////
1397f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////// Clean caches on global tear down ////////////////////////
1398f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
1399f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
1400f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardint main(int argc, char** argv) {
1401f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    environment = new Environment;
1402f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::AddGlobalTestEnvironment(environment);
1403f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::InitGoogleTest(&argc, argv);
1404f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    int status = RUN_ALL_TESTS();
1405f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    LOG(INFO) << "Test result = " << status;
1406f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    return status;
1407f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
1408