1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsHalAudioVTargetTest"
18 
19 #include <algorithm>
20 #include <cmath>
21 #include <cstddef>
22 #include <cstdio>
23 #include <initializer_list>
24 #include <limits>
25 #include <list>
26 #include <map>
27 #include <set>
28 #include <string>
29 #include <variant>
30 #include <vector>
31 
32 #include <fcntl.h>
33 #include <unistd.h>
34 
35 #include <hwbinder/IPCThreadState.h>
36 
37 #include <android-base/logging.h>
38 #include <system/audio_config.h>
39 
40 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
41 #include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
42 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
43 #include PATH(android/hardware/audio/FILE_VERSION/types.h)
44 #include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
45 
46 #include <Serializer.h>
47 #include <fmq/EventFlag.h>
48 #include <fmq/MessageQueue.h>
49 #include <hidl/GtestPrinter.h>
50 #include <hidl/ServiceManagement.h>
51 
52 #include <common/all-versions/VersionUtils.h>
53 
54 #include "utility/AssertOk.h"
55 #include "utility/Documentation.h"
56 #include "utility/ReturnIn.h"
57 #include "utility/ValidateXml.h"
58 
59 /** Provide version specific functions that are used in the generic tests */
60 #if MAJOR_VERSION == 2
61 #include "2.0/AudioPrimaryHidlHalUtils.h"
62 #elif MAJOR_VERSION >= 4
63 #include "4.0/AudioPrimaryHidlHalUtils.h"
64 #endif
65 
66 using std::initializer_list;
67 using std::list;
68 using std::string;
69 using std::to_string;
70 using std::vector;
71 
72 using ::android::AudioPolicyConfig;
73 using ::android::HwModule;
74 using ::android::NO_INIT;
75 using ::android::OK;
76 using ::android::sp;
77 using ::android::status_t;
78 using ::android::hardware::EventFlag;
79 using ::android::hardware::hidl_bitfield;
80 using ::android::hardware::hidl_enum_range;
81 using ::android::hardware::hidl_handle;
82 using ::android::hardware::hidl_string;
83 using ::android::hardware::hidl_vec;
84 using ::android::hardware::IPCThreadState;
85 using ::android::hardware::kSynchronizedReadWrite;
86 using ::android::hardware::MessageQueue;
87 using ::android::hardware::MQDescriptorSync;
88 using ::android::hardware::Return;
89 using ::android::hardware::audio::common::utils::EnumBitfield;
90 using ::android::hardware::audio::common::utils::mkEnumBitfield;
91 using ::android::hardware::details::toHexString;
92 
93 using namespace ::android::hardware::audio::common::CPP_VERSION;
94 using namespace ::android::hardware::audio::common::test::utility;
95 using namespace ::android::hardware::audio::CPP_VERSION;
96 
97 // Typical accepted results from interface methods
98 static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
99 static auto okOrNotSupportedOrInvalidArgs = {Result::OK, Result::NOT_SUPPORTED,
100                                              Result::INVALID_ARGUMENTS};
101 static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE,
102                                               Result::NOT_SUPPORTED};
103 static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
104 static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
105 
106 #define AUDIO_PRIMARY_HIDL_HAL_TEST
107 #include "DeviceManager.h"
108 
109 class HidlTest : public ::testing::Test {
110   public:
111     virtual ~HidlTest() = default;
112     // public access to avoid annoyances when using this method in template classes
113     // derived from test classes
getDevice()114     sp<IDevice> getDevice() const {
115         return DeviceManager::getInstance().get(getFactoryName(), getDeviceName());
116     }
117 
118   protected:
119     // Factory and device name getters to be overridden in subclasses.
120     virtual const std::string& getFactoryName() const = 0;
121     virtual const std::string& getDeviceName() const = 0;
122 
getDevicesFactory()123     sp<IDevicesFactory> getDevicesFactory() const {
124         return DevicesFactoryManager::getInstance().get(getFactoryName());
125     }
resetDevice()126     bool resetDevice() const {
127         return DeviceManager::getInstance().reset(getFactoryName(), getDeviceName());
128     }
areAudioPatchesSupported()129     bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
130 
131     // Convenient member to store results
132     Result res;
133 };
134 
135 //////////////////////////////////////////////////////////////////////////////
136 ////////////////////////// Audio policy configuration ////////////////////////
137 //////////////////////////////////////////////////////////////////////////////
138 
139 static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
140 
141 // Stringify the argument.
142 #define QUOTE(x) #x
143 #define STRINGIFY(x) QUOTE(x)
144 
145 struct PolicyConfigData {
146     android::HwModuleCollection hwModules;
147     android::DeviceVector availableOutputDevices;
148     android::DeviceVector availableInputDevices;
149     sp<android::DeviceDescriptor> defaultOutputDevice;
150 };
151 
152 class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
153    public:
PolicyConfig()154     PolicyConfig()
155         : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
156                             defaultOutputDevice) {
157         for (const auto& location : android::audio_get_configuration_paths()) {
158             std::string path = location + '/' + kConfigFileName;
159             if (access(path.c_str(), F_OK) == 0) {
160                 mFilePath = path;
161                 break;
162             }
163         }
164         mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
165         if (mStatus == OK) {
166             mPrimaryModule = getHwModules().getModuleFromName(DeviceManager::kPrimaryDevice);
167             // Available devices are not 'attached' to modules at this moment.
168             // Need to go over available devices and find their module.
169             for (const auto& device : availableOutputDevices) {
170                 for (const auto& module : hwModules) {
171                     if (module->getDeclaredDevices().indexOf(device) >= 0) {
172                         mModulesWithDevicesNames.insert(module->getName());
173                         break;
174                     }
175                 }
176             }
177             for (const auto& device : availableInputDevices) {
178                 for (const auto& module : hwModules) {
179                     if (module->getDeclaredDevices().indexOf(device) >= 0) {
180                         mModulesWithDevicesNames.insert(module->getName());
181                         break;
182                     }
183                 }
184             }
185         }
186     }
getStatus()187     status_t getStatus() const { return mStatus; }
getError()188     std::string getError() const {
189         if (mFilePath.empty()) {
190             return std::string{"Could not find "} + kConfigFileName +
191                    " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
192         } else {
193             return "Invalid config file: " + mFilePath;
194         }
195     }
getFilePath()196     const std::string& getFilePath() const { return mFilePath; }
getModuleFromName(const std::string & name)197     sp<const HwModule> getModuleFromName(const std::string& name) const {
198         return getHwModules().getModuleFromName(name.c_str());
199     }
getPrimaryModule()200     sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
getModulesWithDevicesNames()201     const std::set<std::string>& getModulesWithDevicesNames() const {
202         return mModulesWithDevicesNames;
203     }
204 
205    private:
206     status_t mStatus = NO_INIT;
207     std::string mFilePath;
208     sp<HwModule> mPrimaryModule = nullptr;
209     std::set<std::string> mModulesWithDevicesNames;
210 };
211 
212 // Cached policy config after parsing for faster test startup
getCachedPolicyConfig()213 const PolicyConfig& getCachedPolicyConfig() {
214     static std::unique_ptr<PolicyConfig> policyConfig = [] {
215         auto config = std::make_unique<PolicyConfig>();
216         return config;
217     }();
218     return *policyConfig;
219 }
220 
221 //////////////////////////////////////////////////////////////////////////////
222 //////////////////// Test parameter types and definitions ////////////////////
223 //////////////////////////////////////////////////////////////////////////////
224 
225 enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
226 using DeviceParameter = std::tuple<std::string, std::string>;
227 
DeviceParameterToString(const::testing::TestParamInfo<DeviceParameter> & info)228 static inline std::string DeviceParameterToString(
229         const ::testing::TestParamInfo<DeviceParameter>& info) {
230     const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
231     const auto factoryName =
232             ::android::hardware::PrintInstanceNameToString(::testing::TestParamInfo<std::string>{
233                     std::get<PARAM_FACTORY_NAME>(info.param), info.index});
234     return !deviceName.empty() ? factoryName + "_" + deviceName : factoryName;
235 }
236 
getDeviceParameters()237 const std::vector<DeviceParameter>& getDeviceParameters() {
238     static std::vector<DeviceParameter> parameters = [] {
239         std::vector<DeviceParameter> result;
240         const auto factories =
241                 ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
242         const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
243         result.reserve(devices.size());
244         for (const auto& factoryName : factories) {
245             for (const auto& deviceName : devices) {
246                 if (DeviceManager::getInstance().get(factoryName, deviceName) != nullptr) {
247                     result.emplace_back(factoryName, deviceName);
248                 }
249             }
250         }
251         return result;
252     }();
253     return parameters;
254 }
255 
getDeviceParametersForFactoryTests()256 const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
257     static std::vector<DeviceParameter> parameters = [] {
258         std::vector<DeviceParameter> result;
259         const auto factories =
260                 ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
261         for (const auto& factoryName : factories) {
262             result.emplace_back(factoryName,
263                                 DeviceManager::getInstance().getPrimary(factoryName) != nullptr
264                                         ? DeviceManager::kPrimaryDevice
265                                         : "");
266         }
267         return result;
268     }();
269     return parameters;
270 }
271 
getDeviceParametersForPrimaryDeviceTests()272 const std::vector<DeviceParameter>& getDeviceParametersForPrimaryDeviceTests() {
273     static std::vector<DeviceParameter> parameters = [] {
274         std::vector<DeviceParameter> result;
275         const auto primary = std::find_if(
276                 getDeviceParameters().begin(), getDeviceParameters().end(), [](const auto& elem) {
277                     return std::get<PARAM_DEVICE_NAME>(elem) == DeviceManager::kPrimaryDevice;
278                 });
279         if (primary != getDeviceParameters().end()) result.push_back(*primary);
280         return result;
281     }();
282     return parameters;
283 }
284 
285 class AudioHidlTestWithDeviceParameter : public HidlTest,
286                                          public ::testing::WithParamInterface<DeviceParameter> {
287   protected:
getFactoryName()288     const std::string& getFactoryName() const override {
289         return std::get<PARAM_FACTORY_NAME>(GetParam());
290     }
getDeviceName()291     const std::string& getDeviceName() const override {
292         return std::get<PARAM_DEVICE_NAME>(GetParam());
293     }
294 };
295 
TEST(CheckConfig,audioPolicyConfigurationValidation)296 TEST(CheckConfig, audioPolicyConfigurationValidation) {
297     auto deviceParameters = getDeviceParametersForFactoryTests();
298     if (deviceParameters.size() == 0) {
299         GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no device parameter "
300                         "is found.";
301     }
302     RecordProperty("description",
303                    "Verify that the audio policy configuration file "
304                    "is valid according to the schema");
305 
306     const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
307     EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName,
308                                             android::audio_get_configuration_paths(), xsd);
309 }
310 
311 class AudioPolicyConfigTest : public AudioHidlTestWithDeviceParameter {
312   public:
SetUp()313     void SetUp() override {
314         ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp());  // setup base
315         auto& policyConfig = getCachedPolicyConfig();
316         ASSERT_EQ(0, policyConfig.getStatus()) << policyConfig.getError();
317     }
318 };
319 
TEST_P(AudioPolicyConfigTest,LoadAudioPolicyXMLConfiguration)320 TEST_P(AudioPolicyConfigTest, LoadAudioPolicyXMLConfiguration) {
321     doc::test("Test parsing audio_policy_configuration.xml (called in SetUp)");
322 }
323 
TEST_P(AudioPolicyConfigTest,HasPrimaryModule)324 TEST_P(AudioPolicyConfigTest, HasPrimaryModule) {
325     auto& policyConfig = getCachedPolicyConfig();
326     ASSERT_TRUE(policyConfig.getPrimaryModule() != nullptr)
327             << "Could not find primary module in configuration file: "
328             << policyConfig.getFilePath();
329 }
330 
331 INSTANTIATE_TEST_CASE_P(AudioHidl, AudioPolicyConfigTest,
332                         ::testing::ValuesIn(getDeviceParametersForFactoryTests()),
333                         &DeviceParameterToString);
334 
335 //////////////////////////////////////////////////////////////////////////////
336 ////////////////////// getService audio_devices_factory //////////////////////
337 //////////////////////////////////////////////////////////////////////////////
338 
339 // Test audio devices factory
340 class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
341   public:
SetUp()342     void SetUp() override {
343         ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp());  // setup base
344         ASSERT_TRUE(getDevicesFactory() != nullptr);
345     }
346 };
347 
TEST_P(AudioHidlTest,GetAudioDevicesFactoryService)348 TEST_P(AudioHidlTest, GetAudioDevicesFactoryService) {
349     doc::test("Test the getService");
350 }
351 
TEST_P(AudioHidlTest,OpenDeviceInvalidParameter)352 TEST_P(AudioHidlTest, OpenDeviceInvalidParameter) {
353     doc::test("Test passing an invalid parameter to openDevice");
354     Result result;
355     sp<IDevice> device;
356 #if MAJOR_VERSION == 2
357     auto invalidDevice = IDevicesFactory::Device(-1);
358 #elif MAJOR_VERSION >= 4
359     auto invalidDevice = "Non existing device";
360 #endif
361     ASSERT_OK(getDevicesFactory()->openDevice(invalidDevice, returnIn(result, device)));
362     ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
363     ASSERT_TRUE(device == nullptr);
364 }
365 
366 INSTANTIATE_TEST_CASE_P(AudioHidl, AudioHidlTest,
367                         ::testing::ValuesIn(getDeviceParametersForFactoryTests()),
368                         &DeviceParameterToString);
369 
370 //////////////////////////////////////////////////////////////////////////////
371 /////////////////////////////// openDevice ///////////////////////////////////
372 //////////////////////////////////////////////////////////////////////////////
373 
374 // Test all audio devices
375 class AudioHidlDeviceTest : public AudioHidlTest {
376   public:
SetUp()377     void SetUp() override {
378         ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
379         ASSERT_TRUE(getDevice() != nullptr);
380     }
381 };
382 
TEST_P(AudioHidlDeviceTest,OpenDevice)383 TEST_P(AudioHidlDeviceTest, OpenDevice) {
384     doc::test("Test openDevice (called during setup)");
385 }
386 
TEST_P(AudioHidlDeviceTest,Init)387 TEST_P(AudioHidlDeviceTest, Init) {
388     doc::test("Test that the audio hal initialized correctly");
389     ASSERT_OK(getDevice()->initCheck());
390 }
391 
392 INSTANTIATE_TEST_CASE_P(AudioHidlDevice, AudioHidlDeviceTest,
393                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
394 
395 //////////////////////////////////////////////////////////////////////////////
396 /////////////////////////////// openDevice primary ///////////////////////////
397 //////////////////////////////////////////////////////////////////////////////
398 
399 // Test the primary device
400 class AudioPrimaryHidlTest : public AudioHidlDeviceTest {
401   public:
SetUp()402     void SetUp() override {
403         ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
404         ASSERT_TRUE(getDevice() != nullptr);
405     }
406 
407     // public access to avoid annoyances when using this method in template classes
408     // derived from test classes
getDevice()409     sp<IPrimaryDevice> getDevice() const {
410         return DeviceManager::getInstance().getPrimary(getFactoryName());
411     }
412 };
413 
TEST_P(AudioPrimaryHidlTest,OpenPrimaryDevice)414 TEST_P(AudioPrimaryHidlTest, OpenPrimaryDevice) {
415     doc::test("Test openPrimaryDevice (called during setup)");
416 }
417 
418 INSTANTIATE_TEST_CASE_P(AudioPrimaryHidl, AudioPrimaryHidlTest,
419                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
420                         &DeviceParameterToString);
421 
422 //////////////////////////////////////////////////////////////////////////////
423 ///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
424 //////////////////////////////////////////////////////////////////////////////
425 
426 template <class Property, class BaseTestClass = AudioHidlDeviceTest>
427 class AccessorHidlTest : public BaseTestClass {
428   protected:
429     enum Optionality { REQUIRED, OPTIONAL };
430     struct Initial {  // Initial property value
valueInitial431         Initial(Property value, Optionality check = REQUIRED) : value(value), check(check) {}
432         Property value;
433         Optionality check;  // If this initial value should be checked
434     };
435     using BaseTestClass::res;
436     /** Test a property getter and setter.
437      *  The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
438      */
439     template <Optionality optionality = REQUIRED, class IUTGetter, class Getter, class Setter>
440     void testAccessors(IUTGetter iutGetter, const string& propertyName,
441                        const Initial expectedInitial, list<Property> valuesToTest, Setter setter,
442                        Getter getter, const vector<Property>& invalidValues = {}) {
443         const auto expectedResults = {Result::OK,
444                                       optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
445 
446         Property initialValue = expectedInitial.value;
447         ASSERT_OK(((this->*iutGetter)().get()->*getter)(returnIn(res, initialValue)));
448         ASSERT_RESULT(expectedResults, res);
449         if (res == Result::OK && expectedInitial.check == REQUIRED) {
450             EXPECT_EQ(expectedInitial.value, initialValue);
451         }
452 
453         valuesToTest.push_front(expectedInitial.value);
454         valuesToTest.push_back(initialValue);
455         for (Property setValue : valuesToTest) {
456             SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
457                          testing::PrintToString(setValue));
458             auto ret = ((this->*iutGetter)().get()->*setter)(setValue);
459             ASSERT_RESULT(expectedResults, ret);
460             if (ret == Result::NOT_SUPPORTED) {
461                 doc::partialTest(propertyName + " setter is not supported");
462                 break;
463             }
464             Property getValue;
465             // Make sure the getter returns the same value just set
466             ASSERT_OK(((this->*iutGetter)().get()->*getter)(returnIn(res, getValue)));
467             ASSERT_RESULT(expectedResults, res);
468             if (res == Result::NOT_SUPPORTED) {
469                 doc::partialTest(propertyName + " getter is not supported");
470                 continue;
471             }
472             EXPECT_EQ(setValue, getValue);
473         }
474 
475         for (Property invalidValue : invalidValues) {
476             SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
477                          testing::PrintToString(invalidValue));
478             EXPECT_RESULT(invalidArgsOrNotSupported,
479                           ((this->*iutGetter)().get()->*setter)(invalidValue));
480         }
481 
482         // Restore initial value
483         EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue));
484     }
485     template <Optionality optionality = REQUIRED, class Getter, class Setter>
486     void testAccessors(const string& propertyName, const Initial expectedInitial,
487                        list<Property> valuesToTest, Setter setter, Getter getter,
488                        const vector<Property>& invalidValues = {}) {
489         testAccessors<optionality>(&BaseTestClass::getDevice, propertyName, expectedInitial,
490                                    valuesToTest, setter, getter, invalidValues);
491     }
492 };
493 
494 using BoolAccessorHidlTest = AccessorHidlTest<bool>;
495 using BoolAccessorPrimaryHidlTest = AccessorHidlTest<bool, AudioPrimaryHidlTest>;
496 
TEST_P(BoolAccessorHidlTest,MicMuteTest)497 TEST_P(BoolAccessorHidlTest, MicMuteTest) {
498     doc::test("Check that the mic can be muted and unmuted");
499     testAccessors<OPTIONAL>("mic mute", Initial{false}, {true}, &IDevice::setMicMute,
500                             &IDevice::getMicMute);
501     // TODO: check that the mic is really muted (all sample are 0)
502 }
503 
TEST_P(BoolAccessorHidlTest,MasterMuteTest)504 TEST_P(BoolAccessorHidlTest, MasterMuteTest) {
505     doc::test("If master mute is supported, try to mute and unmute the master output");
506     testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
507                             &IDevice::getMasterMute);
508     // TODO: check that the master volume is really muted
509 }
510 
511 INSTANTIATE_TEST_CASE_P(BoolAccessorHidl, BoolAccessorHidlTest,
512                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
513 INSTANTIATE_TEST_CASE_P(BoolAccessorPrimaryHidl, BoolAccessorPrimaryHidlTest,
514                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
515                         &DeviceParameterToString);
516 
517 using FloatAccessorHidlTest = AccessorHidlTest<float>;
TEST_P(FloatAccessorHidlTest,MasterVolumeTest)518 TEST_P(FloatAccessorHidlTest, MasterVolumeTest) {
519     doc::test("Test the master volume if supported");
520     testAccessors<OPTIONAL>(
521         "master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
522         {-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()});
523     // TODO: check that the master volume is really changed
524 }
525 
526 INSTANTIATE_TEST_CASE_P(FloatAccessorHidl, FloatAccessorHidlTest,
527                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
528 
529 //////////////////////////////////////////////////////////////////////////////
530 //////////////////////////////// AudioPatches ////////////////////////////////
531 //////////////////////////////////////////////////////////////////////////////
532 
533 class AudioPatchHidlTest : public AudioHidlDeviceTest {
534   public:
SetUp()535     void SetUp() override {
536         ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
537         if (!areAudioPatchesSupported()) {
538             GTEST_SKIP() << "Audio patches are not supported";
539         }
540     }
541 };
542 
TEST_P(AudioPatchHidlTest,AudioPatches)543 TEST_P(AudioPatchHidlTest, AudioPatches) {
544     doc::test("Test if audio patches are supported");
545     // TODO: test audio patches
546 }
547 
548 INSTANTIATE_TEST_CASE_P(AudioPatchHidl, AudioPatchHidlTest,
549                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
550 
551 // Nesting a tuple in another tuple allows to use GTest Combine function to generate
552 // all combinations of devices and configs.
553 enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
554 enum { INDEX_INPUT, INDEX_OUTPUT };
555 using DeviceConfigParameter =
556         std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
557 
558 #if MAJOR_VERSION >= 6
559 const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
560 const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
561 #endif
562 
563 #if MAJOR_VERSION >= 4
SanitizeStringForGTestName(const string & s)564 static string SanitizeStringForGTestName(const string& s) {
565     string result = s;
566     for (size_t i = 0; i < result.size(); i++) {
567         // gtest test names must only contain alphanumeric characters
568         if (!std::isalnum(result[i])) result[i] = '_';
569     }
570     return result;
571 }
572 #endif
573 
574 /** Generate a test name based on an audio config.
575  *
576  * As the only parameter changing are channel mask and sample rate,
577  * only print those ones in the test name.
578  */
DeviceConfigParameterToString(const testing::TestParamInfo<DeviceConfigParameter> & info)579 static string DeviceConfigParameterToString(
580         const testing::TestParamInfo<DeviceConfigParameter>& info) {
581     const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
582     const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
583             std::get<PARAM_DEVICE>(info.param), info.index});
584     return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" +
585            to_string(config.sampleRateHz) + "_" +
586            // "MONO" is more clear than "FRONT_LEFT"
587            ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
588              config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
589                     ? "MONO"
590 #if MAJOR_VERSION == 2
591                     : ::testing::PrintToString(config.channelMask)
592 #elif MAJOR_VERSION >= 4
593                     // In V4 and above the channel mask is a bitfield.
594                     // Printing its value using HIDL's toString for a bitfield emits a lot of extra
595                     // text due to overlapping constant values. Instead, we print the bitfield value
596                     // as if it was a single value + its hex representation
597                     : SanitizeStringForGTestName(
598                               ::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" +
599                               toHexString(config.channelMask))
600 #endif
601                     ) +
602            "_" +
603 #if MAJOR_VERSION == 2
604            std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
605                       std::get<PARAM_FLAGS>(info.param));
606 #elif MAJOR_VERSION >= 4
607            SanitizeStringForGTestName(std::visit(
608                    [](auto&& arg) -> std::string {
609                        using T = std::decay_t<decltype(arg)>;
610                        // Need to use FQN of toString to avoid confusing the compiler
611                        return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
612                                hidl_bitfield<T>(arg));
613                    },
614                    std::get<PARAM_FLAGS>(info.param)));
615 #endif
616 }
617 
618 class AudioHidlTestWithDeviceConfigParameter
619     : public HidlTest,
620       public ::testing::WithParamInterface<DeviceConfigParameter> {
621   protected:
SetUp()622     void SetUp() override {
623         ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
624         ASSERT_TRUE(getDevicesFactory() != nullptr);
625         ASSERT_TRUE(getDevice() != nullptr);
626     }
getFactoryName()627     const std::string& getFactoryName() const override {
628         return std::get<PARAM_FACTORY_NAME>(std::get<PARAM_DEVICE>(GetParam()));
629     }
getDeviceName()630     const std::string& getDeviceName() const override {
631         return std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(GetParam()));
632     }
getConfig()633     const AudioConfig& getConfig() const { return std::get<PARAM_CONFIG>(GetParam()); }
634 #if MAJOR_VERSION == 2
getInputFlags()635     AudioInputFlag getInputFlags() const {
636         return std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam()));
637     }
getOutputFlags()638     AudioOutputFlag getOutputFlags() const {
639         return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
640     }
641 #elif MAJOR_VERSION >= 4
getInputFlags()642     hidl_bitfield<AudioInputFlag> getInputFlags() const {
643         return hidl_bitfield<AudioInputFlag>(
644                 std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
645     }
getOutputFlags()646     hidl_bitfield<AudioOutputFlag> getOutputFlags() const {
647         return hidl_bitfield<AudioOutputFlag>(
648                 std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
649     }
650 #endif
651 };
652 
653 #include "ConfigHelper.h"
654 
655 //////////////////////////////////////////////////////////////////////////////
656 ///////////////////////////// getInputBufferSize /////////////////////////////
657 //////////////////////////////////////////////////////////////////////////////
658 
659 // FIXME: execute input test only if platform declares
660 // android.hardware.microphone
661 //        how to get this value ? is it a property ???
662 
663 class AudioCaptureConfigTest : public AudioHidlTestWithDeviceConfigParameter {
664   protected:
inputBufferSizeTest(const AudioConfig & audioConfig,bool supportRequired)665     void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
666         uint64_t bufferSize;
667         ASSERT_OK(getDevice()->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
668 
669         switch (res) {
670             case Result::INVALID_ARGUMENTS:
671                 EXPECT_FALSE(supportRequired);
672                 break;
673             case Result::OK:
674                 // Check that the buffer is of a sane size
675                 // For now only that it is > 0
676                 EXPECT_GT(bufferSize, uint64_t(0));
677                 break;
678             default:
679                 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
680         }
681     }
682 };
683 
684 // Test that the required capture config and those declared in the policy are
685 // indeed supported
686 class RequiredInputBufferSizeTest : public AudioCaptureConfigTest {};
TEST_P(RequiredInputBufferSizeTest,RequiredInputBufferSizeTest)687 TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
688     doc::test(
689         "Input buffer size must be retrievable for a format with required "
690         "support.");
691     inputBufferSizeTest(getConfig(), true);
692 }
693 
694 // Test that the recommended capture config are supported or lead to a
695 // INVALID_ARGUMENTS return
696 class OptionalInputBufferSizeTest : public AudioCaptureConfigTest {};
TEST_P(OptionalInputBufferSizeTest,OptionalInputBufferSizeTest)697 TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
698     doc::test(
699             "Input buffer size should be retrievable for a format with recommended "
700             "support.");
701     inputBufferSizeTest(getConfig(), false);
702 }
703 
704 #if MAJOR_VERSION <= 5
705 // For V2..5 test the primary device according to CDD requirements.
706 INSTANTIATE_TEST_CASE_P(
707         RequiredInputBufferSize, RequiredInputBufferSizeTest,
708         ::testing::Combine(
709                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
710                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
711                 ::testing::Values(AudioInputFlag::NONE)),
712         &DeviceConfigParameterToString);
713 INSTANTIATE_TEST_CASE_P(
714         RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
715         ::testing::Combine(
716                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
717                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
718                 ::testing::Values(AudioInputFlag::NONE)),
719         &DeviceConfigParameterToString);
720 #elif MAJOR_VERSION >= 6
721 INSTANTIATE_TEST_CASE_P(SupportedInputBufferSize, RequiredInputBufferSizeTest,
722                         ::testing::ValuesIn(getInputDeviceConfigParameters()),
723                         &DeviceConfigParameterToString);
724 #endif
725 
726 //////////////////////////////////////////////////////////////////////////////
727 /////////////////////////////// setScreenState ///////////////////////////////
728 //////////////////////////////////////////////////////////////////////////////
729 
TEST_P(AudioHidlDeviceTest,setScreenState)730 TEST_P(AudioHidlDeviceTest, setScreenState) {
731     doc::test("Check that the hal can receive the screen state");
732     for (bool turnedOn : {false, true, true, false, false}) {
733         ASSERT_RESULT(okOrNotSupported, getDevice()->setScreenState(turnedOn));
734     }
735 }
736 
737 //////////////////////////////////////////////////////////////////////////////
738 //////////////////////////// {get,set}Parameters /////////////////////////////
739 //////////////////////////////////////////////////////////////////////////////
740 
TEST_P(AudioHidlDeviceTest,getParameters)741 TEST_P(AudioHidlDeviceTest, getParameters) {
742     doc::test("Check that the hal can set and get parameters");
743     hidl_vec<ParameterValue> context;
744     hidl_vec<hidl_string> keys;
745     hidl_vec<ParameterValue> values;
746     ASSERT_OK(Parameters::get(getDevice(), keys, returnIn(res, values)));
747     ASSERT_RESULT(okOrNotSupported, res);
748     ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
749     values.resize(0);
750     ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
751 }
752 
753 //////////////////////////////////////////////////////////////////////////////
754 //////////////////////////////// debugDebug //////////////////////////////////
755 //////////////////////////////////////////////////////////////////////////////
756 
757 template <class DebugDump>
testDebugDump(DebugDump debugDump)758 static void testDebugDump(DebugDump debugDump) {
759     // File descriptors to our pipe. fds[0] corresponds to the read end and
760     // fds[1] to the write end.
761     int fds[2];
762     ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
763 
764     // Make sure that the pipe is at least 1 MB in size. The test process runs
765     // in su domain, so it should be safe to make this call.
766     fcntl(fds[0], F_SETPIPE_SZ, 1 << 20);
767 
768     // Wrap the temporary file file descriptor in a native handle
769     auto* nativeHandle = native_handle_create(1, 0);
770     ASSERT_NE(nullptr, nativeHandle);
771     nativeHandle->data[0] = fds[1];
772 
773     // Wrap this native handle in a hidl handle
774     hidl_handle handle;
775     handle.setTo(nativeHandle, false /*take ownership*/);
776 
777     ASSERT_OK(debugDump(handle));
778 
779     // Check that at least one bit was written by the hal
780     // TODO: debugDump does not return a Result.
781     // This mean that the hal can not report that it not implementing the
782     // function.
783     char buff;
784     if (read(fds[0], &buff, 1) != 1) {
785         doc::note("debugDump does not seem implemented");
786     }
787     EXPECT_EQ(0, close(fds[0])) << errno;
788     EXPECT_EQ(0, close(fds[1])) << errno;
789 }
790 
TEST_P(AudioHidlDeviceTest,DebugDump)791 TEST_P(AudioHidlDeviceTest, DebugDump) {
792     doc::test("Check that the hal can dump its state without error");
793     testDebugDump([this](const auto& handle) { return dump(getDevice(), handle); });
794 }
795 
TEST_P(AudioHidlDeviceTest,DebugDumpInvalidArguments)796 TEST_P(AudioHidlDeviceTest, DebugDumpInvalidArguments) {
797     doc::test("Check that the hal dump doesn't crash on invalid arguments");
798     ASSERT_OK(dump(getDevice(), hidl_handle()));
799 }
800 
801 //////////////////////////////////////////////////////////////////////////////
802 ////////////////////////// open{Output,Input}Stream //////////////////////////
803 //////////////////////////////////////////////////////////////////////////////
804 
805 // This class is also used by some device tests.
806 template <class Stream>
807 class StreamHelper {
808   public:
809     // StreamHelper doesn't own the stream, this is for simpler stream lifetime management.
StreamHelper(sp<Stream> & stream)810     explicit StreamHelper(sp<Stream>& stream) : mStream(stream) {}
811     template <class Open>
open(Open openStream,const AudioConfig & config,Result * res,AudioConfig * suggestedConfigPtr)812     void open(Open openStream, const AudioConfig& config, Result* res,
813               AudioConfig* suggestedConfigPtr) {
814         // FIXME: Open a stream without an IOHandle
815         //        This is not required to be accepted by hal implementations
816         AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
817         AudioConfig suggestedConfig{};
818         bool retryWithSuggestedConfig = true;
819         if (suggestedConfigPtr == nullptr) {
820             suggestedConfigPtr = &suggestedConfig;
821             retryWithSuggestedConfig = false;
822         }
823         ASSERT_OK(openStream(ioHandle, config, returnIn(*res, mStream, *suggestedConfigPtr)));
824         switch (*res) {
825             case Result::OK:
826                 ASSERT_TRUE(mStream != nullptr);
827                 *suggestedConfigPtr = config;
828                 break;
829             case Result::INVALID_ARGUMENTS:
830                 ASSERT_TRUE(mStream == nullptr);
831                 if (retryWithSuggestedConfig) {
832                     AudioConfig suggestedConfigRetry;
833                     ASSERT_OK(openStream(ioHandle, *suggestedConfigPtr,
834                                          returnIn(*res, mStream, suggestedConfigRetry)));
835                     ASSERT_OK(*res);
836                     ASSERT_TRUE(mStream != nullptr);
837                 }
838                 break;
839             default:
840                 FAIL() << "Invalid return status: " << ::testing::PrintToString(*res);
841         }
842     }
close(bool clear,Result * res)843     void close(bool clear, Result* res) {
844         auto ret = mStream->close();
845         EXPECT_TRUE(ret.isOk());
846         *res = ret;
847         if (clear) {
848             mStream.clear();
849 #if MAJOR_VERSION <= 5
850             // FIXME: there is no way to know when the remote IStream is being destroyed
851             //        Binder does not support testing if an object is alive, thus
852             //        wait for 100ms to let the binder destruction propagates and
853             //        the remote device has the time to be destroyed.
854             //        flushCommand makes sure all local command are sent, thus should reduce
855             //        the latency between local and remote destruction.
856             IPCThreadState::self()->flushCommands();
857             usleep(100 * 1000);
858 #endif
859         }
860     }
861 
862   private:
863     sp<Stream>& mStream;
864 };
865 
866 template <class Stream>
867 class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
868   public:
869     // public access to avoid annoyances when using this method in template classes
870     // derived from test classes
getStream()871     sp<Stream> getStream() const { return stream; }
872 
873   protected:
OpenStreamTest()874     OpenStreamTest() : AudioHidlTestWithDeviceConfigParameter(), helper(stream) {}
875     template <class Open>
testOpen(Open openStream,const AudioConfig & config)876     void testOpen(Open openStream, const AudioConfig& config) {
877         // TODO: only allow failure for RecommendedPlaybackAudioConfig
878         ASSERT_NO_FATAL_FAILURE(helper.open(openStream, config, &res, &audioConfig));
879         open = true;
880     }
881 
882     Result closeStream(bool clear = true) {
883         open = false;
884         helper.close(clear, &res);
885         return res;
886     }
887 
888   private:
TearDown()889     void TearDown() override {
890         if (open) {
891             ASSERT_OK(closeStream());
892         }
893         AudioHidlTestWithDeviceConfigParameter::TearDown();
894     }
895 
896    protected:
897     AudioConfig audioConfig;
898     DeviceAddress address = {};
899     sp<Stream> stream;
900     StreamHelper<Stream> helper;
901     bool open = false;
902 };
903 
904 ////////////////////////////// openOutputStream //////////////////////////////
905 
906 class OutputStreamTest : public OpenStreamTest<IStreamOut> {
SetUp()907     void SetUp() override {
908         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
909         address.device = AudioDevice::OUT_DEFAULT;
910         const AudioConfig& config = getConfig();
911         auto flags = getOutputFlags();
912         testOpen(
913                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
914 #if MAJOR_VERSION == 2
915                     return getDevice()->openOutputStream(handle, address, config, flags, cb);
916 #elif MAJOR_VERSION >= 4
917                     return getDevice()->openOutputStream(handle, address, config, flags,
918                                                          initMetadata, cb);
919 #endif
920                 },
921                 config);
922     }
923 #if MAJOR_VERSION >= 4
924 
925    protected:
926     const SourceMetadata initMetadata = {
927         { { AudioUsage::MEDIA,
928             AudioContentType::MUSIC,
929             1 /* gain */ } }};
930 #endif
931 };
TEST_P(OutputStreamTest,OpenOutputStreamTest)932 TEST_P(OutputStreamTest, OpenOutputStreamTest) {
933     doc::test(
934         "Check that output streams can be open with the required and "
935         "recommended config");
936     // Open done in SetUp
937 }
938 
939 #if MAJOR_VERSION <= 5
940 // For V2..5 test the primary device according to CDD requirements.
941 INSTANTIATE_TEST_CASE_P(
942         RequiredOutputStreamConfigSupport, OutputStreamTest,
943         ::testing::Combine(
944                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
945                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportPlaybackAudioConfig()),
946                 ::testing::Values(AudioOutputFlag::NONE)),
947         &DeviceConfigParameterToString);
948 INSTANTIATE_TEST_CASE_P(
949         RecommendedOutputStreamConfigSupport, OutputStreamTest,
950         ::testing::Combine(
951                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
952                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportPlaybackAudioConfig()),
953                 ::testing::Values(AudioOutputFlag::NONE)),
954         &DeviceConfigParameterToString);
955 #elif MAJOR_VERSION >= 6
956 // For V6 and above test according to the audio policy manager configuration.
957 // This is more correct as CDD is written from the apps perspective.
958 // Audio system provides necessary format conversions for missing configurations.
959 INSTANTIATE_TEST_CASE_P(DeclaredOutputStreamConfigSupport, OutputStreamTest,
960                         ::testing::ValuesIn(getOutputDeviceConfigParameters()),
961                         &DeviceConfigParameterToString);
962 #endif
963 
964 ////////////////////////////// openInputStream //////////////////////////////
965 
966 class InputStreamTest : public OpenStreamTest<IStreamIn> {
SetUp()967     void SetUp() override {
968         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
969         address.device = AudioDevice::IN_DEFAULT;
970         const AudioConfig& config = getConfig();
971         auto flags = getInputFlags();
972         testOpen(
973                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
974                     return getDevice()->openInputStream(handle, address, config, flags,
975                                                         initMetadata, cb);
976                 },
977                 config);
978     }
979 
980    protected:
981 #if MAJOR_VERSION == 2
982     const AudioSource initMetadata = AudioSource::DEFAULT;
983 #elif MAJOR_VERSION >= 4
984     const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}};
985 #endif
986 };
987 
TEST_P(InputStreamTest,OpenInputStreamTest)988 TEST_P(InputStreamTest, OpenInputStreamTest) {
989     doc::test(
990         "Check that input streams can be open with the required and "
991         "recommended config");
992     // Open done in setup
993 }
994 #if MAJOR_VERSION <= 5
995 // For V2..5 test the primary device according to CDD requirements.
996 INSTANTIATE_TEST_CASE_P(
997         RequiredInputStreamConfigSupport, InputStreamTest,
998         ::testing::Combine(
999                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1000                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
1001                 ::testing::Values(AudioInputFlag::NONE)),
1002         &DeviceConfigParameterToString);
1003 INSTANTIATE_TEST_CASE_P(
1004         RecommendedInputStreamConfigSupport, InputStreamTest,
1005         ::testing::Combine(
1006                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1007                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
1008                 ::testing::Values(AudioInputFlag::NONE)),
1009         &DeviceConfigParameterToString);
1010 #elif MAJOR_VERSION >= 6
1011 // For V6 and above test according to the audio policy manager configuration.
1012 // This is more correct as CDD is written from the apps perspective.
1013 // Audio system provides necessary format conversions for missing configurations.
1014 INSTANTIATE_TEST_CASE_P(DeclaredInputStreamConfigSupport, InputStreamTest,
1015                         ::testing::ValuesIn(getInputDeviceConfigParameters()),
1016                         &DeviceConfigParameterToString);
1017 #endif
1018 
1019 //////////////////////////////////////////////////////////////////////////////
1020 ////////////////////////////// IStream getters ///////////////////////////////
1021 //////////////////////////////////////////////////////////////////////////////
1022 
1023 /* Could not find a way to write a test for two parametrized class fixure
1024  * thus use this macro do duplicate tests for Input and Output stream */
1025 #define TEST_IO_STREAM(test_name, documentation, code) \
1026     TEST_P(InputStreamTest, test_name) {               \
1027         doc::test(documentation);                      \
1028         code;                                          \
1029     }                                                  \
1030     TEST_P(OutputStreamTest, test_name) {              \
1031         doc::test(documentation);                      \
1032         code;                                          \
1033     }
1034 
1035 TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
1036                ASSERT_TRUE(stream->getFrameCount().isOk()))
1037 
1038 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
1039                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
1040 
1041 TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
1042                ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
1043 
1044 TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
1045                ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
1046 
1047 // TODO: for now only check that the framesize is not incoherent
1048 TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
1049                ASSERT_GT(extract(stream->getFrameSize()), 0U))
1050 
1051 TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
1052                ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
1053 
1054 template <class Property, class CapabilityGetter>
1055 static void testCapabilityGetter(const string& name, IStream* stream,
1056                                  CapabilityGetter capabilityGetter,
1057                                  Return<Property> (IStream::*getter)(),
1058                                  Return<Result> (IStream::*setter)(Property),
1059                                  bool currentMustBeSupported = true) {
1060     hidl_vec<Property> capabilities;
1061     auto ret = capabilityGetter(stream, capabilities);
1062     ASSERT_RESULT(okOrNotSupported, ret);
1063     bool notSupported = ret == Result::NOT_SUPPORTED;
1064     if (notSupported) {
1065         doc::partialTest(name + " is not supported");
1066         return;
1067     };
1068 
1069     if (currentMustBeSupported) {
1070         ASSERT_NE(0U, capabilities.size()) << name << " must not return an empty list";
1071         Property currentValue = extract((stream->*getter)());
1072         EXPECT_TRUE(std::find(capabilities.begin(), capabilities.end(), currentValue) !=
1073                     capabilities.end())
1074             << "value returned by " << name << "() = " << testing::PrintToString(currentValue)
1075             << " is not in the list of the supported ones " << toString(capabilities);
1076     }
1077 
1078     // Check that all declared supported values are indeed supported
1079     for (auto capability : capabilities) {
1080         auto ret = (stream->*setter)(capability);
1081         ASSERT_TRUE(ret.isOk());
1082         if (ret == Result::NOT_SUPPORTED) {
1083             doc::partialTest("Setter is not supported");
1084             return;
1085         }
1086         ASSERT_OK(ret);
1087         ASSERT_EQ(capability, extract((stream->*getter)()));
1088     }
1089 }
1090 
1091 TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
1092                testCapabilityGetter("getSupportedSampleRate", stream.get(),
1093                                     &GetSupported::sampleRates, &IStream::getSampleRate,
1094                                     &IStream::setSampleRate,
1095                                     // getSupportedSampleRate returns the native sampling rates,
1096                                     // (the sampling rates that can be played without resampling)
1097                                     // but other sampling rates can be supported by the HAL.
1098                                     false))
1099 
1100 TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
1101                testCapabilityGetter("getSupportedChannelMask", stream.get(),
1102                                     &GetSupported::channelMasks, &IStream::getChannelMask,
1103                                     &IStream::setChannelMask))
1104 
1105 TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
1106                testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
1107                                     &IStream::getFormat, &IStream::setFormat))
1108 
testGetAudioProperties(IStream * stream,AudioConfig expectedConfig)1109 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
1110     uint32_t sampleRateHz;
1111     auto mask = mkEnumBitfield<AudioChannelMask>({});
1112     AudioFormat format;
1113 
1114     stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
1115 
1116     // FIXME: the qcom hal it does not currently negotiate the sampleRate &
1117     // channel mask
1118     EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
1119     EXPECT_EQ(expectedConfig.channelMask, mask);
1120     EXPECT_EQ(expectedConfig.format, format);
1121 }
1122 
1123 TEST_IO_STREAM(GetAudioProperties,
1124                "Check that the stream audio properties == the ones it was opened with",
1125                testGetAudioProperties(stream.get(), audioConfig))
1126 
1127 TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
1128                ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
1129 
checkGetNoParameter(IStream * stream,hidl_vec<hidl_string> keys,initializer_list<Result> expectedResults)1130 static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
1131                                 initializer_list<Result> expectedResults) {
1132     hidl_vec<ParameterValue> parameters;
1133     Result res;
1134     ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
1135     ASSERT_RESULT(expectedResults, res);
1136     if (res == Result::OK) {
1137         for (auto& parameter : parameters) {
1138             ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
1139         }
1140     }
1141 }
1142 
1143 /* Get/Set parameter is intended to be an opaque channel between vendors app and
1144  * their HALs.
1145  * Thus can not be meaningfully tested.
1146  */
1147 TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
1148                checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
1149 
1150 TEST_IO_STREAM(getNonExistingParameter, "Retrieve the values of an non existing parameter",
1151                checkGetNoParameter(stream.get(), {"Non existing key"} /* keys */,
1152                                    {Result::NOT_SUPPORTED}))
1153 
1154 TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
1155                ASSERT_RESULT(Result::OK, Parameters::set(stream, {})))
1156 
1157 TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
1158                // Unfortunately, the set_parameter legacy interface did not return any
1159                // error code when a key is not supported.
1160                // To allow implementation to just wrapped the legacy one, consider OK as a
1161                // valid result for setting a non existing parameter.
1162                ASSERT_RESULT(okOrNotSupportedOrInvalidArgs,
1163                              Parameters::set(stream, {{"non existing key", "0"}})))
1164 
1165 TEST_IO_STREAM(DebugDump, "Check that a stream can dump its state without error",
1166                testDebugDump([this](const auto& handle) { return dump(stream, handle); }))
1167 
1168 TEST_IO_STREAM(DebugDumpInvalidArguments,
1169                "Check that the stream dump doesn't crash on invalid arguments",
1170                ASSERT_OK(dump(stream, hidl_handle())))
1171 
1172 //////////////////////////////////////////////////////////////////////////////
1173 ////////////////////////////// addRemoveEffect ///////////////////////////////
1174 //////////////////////////////////////////////////////////////////////////////
1175 
1176 TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
1177                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
1178 TEST_IO_STREAM(RemoveNonExistingEffect, "Removing a non existing effect should fail",
1179                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->removeEffect(666)))
1180 
1181 // TODO: positive tests
1182 
1183 //////////////////////////////////////////////////////////////////////////////
1184 /////////////////////////////// Control ////////////////////////////////
1185 //////////////////////////////////////////////////////////////////////////////
1186 
1187 TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
1188                ASSERT_OK(stream->standby()))  // can not fail
1189 
1190 TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
1191                ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
1192 
1193 TEST_IO_STREAM(stopNoMmap, "Stopping a mmaped stream before mapping it should fail",
1194                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
1195 
1196 TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping it should fail",
1197                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
1198 
1199 TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
1200 // clang-format off
1201 TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
1202         ASSERT_OK(closeStream(false /*clear*/));
1203         ASSERT_EQ(Result::INVALID_STATE, closeStream()))
1204 // clang-format on
1205 
testMmapBufferOfInvalidSize(IStream * stream)1206 static void testMmapBufferOfInvalidSize(IStream* stream) {
1207     for (int32_t value : {-1, 0, std::numeric_limits<int32_t>::max()}) {
1208         MmapBufferInfo info;
1209         Result res;
1210         EXPECT_OK(stream->createMmapBuffer(value, returnIn(res, info)));
1211         EXPECT_RESULT(invalidArgsOrNotSupported, res) << "value=" << value;
1212     }
1213 }
1214 
1215 TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer of invalid size must fail",
1216                testMmapBufferOfInvalidSize(stream.get()))
1217 
testGetMmapPositionOfNonMmapedStream(IStream * stream)1218 static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
1219     Result res;
1220     MmapPosition position;
1221     ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
1222     ASSERT_RESULT(invalidArgsOrNotSupported, res);
1223 }
1224 
1225 TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream,
1226                "Retrieving the mmap position of a non mmaped stream should fail",
1227                testGetMmapPositionOfNonMmapedStream(stream.get()))
1228 
1229 //////////////////////////////////////////////////////////////////////////////
1230 ///////////////////////////////// StreamIn ///////////////////////////////////
1231 //////////////////////////////////////////////////////////////////////////////
1232 
TEST_P(InputStreamTest,GetAudioSource)1233 TEST_P(InputStreamTest, GetAudioSource) {
1234     doc::test("Retrieving the audio source of an input stream should always succeed");
1235     AudioSource source;
1236     ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
1237     if (res == Result::NOT_SUPPORTED) {
1238         doc::partialTest("getAudioSource is not supported");
1239         return;
1240     }
1241     ASSERT_OK(res);
1242     ASSERT_EQ(AudioSource::DEFAULT, source);
1243 }
1244 
testUnitaryGain(std::function<Return<Result> (float)> setGain)1245 static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
1246     for (float value : (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(), 2.0,
1247                                  INFINITY, NAN}) {
1248         EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value=" << value;
1249     }
1250     // Do not consider -0.0 as an invalid value as it is == with 0.0
1251     for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
1252         EXPECT_OK(setGain(value)) << "value=" << value;
1253     }
1254 }
1255 
testOptionalUnitaryGain(std::function<Return<Result> (float)> setGain,string debugName)1256 static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain,
1257                                     string debugName) {
1258     auto result = setGain(1);
1259     ASSERT_IS_OK(result);
1260     if (result == Result::NOT_SUPPORTED) {
1261         doc::partialTest(debugName + " is not supported");
1262         return;
1263     }
1264     testUnitaryGain(setGain);
1265 }
1266 
TEST_P(InputStreamTest,SetGain)1267 TEST_P(InputStreamTest, SetGain) {
1268     doc::test("The gain of an input stream should only be set between [0,1]");
1269     testOptionalUnitaryGain([this](float volume) { return stream->setGain(volume); },
1270                             "InputStream::setGain");
1271 }
1272 
testPrepareForReading(IStreamIn * stream,uint32_t frameSize,uint32_t framesCount)1273 static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) {
1274     Result res;
1275     // Ignore output parameters as the call should fail
1276     ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
1277                                         [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1278     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1279 }
1280 
TEST_P(InputStreamTest,PrepareForReadingWithZeroBuffer)1281 TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
1282     doc::test("Preparing a stream for reading with a 0 sized buffer should fail");
1283     testPrepareForReading(stream.get(), 0, 0);
1284 }
1285 
TEST_P(InputStreamTest,PrepareForReadingWithHugeBuffer)1286 TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
1287     doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail");
1288     testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max());
1289 }
1290 
TEST_P(InputStreamTest,PrepareForReadingCheckOverflow)1291 TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
1292     doc::test(
1293         "Preparing a stream for reading with a overflowing sized buffer should "
1294         "fail");
1295     auto uintMax = std::numeric_limits<uint32_t>::max();
1296     testPrepareForReading(stream.get(), uintMax, uintMax);
1297 }
1298 
TEST_P(InputStreamTest,GetInputFramesLost)1299 TEST_P(InputStreamTest, GetInputFramesLost) {
1300     doc::test("The number of frames lost on a never started stream should be 0");
1301     auto ret = stream->getInputFramesLost();
1302     ASSERT_IS_OK(ret);
1303     uint32_t framesLost{ret};
1304     ASSERT_EQ(0U, framesLost);
1305 }
1306 
TEST_P(InputStreamTest,getCapturePosition)1307 TEST_P(InputStreamTest, getCapturePosition) {
1308     doc::test(
1309         "The capture position of a non prepared stream should not be "
1310         "retrievable or 0");
1311     uint64_t frames;
1312     uint64_t time;
1313     ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
1314     ASSERT_RESULT(okOrInvalidStateOrNotSupported, res);
1315     if (res == Result::OK) {
1316         ASSERT_EQ(0U, frames);
1317         ASSERT_LE(0U, time);
1318     }
1319 }
1320 
1321 //////////////////////////////////////////////////////////////////////////////
1322 ///////////////////////////////// StreamOut //////////////////////////////////
1323 //////////////////////////////////////////////////////////////////////////////
1324 
TEST_P(OutputStreamTest,getLatency)1325 TEST_P(OutputStreamTest, getLatency) {
1326     doc::test("Make sure latency is over 0");
1327     auto result = stream->getLatency();
1328     ASSERT_IS_OK(result);
1329     ASSERT_GT(result, 0U);
1330 }
1331 
TEST_P(OutputStreamTest,setVolume)1332 TEST_P(OutputStreamTest, setVolume) {
1333     doc::test("Try to set the output volume");
1334     testOptionalUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); },
1335                             "setVolume");
1336 }
1337 
testPrepareForWriting(IStreamOut * stream,uint32_t frameSize,uint32_t framesCount)1338 static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) {
1339     Result res;
1340     // Ignore output parameters as the call should fail
1341     ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
1342                                         [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1343     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1344 }
1345 
TEST_P(OutputStreamTest,PrepareForWriteWithZeroBuffer)1346 TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
1347     doc::test("Preparing a stream for writing with a 0 sized buffer should fail");
1348     testPrepareForWriting(stream.get(), 0, 0);
1349 }
1350 
TEST_P(OutputStreamTest,PrepareForWriteWithHugeBuffer)1351 TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
1352     doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
1353     testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
1354 }
1355 
TEST_P(OutputStreamTest,PrepareForWritingCheckOverflow)1356 TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
1357     doc::test(
1358         "Preparing a stream for writing with a overflowing sized buffer should "
1359         "fail");
1360     auto uintMax = std::numeric_limits<uint32_t>::max();
1361     testPrepareForWriting(stream.get(), uintMax, uintMax);
1362 }
1363 
1364 struct Capability {
CapabilityCapability1365     Capability(IStreamOut* stream) {
1366         EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
1367         drain = extract(stream->supportsDrain());
1368     }
1369     bool pause = false;
1370     bool resume = false;
1371     bool drain = false;
1372 };
1373 
TEST_P(OutputStreamTest,SupportsPauseAndResumeAndDrain)1374 TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
1375     doc::test("Implementation must expose pause, resume and drain capabilities");
1376     Capability(stream.get());
1377 }
1378 
TEST_P(OutputStreamTest,GetRenderPosition)1379 TEST_P(OutputStreamTest, GetRenderPosition) {
1380     doc::test("A new stream render position should be 0 or INVALID_STATE");
1381     uint32_t dspFrames;
1382     ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
1383     if (res == Result::NOT_SUPPORTED) {
1384         doc::partialTest("getRenderPosition is not supported");
1385         return;
1386     }
1387     expectValueOrFailure(res, 0U, dspFrames, Result::INVALID_STATE);
1388 }
1389 
TEST_P(OutputStreamTest,GetNextWriteTimestamp)1390 TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
1391     doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
1392     uint64_t timestampUs;
1393     ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
1394     if (res == Result::NOT_SUPPORTED) {
1395         doc::partialTest("getNextWriteTimestamp is not supported");
1396         return;
1397     }
1398     expectValueOrFailure(res, uint64_t{0}, timestampUs, Result::INVALID_STATE);
1399 }
1400 
1401 /** Stub implementation of out stream callback. */
1402 class MockOutCallbacks : public IStreamOutCallback {
onWriteReady()1403     Return<void> onWriteReady() override { return {}; }
onDrainReady()1404     Return<void> onDrainReady() override { return {}; }
onError()1405     Return<void> onError() override { return {}; }
1406 };
1407 
isAsyncModeSupported(IStreamOut * stream)1408 static bool isAsyncModeSupported(IStreamOut* stream) {
1409     auto res = stream->setCallback(new MockOutCallbacks);
1410     stream->clearCallback();  // try to restore the no callback state, ignore
1411                               // any error
1412     EXPECT_RESULT(okOrNotSupported, res);
1413     return res.isOk() ? res == Result::OK : false;
1414 }
1415 
TEST_P(OutputStreamTest,SetCallback)1416 TEST_P(OutputStreamTest, SetCallback) {
1417     doc::test(
1418         "If supported, registering callback for async operation should never "
1419         "fail");
1420     if (!isAsyncModeSupported(stream.get())) {
1421         doc::partialTest("The stream does not support async operations");
1422         return;
1423     }
1424     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1425     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1426 }
1427 
TEST_P(OutputStreamTest,clearCallback)1428 TEST_P(OutputStreamTest, clearCallback) {
1429     doc::test(
1430         "If supported, clearing a callback to go back to sync operation should "
1431         "not fail");
1432     if (!isAsyncModeSupported(stream.get())) {
1433         doc::partialTest("The stream does not support async operations");
1434         return;
1435     }
1436     // TODO: Clarify if clearing a non existing callback should fail
1437     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1438     ASSERT_OK(stream->clearCallback());
1439 }
1440 
TEST_P(OutputStreamTest,Resume)1441 TEST_P(OutputStreamTest, Resume) {
1442     doc::test(
1443         "If supported, a stream should fail to resume if not previously "
1444         "paused");
1445     if (!Capability(stream.get()).resume) {
1446         doc::partialTest("The output stream does not support resume");
1447         return;
1448     }
1449     ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1450 }
1451 
TEST_P(OutputStreamTest,Pause)1452 TEST_P(OutputStreamTest, Pause) {
1453     doc::test(
1454         "If supported, a stream should fail to pause if not previously "
1455         "started");
1456     if (!Capability(stream.get()).pause) {
1457         doc::partialTest("The output stream does not support pause");
1458         return;
1459     }
1460     ASSERT_RESULT(Result::INVALID_STATE, stream->pause());
1461 }
1462 
testDrain(IStreamOut * stream,AudioDrain type)1463 static void testDrain(IStreamOut* stream, AudioDrain type) {
1464     if (!Capability(stream).drain) {
1465         doc::partialTest("The output stream does not support drain");
1466         return;
1467     }
1468     ASSERT_RESULT(Result::OK, stream->drain(type));
1469 }
1470 
TEST_P(OutputStreamTest,DrainAll)1471 TEST_P(OutputStreamTest, DrainAll) {
1472     doc::test("If supported, a stream should always succeed to drain");
1473     testDrain(stream.get(), AudioDrain::ALL);
1474 }
1475 
TEST_P(OutputStreamTest,DrainEarlyNotify)1476 TEST_P(OutputStreamTest, DrainEarlyNotify) {
1477     doc::test("If supported, a stream should always succeed to drain");
1478     testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
1479 }
1480 
TEST_P(OutputStreamTest,FlushStop)1481 TEST_P(OutputStreamTest, FlushStop) {
1482     doc::test("If supported, a stream should always succeed to flush");
1483     auto ret = stream->flush();
1484     ASSERT_IS_OK(ret);
1485     if (ret == Result::NOT_SUPPORTED) {
1486         doc::partialTest("Flush is not supported");
1487         return;
1488     }
1489     ASSERT_OK(ret);
1490 }
1491 
TEST_P(OutputStreamTest,GetPresentationPositionStop)1492 TEST_P(OutputStreamTest, GetPresentationPositionStop) {
1493     doc::test(
1494         "If supported, a stream should always succeed to retrieve the "
1495         "presentation position");
1496     uint64_t frames;
1497     TimeSpec mesureTS;
1498     ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
1499     if (res == Result::NOT_SUPPORTED) {
1500         doc::partialTest("getpresentationPosition is not supported");
1501         return;
1502     }
1503     ASSERT_EQ(0U, frames);
1504 
1505     if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) {
1506         // As the stream has never written a frame yet,
1507         // the timestamp does not really have a meaning, allow to return 0
1508         return;
1509     }
1510 
1511     // Make sure the return measure is not more than 1s old.
1512     struct timespec currentTS;
1513     ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
1514 
1515     auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
1516     auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
1517     auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
1518     ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime, mesureTime);
1519 }
1520 
1521 //////////////////////////////////////////////////////////////////////////////
1522 /////////////////////////////// PrimaryDevice ////////////////////////////////
1523 //////////////////////////////////////////////////////////////////////////////
1524 
TEST_P(AudioPrimaryHidlTest,setVoiceVolume)1525 TEST_P(AudioPrimaryHidlTest, setVoiceVolume) {
1526     doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
1527     testUnitaryGain([this](float volume) { return getDevice()->setVoiceVolume(volume); });
1528 }
1529 
TEST_P(BoolAccessorPrimaryHidlTest,BtScoNrecEnabled)1530 TEST_P(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
1531     doc::test("Query and set the BT SCO NR&EC state");
1532     testAccessors<OPTIONAL>("BtScoNrecEnabled", Initial{false, OPTIONAL}, {true},
1533                             &IPrimaryDevice::setBtScoNrecEnabled,
1534                             &IPrimaryDevice::getBtScoNrecEnabled);
1535 }
1536 
TEST_P(BoolAccessorPrimaryHidlTest,setGetBtScoWidebandEnabled)1537 TEST_P(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
1538     doc::test("Query and set the SCO whideband state");
1539     testAccessors<OPTIONAL>("BtScoWideband", Initial{false, OPTIONAL}, {true},
1540                             &IPrimaryDevice::setBtScoWidebandEnabled,
1541                             &IPrimaryDevice::getBtScoWidebandEnabled);
1542 }
1543 
1544 using TtyModeAccessorPrimaryHidlTest =
1545         AccessorHidlTest<IPrimaryDevice::TtyMode, AudioPrimaryHidlTest>;
TEST_P(TtyModeAccessorPrimaryHidlTest,setGetTtyMode)1546 TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
1547     doc::test("Query and set the TTY mode state");
1548     testAccessors<OPTIONAL>(
1549         "TTY mode", Initial{IPrimaryDevice::TtyMode::OFF},
1550         {IPrimaryDevice::TtyMode::HCO, IPrimaryDevice::TtyMode::VCO, IPrimaryDevice::TtyMode::FULL},
1551         &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
1552 }
1553 INSTANTIATE_TEST_CASE_P(TtyModeAccessorPrimaryHidl, TtyModeAccessorPrimaryHidlTest,
1554                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1555                         &DeviceParameterToString);
1556 
TEST_P(BoolAccessorPrimaryHidlTest,setGetHac)1557 TEST_P(BoolAccessorPrimaryHidlTest, setGetHac) {
1558     doc::test("Query and set the HAC state");
1559     testAccessors<OPTIONAL>("HAC", Initial{false}, {true}, &IPrimaryDevice::setHacEnabled,
1560                             &IPrimaryDevice::getHacEnabled);
1561 }
1562