AudioPrimaryHidlHalTest.cpp revision 161b564b350c6038d9b49edc48ae2a220cc6326c
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/ReturnIn.h"
40f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/AssertOk.h"
41f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/PrettyPrintAudioTypes.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;
52f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::DeviceAddress;
53f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevice;
543c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::V2_0::IPrimaryDevice;
553c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode;
56f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevicesFactory;
57f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStream;
58f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamIn;
59f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamOut;
60f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::ParameterValue;
61f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::Result;
62f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioChannelMask;
63f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioConfig;
64f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioDevice;
65f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioFormat;
66f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioHandleConsts;
67f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioInputFlag;
68f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioIoHandle;
693c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioMode;
70f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
71f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOutputFlag;
72f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioSource;
73f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
74f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing utility::returnIn;
75f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
76f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardnamespace doc {
77f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Document the current test case.
78f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test will output:
79f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard *   <testcase name="debugDump" status="run" time="6" classname="AudioPrimaryHidlTest"
80f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            description="Dump the state of the hal." />
81f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * see https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
82f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard */
83f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid test(const std::string& testCaseDocumentation) {
84f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::Test::RecordProperty("description", testCaseDocumentation);
85f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
86f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
87f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Document why a test was not fully run. Usually due to an optional feature not implemented. */
88f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid partialTest(const std::string& reason) {
89f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::Test::RecordProperty("partialyRunTest", reason);
90f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
91f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
92f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
93f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Register callback for static object destruction
94f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Avoid destroying static objects after main return.
95f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Post main return destruction leads to incorrect gtest timing measurements as well as harder
96f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// debuging if anything goes wrong during destruction.
97f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass Environment : public ::testing::Environment {
98f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardpublic:
99f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    using TearDownFunc = std::function<void ()>;
100f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard     void registerTearDown(TearDownFunc&& tearDown) {
101f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard         tearDowns.push_back(std::move(tearDown));
102f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
103f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
104f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprivate:
105f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void TearDown() override {
106f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // Call the tear downs in reverse order of insertion
107f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        for (auto& tearDown : tearDowns) {
108f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            tearDown();
109f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
110f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
111f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    std::list<TearDownFunc> tearDowns;
112f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
113f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Instance to register global tearDown
114f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic Environment* environment;
115f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
116161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Maclass HidlTest : public ::testing::VtsHalHidlTargetTestBase {
117f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
118f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Convenient member to store results
119f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    Result res;
120f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
121f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
122f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
123f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////// getService audio_devices_factory //////////////////////
124f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
125f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
126f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test all audio devices
127f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioHidlTest : public HidlTest {
128f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardpublic:
129f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void SetUp() override {
130f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
131f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
132f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (devicesFactory == nullptr) {
133f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            environment->registerTearDown([]{ devicesFactory.clear(); });
134161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Ma            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>();
135f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
136f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(devicesFactory != nullptr);
137f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
138f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
139f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
140f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache the devicesFactory retrieval to speed up each test by ~0.5s
141f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static sp<IDevicesFactory> devicesFactory;
142f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
143f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardsp<IDevicesFactory> AudioHidlTest::devicesFactory;
144f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
145f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
146f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("test the getService (called in SetUp)");
147f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
148f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
149f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
150f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// openDevice primary ///////////////////////////
151f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
152f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
153f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test the primary device
154f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioPrimaryHidlTest : public AudioHidlTest {
155f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardpublic:
156f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    /** Primary HAL test are NOT thread safe. */
157f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void SetUp() override {
158f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
159f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
160f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (device == nullptr) {
161f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            IDevicesFactory::Result result;
1623c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            sp<IDevice> baseDevice;
163f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
1643c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                                                 returnIn(result, baseDevice)));
1653c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_TRUE(baseDevice != nullptr);
1663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
1673c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            environment->registerTearDown([]{ device.clear(); });
1683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            device = IPrimaryDevice::castFrom(baseDevice);
1693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_TRUE(device != nullptr);
170f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
171f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
172f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
173f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
174f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache the device opening to speed up each test by ~0.5s
1753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    static sp<IPrimaryDevice> device;
176f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
1773c405a7acf443a5910601763616275f21bb91a41Kevin Rocardsp<IPrimaryDevice> AudioPrimaryHidlTest::device;
178f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
179f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
180f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test the openDevice (called in SetUp)");
181f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
182f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
183f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, Init) {
184f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test that the audio primary hal initialized correctly");
185f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->initCheck());
186f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
187f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
188f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
189f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////// {set,get}MasterVolume ///////////////////////////
190f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
191f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
192f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass MasterVolumeTest : public AudioPrimaryHidlTest {
193f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
194f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void testSetGetConsistency(float volume, Result expectedSetResult, float expectedGetVolume) {
195f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SCOPED_TRACE("Test set/get consistency for " + to_string(volume));
196f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        auto ret = device->setMasterVolume(volume);
197f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(ret.isOk());
198f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_EQ(expectedSetResult, ret);
199f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
200f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        float observedVolume;
201f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK(device->getMasterVolume(returnIn(res, observedVolume)));
202f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK(res);
203f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
204f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // Check that `get` returned the expected value
205f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        EXPECT_EQ(expectedGetVolume, observedVolume);
206f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
207f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
208f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
209f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(MasterVolumeTest, MasterVolumeTest) {
210f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test the master volume if supported");
211f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    {
212f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SCOPED_TRACE("Check for master volume support");
213f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        auto ret = device->setMasterVolume(1);
214f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(ret.isOk());
215f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (ret == Result::NOT_SUPPORTED) {
216f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            doc::partialTest("Master volume is not supported");
217f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            return;
218f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
219f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
220f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // NOTE: this code has never been tested on a platform supporting MasterVolume
221f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    float lastValidVolumeSet;
222f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    using Volumes = float[];
223f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    SCOPED_TRACE("As set/get master volume are supported...");
224f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    {
225f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SCOPED_TRACE("...test them with valid values");
226f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        for (float validVolume : Volumes{0, 0.5, 1}) {
227f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(validVolume, Result::OK, validVolume));
228f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            lastValidVolumeSet = validVolume;
229f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
230f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }{
231f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SCOPED_TRACE("...test them with tricky values");
232f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        for (float outOfBoundVolume :Volumes{-0.1, 1.1, NAN, INFINITY, -INFINITY,
233f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                             1 + std::numeric_limits<float>::epsilon()}) {
234f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(outOfBoundVolume,
235f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                                      Result::INVALID_ARGUMENTS,
236f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                                      lastValidVolumeSet));
237f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
238f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
239f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
240f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
241f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
242f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////// {set,get}{Master,Mic}Mute /////////////////////////
243f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
244f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
2453c405a7acf443a5910601763616275f21bb91a41Kevin Rocardtemplate <class Property>
2463c405a7acf443a5910601763616275f21bb91a41Kevin Rocardclass AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
247f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
2483c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2493c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    /** Test a property getter and setter. */
250f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    template <class Getter, class Setter>
2513c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
2523c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                       Setter setter, Getter getter) {
2533c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2543c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        Property initialValue; // Save initial value to restore it at the end of the test
2553c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
2563c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK(res);
2573c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2583c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        for (Property setValue : valuesToTest) {
2593c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            SCOPED_TRACE("Test " + propertyName + " getter and setter for " + testing::PrintToString(setValue));
2603c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*setter)(setValue));
2613c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            Property getValue;
2623c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            // Make sure the getter returns the same value just set
2633c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
264f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_OK(res);
2653c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            EXPECT_EQ(setValue, getValue);
2663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        }
2673c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK((device.get()->*setter)(initialValue)); // restore initial value
2693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
2703c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
2713c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    /** Test the getter and setter of an optional feature. */
2723c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    template <class Getter, class Setter>
2733c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
2743c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                               Setter setter, Getter getter) {
2753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        doc::test("Test the optional " + propertyName + " getters and setter");
2763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        {
2773c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            SCOPED_TRACE("Test feature support by calling the getter");
2783c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            Property initialValue;
2793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
2803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            if (res == Result::NOT_SUPPORTED) {
2813c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                doc::partialTest(propertyName + " getter is not supported");
2823c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                return;
2833c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            }
2843c405a7acf443a5910601763616275f21bb91a41Kevin Rocard            ASSERT_OK(res); // If it is supported it must succeed
285f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
2863c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        // The feature is supported, test it
2873c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        testAccessors(propertyName, valuesToTest, setter, getter);
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");
2953c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
296f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: check that the mic is really muted (all sample are 0)
297f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
298f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
299f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
300f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("If master mute is supported, try to mute and unmute the master output");
3013c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("master mute", {true, false, true},
3023c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                          &IDevice::setMasterMute, &IDevice::getMasterMute);
303f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: check that the master volume is really muted
304f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
305f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
306f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
307f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////// Required and recommended audio format support ///////////////
308f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// From: https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
309f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// From: https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
310f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////// TODO: move to the beginning of the file for easier update ////////
311f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
312f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
313f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioConfigPrimaryTest : public AudioPrimaryHidlTest {
314f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardpublic:
315f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Cache result ?
316f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
317f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
318f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {8000, 11025, 16000, 22050, 32000, 44100},
319f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
320f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
321f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
322f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
323f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
324f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {24000, 48000},
325f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
326f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
327f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
328f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
329f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: retrieve audio config supported by the platform
330f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // as declared in the policy configuration
331f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return {};
332f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
333f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
334f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
335f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return combineAudioConfig({AudioChannelMask::IN_MONO},
336f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {8000, 11025, 16000, 44100},
337f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
338f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
339f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
340f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return combineAudioConfig({AudioChannelMask::IN_STEREO},
341f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {22050, 48000},
342f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                  {AudioFormat::PCM_16_BIT});
343f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
344f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
345f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: retrieve audio config supported by the platform
346f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // as declared in the policy configuration
347f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return {};
348f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
349f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprivate:
350f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    static const vector<AudioConfig> combineAudioConfig(
351f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            vector<AudioChannelMask> channelMasks,
352f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            vector<uint32_t> sampleRates,
353f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            vector<AudioFormat> formats) {
354f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        vector<AudioConfig> configs;
355f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        for (auto channelMask: channelMasks) {
356f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            for (auto sampleRate : sampleRates) {
357f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                for (auto format : formats) {
358f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    AudioConfig config{};
359f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    // leave offloadInfo to 0
360f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.channelMask = channelMask;
361f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.sampleRateHz = sampleRate;
362f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    config.format = format;
363f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    // FIXME: leave frameCount to 0 ?
364f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                    configs.push_back(config);
365f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                }
366f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            }
367f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
368f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return configs;
369f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
370f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
371f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
372f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
373f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard///////////////////////////// getInputBufferSize /////////////////////////////
374f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
375f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
376f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// FIXME: execute input test only if platform declares android.hardware.microphone
377f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//        how to get this value ? is it a property ???
378f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
379f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest,
380f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                      public ::testing::WithParamInterface<AudioConfig> {
381f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
382f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
383f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        uint64_t bufferSize;
384f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
385f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
386f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        switch (res) {
387f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::INVALID_ARGUMENTS:
388f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                EXPECT_FALSE(supportRequired);
389f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
390f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::OK:
391f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // Check that the buffer is of a sane size
392f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // For now only that it is > 0
393f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                EXPECT_GT(bufferSize, uint64_t(0));
394f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
395f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            default:
396f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
397f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
398f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
399f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
400f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
401f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test that the required capture config and those declared in the policy are indeed supported
402f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
403f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
404f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Input buffer size must be retrievable for a format with required support.");
405f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    inputBufferSizeTest(GetParam(), true);
406f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
407f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
408f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RequiredInputBufferSize, RequiredInputBufferSizeTest,
409f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
410f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
411f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SupportedInputBufferSize, RequiredInputBufferSizeTest,
412f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
413f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
414f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test that the recommended capture config are supported or lead to a INVALID_ARGUMENTS return
415f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
416f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
417f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Input buffer size should be retrievable for a format with recommended support.");
418f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    inputBufferSizeTest(GetParam(), false);
419f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
420f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
421f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
422f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
423f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
424f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
425f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// setScreenState ///////////////////////////////
426f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
427f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
428f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, setScreenState) {
429f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the hal can receive the screen state");
430f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    for (bool turnedOn : {false, true, true, false, false}) {
431f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        auto ret = device->setScreenState(turnedOn);
432f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(ret.isOk());
433f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        Result result = ret;
434f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_TRUE(result == Result::OK || result == Result::NOT_SUPPORTED) << toString(result);
435f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
436f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
437f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
438f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
439f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////// {get,set}Parameters /////////////////////////////
440f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
441f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
442f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, getParameters) {
443f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the hal can set and get parameters");
444f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<hidl_string> keys;
445f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<ParameterValue> values;
446f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
447f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->setParameters(values));
448f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    values.resize(0);
449f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(device->setParameters(values));
450f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
451f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
452f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
453f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////// debugDebug //////////////////////////////////
454f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
455f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
456f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, debugDump) {
457f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that the hal can dump its state without error");
458f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    FILE* file = tmpfile();
459f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_NE(nullptr, file) << errno;
460f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
461f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto* nativeHandle = native_handle_create(1, 0);
462f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_NE(nullptr, nativeHandle);
463f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    nativeHandle->data[0] = fileno(file);
464f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
465f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_handle handle;
466f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    handle.setTo(nativeHandle, true /*take ownership*/);
467f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
468f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto ret = device->debugDump(handle);
469f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_TRUE(ret.isOk());
470f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
471f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // FIXME: debugDump does not return a Result.
472f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // This mean that the hal can not report that it not implementing the function.
473f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // As the default hal does not implement debugDump, the function can not be tested.
474f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    /*
475f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    res = ret;
476f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (res == Result::NOT_SUPPORTED) {
477f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard         doc::partialTest("debugDump is not implemented");
478f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard         return;
479f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
480f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK(res);
481f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    rewind(file);
482f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
483f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Check that at least one bit was written by the hal
484f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    char buff;
485f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_EQ(1, fread(&buff, sizeof(buff), 1, file));
486f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    */
487f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    EXPECT_EQ(0, fclose(file)) << errno;
488f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
489f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
490f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
491f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////// open{Output,Input}Stream //////////////////////////
492f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
493f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
494f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Stream>
495f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OpenStreamTest : public AudioConfigPrimaryTest,
496f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                       public ::testing::WithParamInterface<AudioConfig> {
497f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
498f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    template <class Open>
499f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void testOpen(Open openStream, const AudioConfig& config) {
500f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // FIXME: Open a stream without an IOHandle
501f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        //        This is not required to be accepted by hal implementations
502f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
503f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioConfig suggestedConfig{};
504f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
505f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
506f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // TODO: only allow failure for RecommendedPlaybackAudioConfig
507f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        switch (res) {
508f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::OK:
509f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_TRUE(stream != nullptr);
510f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                audioConfig = config;
511f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
512f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            case Result::INVALID_ARGUMENTS:
513f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_TRUE(stream == nullptr);
514f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                AudioConfig suggestedConfigRetry;
515f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // Could not open stream with config, try again with the suggested one
516f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_OK(openStream(ioHandle, suggestedConfig,
517f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                     returnIn(res, stream, suggestedConfigRetry)));
518f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                // This time it must succeed
519f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_OK(res);
520f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                ASSERT_TRUE(stream == nullptr);
521f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                audioConfig = suggestedConfig;
522f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                break;
523f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            default:
524f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
525f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
526f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        open = true;
527f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
528f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
529f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprivate:
530f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    void TearDown() override {
531f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        if (open) {
532f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard            ASSERT_OK(stream->close());
533f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        }
534f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
535f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
536f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardprotected:
537f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
538f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioConfig audioConfig;
539f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    sp<Stream> stream;
540f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    bool open = false;
541f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
542f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
543f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openOutputStream //////////////////////////////
544f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
545f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OutputStreamTest : public OpenStreamTest<IStreamOut> {
546f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    virtual void SetUp() override {
547f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
548f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
549f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        const AudioConfig& config = GetParam();
550f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        DeviceAddress deviceAddr{};  // Ignored by primary hal
551f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
552f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
553f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                 { return device->openOutputStream(handle, deviceAddr, config, flags, cb); },
554f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                 config);
555f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
556f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
557f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OutputStreamTest, OpenOutputStreamTest) {
558f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that output streams can be open with the required and recommended config");
559f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Open done in SetUp
560f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
561f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
562f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RequiredOutputStreamConfigSupport, OutputStreamTest,
563f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()));
564f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
565f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SupportedOutputStreamConfig, OutputStreamTest,
566f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()));
567f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
568f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
569f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RecommendedOutputStreamConfigSupport, OutputStreamTest,
570f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()));
571f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
572f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openInputStream //////////////////////////////
573f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
574f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass InputStreamTest : public OpenStreamTest<IStreamIn> {
575f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
576f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    virtual void SetUp() override {
577f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
578f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
579f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        const AudioConfig& config = GetParam();
580f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        DeviceAddress deviceAddr{}; // TODO: test all devices
581f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
582f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
583f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
584f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                 { return device->openInputStream(handle, deviceAddr, config, flags, source, cb); },
585f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                 config);
586f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
587f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard};
588f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
589f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(InputStreamTest, OpenInputStreamTest) {
590f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Check that input streams can be open with the required and recommended config");
591f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Open done in setup
592f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
593f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
594f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RequiredInputStreamConfigSupport, InputStreamTest,
595f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
596f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
597f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        SupportedInputStreamConfig, InputStreamTest,
598f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
599f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
600f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P(
601f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        RecommendedInputStreamConfigSupport, InputStreamTest,
602f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
603f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
604f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
605f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// IStream getters ///////////////////////////////
606f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
607f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
608f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Unpack the provided result.
609f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * If the result is not OK, register a failure and return an undefined value. */
610f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class R>
611f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic R extract(Return<R> ret) {
612f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (!ret.isOk()) {
613f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ADD_FAILURE();
614f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return R{};
615f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
616f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    return ret;
617f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
618f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
619f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Property, class CapabilityGetter, class Getter, class Setter>
620f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic void testCapabilityGetter(const string& name,IStream* stream, Property currentValue,
621f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                                 CapabilityGetter capablityGetter, Getter getter, Setter setter) {
622f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    hidl_vec<Property> capabilities;
623f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
624f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (capabilities.size() == 0) {
625f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // The default hal should probably return a NOT_SUPPORTED if the hal does not expose
626f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        // capability retrieval. For now it returns an empty list if not implemented
627f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        doc::partialTest(name + " is not supported");
628f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return;
629f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    };
630f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: This code has never been tested on a hal that supports getSupportedSampleRates
631f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
632f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard             capabilities.end())
633f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        << "current " << name << " is not in the list of the supported ones "
634f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        << toString(capabilities);
635f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
636f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // Check that all declared supported values are indeed supported
637f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    for (auto capability : capabilities) {
638f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_OK((stream->*setter)(capability));
639f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        ASSERT_EQ(capability, extract((stream->*getter)()));
640f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
641f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
642f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
643f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
644f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    uint32_t sampleRateHz;
645f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioChannelMask mask;
646f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioFormat format;
647f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
648f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
649f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
650f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // FIXME: the qcom hal it does not currently negotiate the sampleRate & channel mask
651d1e98aef14a6ad2042548c7c02a9b76c086744edKevin Rocard    EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
652d1e98aef14a6ad2042548c7c02a9b76c086744edKevin Rocard    EXPECT_EQ(expectedConfig.channelMask, mask);
653f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    EXPECT_EQ(expectedConfig.format, format);
654f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
655f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
656f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic void testAccessors(IStream* stream, AudioConfig audioConfig) {
657f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test IStream getters and setters that can be called in the stop state");
658f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
659f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto frameCount = extract(stream->getFrameCount());
660f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_EQ(audioConfig.frameCount, frameCount);
661f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
662f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto sampleRate = extract(stream->getSampleRate());
663f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // FIXME: the qcom hal it does not currently negotiate the sampleRate
664d1e98aef14a6ad2042548c7c02a9b76c086744edKevin Rocard    ASSERT_EQ(audioConfig.sampleRateHz, sampleRate);
665f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
666f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto channelMask = extract(stream->getChannelMask());
667f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // FIXME: the qcom hal it does not currently negotiate the channelMask
668d1e98aef14a6ad2042548c7c02a9b76c086744edKevin Rocard    ASSERT_EQ(audioConfig.channelMask, channelMask);
669f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
670f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto frameSize = extract(stream->getFrameSize());
671f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_GE(frameSize, 0U);
672f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
673f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto bufferSize = extract(stream->getBufferSize());
674f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_GE(bufferSize, frameSize);
675f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
676f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testCapabilityGetter("getSupportedsampleRate", stream, sampleRate,
677f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                         &IStream::getSupportedSampleRates,
678f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                         &IStream::getSampleRate, &IStream::setSampleRate);
679f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
680f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testCapabilityGetter("getSupportedChannelMask", stream, channelMask,
681f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                         &IStream::getSupportedChannelMasks,
682f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                         &IStream::getChannelMask, &IStream::setChannelMask);
683f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
684f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    AudioFormat format = extract(stream->getFormat());
685f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_EQ(audioConfig.format, format);
686f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
687f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testCapabilityGetter("getSupportedFormats", stream, format,
688f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard                         &IStream::getSupportedFormats, &IStream::getFormat, &IStream::setFormat);
689f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
690f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testGetAudioProperties(stream, audioConfig);
691f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
692fd067c3f54669b84b267047d173d15392d178dc4Kevin Rocard    auto ret = stream->getDevice();
693fd067c3f54669b84b267047d173d15392d178dc4Kevin Rocard    ASSERT_TRUE(ret.isOk());
694fd067c3f54669b84b267047d173d15392d178dc4Kevin Rocard    AudioDevice device = ret;
695fd067c3f54669b84b267047d173d15392d178dc4Kevin Rocard    ASSERT_EQ(AudioDevice::OUT_DEFAULT, device);
696f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
697f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
698f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(InputStreamTest, GettersTest) {
699f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testAccessors(stream.get(), audioConfig);
700f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
701f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OutputStreamTest, GettersTest) {
702f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    testAccessors(stream.get(), audioConfig);
703f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
704f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
705f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
706f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////// AudioPatches ////////////////////////////////
707f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
708f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
709f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
710f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, AudioPatches) {
711f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    doc::test("Test if audio patches are supported");
712f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    auto result = device->supportsAudioPatches();
713f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ASSERT_TRUE(result.isOk());
714f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    bool supportsAudioPatch = result;
715f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    if (!supportsAudioPatch) {
716f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        doc::partialTest("Audio patches are not supported");
717f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard        return;
718f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    }
719f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    // TODO: test audio patches
720f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
721f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
722f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
7233c405a7acf443a5910601763616275f21bb91a41Kevin Rocard/////////////////////////////// PrimaryDevice ////////////////////////////////
7243c405a7acf443a5910601763616275f21bb91a41Kevin Rocard//////////////////////////////////////////////////////////////////////////////
7253c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7263c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
7273c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
7283c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    for (float volume : {0.0, 0.01, 0.5, 0.09, 1.0}) {
7293c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        SCOPED_TRACE("volume=" + to_string(volume));
7303c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK(device->setVoiceVolume(volume));
7313c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
7323c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    for (float volume : (float[]){-INFINITY,-1.0, -0.0,
7333c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                                  1.0 + std::numeric_limits<float>::epsilon(), 2.0, INFINITY,
7343c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                                  NAN}) {
7353c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        SCOPED_TRACE("volume=" + to_string(volume));
7363c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        // FIXME: NAN should never be accepted
7373c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        // FIXME: Missing api doc. What should the impl do if the volume is outside [0,1] ?
7383c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_INVALID_ARGUMENTS(device->setVoiceVolume(volume));
7393c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
7403c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7413c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7423c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(AudioPrimaryHidlTest, setMode) {
7433c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Make sure setMode always succeeds if mode is valid");
7443c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION,
7453c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                           AudioMode::RINGTONE, AudioMode::CURRENT,
7463c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                           AudioMode::NORMAL /* Make sure to leave the test in normal mode */ }) {
7473c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        SCOPED_TRACE("mode=" + toString(mode));
7483c405a7acf443a5910601763616275f21bb91a41Kevin Rocard        ASSERT_OK(device->setMode(mode));
7493c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    }
7503c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7513c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    // FIXME: Missing api doc. What should the impl do if the mode is invalid ?
7523c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    ASSERT_INVALID_ARGUMENTS(device->setMode(AudioMode::INVALID));
7533c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7543c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7553c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7563c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
7573c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the BT SCO NR&EC state");
7583c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
7593c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::setBtScoNrecEnabled,
7603c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::getBtScoNrecEnabled);
7613c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7623c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7633c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
7643c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the SCO whideband state");
7653c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("BtScoWideband", {true, false, true},
7663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::setBtScoWidebandEnabled,
7673c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::getBtScoWidebandEnabled);
7683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7703c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
7713c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
7723c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the TTY mode state");
7733c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testOptionalAccessors("TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
7743c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                          &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
7753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7773c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
7783c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    doc::test("Query and set the HAC state");
7793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard    testAccessors("HAC", {true, false, true},
7803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::setHacEnabled,
7813c405a7acf443a5910601763616275f21bb91a41Kevin Rocard                         &IPrimaryDevice::getHacEnabled);
7823c405a7acf443a5910601763616275f21bb91a41Kevin Rocard}
7833c405a7acf443a5910601763616275f21bb91a41Kevin Rocard
7843c405a7acf443a5910601763616275f21bb91a41Kevin Rocard//////////////////////////////////////////////////////////////////////////////
785f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////// Clean caches on global tear down ////////////////////////
786f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////////////////////////////////////////////////////
787f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard
788f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardint main(int argc, char** argv) {
789f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    environment = new Environment;
790f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::AddGlobalTestEnvironment(environment);
791f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    ::testing::InitGoogleTest(&argc, argv);
792f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    int status = RUN_ALL_TESTS();
793f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    LOG(INFO) << "Test result = " << status;
794f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard    return status;
795f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}
796