• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/expected.h>
38 #include <android-base/logging.h>
39 #include <system/audio_config.h>
40 
41 // clang-format off
42 #include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
43 #include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
44 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
45 #include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
46 #include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
47 #if MAJOR_VERSION >= 7
48 #include PATH(APM_XSD_ENUMS_H_FILENAME)
49 #include PATH(APM_XSD_H_FILENAME)
50 #endif
51 // clang-format on
52 
53 #include <fmq/EventFlag.h>
54 #include <fmq/MessageQueue.h>
55 #include <hidl/GtestPrinter.h>
56 #include <hidl/ServiceManagement.h>
57 
58 #include <common/all-versions/VersionUtils.h>
59 
60 #include "utility/AssertOk.h"
61 #include "utility/Documentation.h"
62 #include "utility/ReturnIn.h"
63 #include "utility/ValidateXml.h"
64 
65 #include "AudioTestDefinitions.h"
66 /** Provide version specific functions that are used in the generic tests */
67 #if MAJOR_VERSION == 2
68 #include "2.0/AudioPrimaryHidlHalUtils.h"
69 #elif MAJOR_VERSION >= 4
70 #include "4.0/AudioPrimaryHidlHalUtils.h"
71 #endif
72 
73 using ::android::NO_INIT;
74 using ::android::OK;
75 using ::android::sp;
76 using ::android::status_t;
77 using ::android::hardware::EventFlag;
78 using ::android::hardware::hidl_bitfield;
79 using ::android::hardware::hidl_enum_range;
80 using ::android::hardware::hidl_handle;
81 using ::android::hardware::hidl_string;
82 using ::android::hardware::hidl_vec;
83 using ::android::hardware::IPCThreadState;
84 using ::android::hardware::kSynchronizedReadWrite;
85 using ::android::hardware::MessageQueue;
86 using ::android::hardware::MQDescriptorSync;
87 using ::android::hardware::Return;
88 using ::android::hardware::audio::common::utils::EnumBitfield;
89 using ::android::hardware::audio::common::utils::mkEnumBitfield;
90 using ::android::hardware::details::toHexString;
91 
92 using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
93 using namespace ::android::hardware::audio::common::test::utility;
94 using namespace ::android::hardware::audio::CPP_VERSION;
95 using ReadParameters =
96         ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn::ReadParameters;
97 using ReadStatus = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn::ReadStatus;
98 using WriteCommand = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteCommand;
99 using WriteStatus = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteStatus;
100 #if MAJOR_VERSION >= 7
101 // Make an alias for enumerations generated from the APM config XSD.
102 namespace xsd {
103 using namespace ::android::audio::policy::configuration::CPP_VERSION;
104 }
105 #endif
106 
107 // Typical accepted results from interface methods
108 static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
109 static auto okOrNotSupportedOrInvalidArgs = {Result::OK, Result::NOT_SUPPORTED,
110                                              Result::INVALID_ARGUMENTS};
111 static auto okOrInvalidState = {Result::OK, Result::INVALID_STATE};
112 static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE,
113                                               Result::NOT_SUPPORTED};
114 static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
115 static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
116 
117 #include "DeviceManager.h"
118 #if MAJOR_VERSION <= 6
119 #include "PolicyConfig.h"
120 #if MAJOR_VERSION == 6
121 #include "6.0/Generators.h"
122 #endif
123 #elif MAJOR_VERSION >= 7
124 #include "7.0/Generators.h"
125 #include "7.0/PolicyConfig.h"
126 #endif
127 #include "StreamWorker.h"
128 
129 class HidlTest : public ::testing::Test {
130   public:
131     using IDevice = ::android::hardware::audio::CPP_VERSION::IDevice;
132     using IDevicesFactory = ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
133 
getAllFactoryInstances()134     static android::base::expected<std::vector<std::string>, std::string> getAllFactoryInstances() {
135         using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
136         const std::string factoryDescriptor = IDevicesFactory::descriptor;
137         // Make sure that the instance is the exact minor version.
138         // Using a 7.1 factory for 7.0 test is not always possible because
139         // 7.1 can be configured via the XML config to use features that are
140         // absent in 7.0.
141         auto instances = ::android::hardware::getAllHalInstanceNames(factoryDescriptor);
142         if (instances.empty()) return instances;
143         // Use the default instance for checking the implementation version.
144         auto defaultInstance = IDevicesFactory::getService("default");
145         if (defaultInstance == nullptr) {
146             return ::android::base::unexpected("Failed to obtain IDevicesFactory/default");
147         }
148         std::string actualDescriptor;
149         auto intDescRet = defaultInstance->interfaceDescriptor(
150                 [&](const auto& descriptor) { actualDescriptor = descriptor; });
151         if (!intDescRet.isOk()) {
152             return ::android::base::unexpected("Failed to obtain interface descriptor: " +
153                                                intDescRet.description());
154         }
155         if (factoryDescriptor == actualDescriptor)
156             return instances;
157         else
158             return {};
159     }
160 
161     virtual ~HidlTest() = default;
162     // public access to avoid annoyances when using this method in template classes
163     // derived from test classes
getDevice()164     sp<IDevice> getDevice() const {
165         return DeviceManager::getInstance().get(getFactoryName(), getDeviceName());
166     }
167 
168   protected:
169     // Factory and device name getters to be overridden in subclasses.
170     virtual const std::string& getFactoryName() const = 0;
171     virtual const std::string& getDeviceName() const = 0;
172 
getDevicesFactory()173     sp<IDevicesFactory> getDevicesFactory() const {
174         return DevicesFactoryManager::getInstance().get(getFactoryName());
175     }
resetDevice()176     bool resetDevice() const {
177         return DeviceManager::getInstance().reset(getFactoryName(), getDeviceName());
178     }
areAudioPatchesSupported()179     bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
180 
181     // Convenient member to store results
182     Result res;
183 };
184 
185 //////////////////////////////////////////////////////////////////////////////
186 ////////////////////////// Audio policy configuration ////////////////////////
187 //////////////////////////////////////////////////////////////////////////////
188 
189 // Stringify the argument.
190 #define QUOTE(x) #x
191 #define STRINGIFY(x) QUOTE(x)
192 
193 static constexpr char kConfigFileName[] = "audio_policy_configuration.xml";
194 
195 // Cached policy config after parsing for faster test startup
getCachedPolicyConfig()196 const PolicyConfig& getCachedPolicyConfig() {
197     static std::unique_ptr<PolicyConfig> policyConfig = [] {
198         auto config = std::make_unique<PolicyConfig>("", kConfigFileName);
199         return config;
200     }();
201     return *policyConfig;
202 }
203 
TEST(CheckConfig,audioPolicyConfigurationValidation)204 TEST(CheckConfig, audioPolicyConfigurationValidation) {
205     const auto factories = HidlTest::getAllFactoryInstances();
206     if (!factories.ok()) {
207         FAIL() << factories.error();
208     }
209     if (factories.value().size() == 0) {
210         GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
211                         "are found.";
212     }
213     RecordProperty("description",
214                    "Verify that the audio policy configuration file "
215                    "is valid according to the schema");
216 
217     const char* xsd = "/data/local/tmp/audio_policy_configuration_" STRINGIFY(CPP_VERSION) ".xsd";
218     EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(kConfigFileName,
219                                             android::audio_get_configuration_paths(), xsd);
220 }
221 
222 //////////////////////////////////////////////////////////////////////////////
223 //////////////////// Test parameter types and definitions ////////////////////
224 //////////////////////////////////////////////////////////////////////////////
225 
DeviceParameterToString(const::testing::TestParamInfo<DeviceParameter> & info)226 static inline std::string DeviceParameterToString(
227         const ::testing::TestParamInfo<DeviceParameter>& info) {
228     const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
229     const auto factoryName =
230             ::android::hardware::PrintInstanceNameToString(::testing::TestParamInfo<std::string>{
231                     std::get<PARAM_FACTORY_NAME>(info.param), info.index});
232     return !deviceName.empty() ? factoryName + "_" + deviceName : factoryName;
233 }
234 
getDeviceParameters()235 const std::vector<DeviceParameter>& getDeviceParameters() {
236     static std::vector<DeviceParameter> parameters = [] {
237         std::vector<DeviceParameter> result;
238         const auto factories = HidlTest::getAllFactoryInstances();
239         if (!factories.ok()) return result;
240         const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
241         result.reserve(devices.size());
242         for (const auto& factoryName : factories.value()) {
243             for (const auto& deviceName : devices) {
244                 if (DeviceManager::getInstance().get(factoryName, deviceName) != nullptr) {
245                     result.emplace_back(factoryName, deviceName);
246                 }
247             }
248         }
249         return result;
250     }();
251     return parameters;
252 }
253 
getDeviceParametersForFactoryTests()254 const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
255     static std::vector<DeviceParameter> parameters = [] {
256         std::vector<DeviceParameter> result;
257         const auto factories = HidlTest::getAllFactoryInstances();
258         if (!factories.ok()) return result;
259         for (const auto& factoryName : factories.value()) {
260             result.emplace_back(factoryName,
261                                 DeviceManager::getInstance().getPrimary(factoryName) != nullptr
262                                         ? DeviceManager::kPrimaryDevice
263                                         : "");
264         }
265         return result;
266     }();
267     return parameters;
268 }
269 
getDeviceParametersForPrimaryDeviceTests()270 const std::vector<DeviceParameter>& getDeviceParametersForPrimaryDeviceTests() {
271     static std::vector<DeviceParameter> parameters = [] {
272         std::vector<DeviceParameter> result;
273         const auto primary = std::find_if(
274                 getDeviceParameters().begin(), getDeviceParameters().end(), [](const auto& elem) {
275                     return std::get<PARAM_DEVICE_NAME>(elem) == DeviceManager::kPrimaryDevice;
276                 });
277         if (primary != getDeviceParameters().end()) result.push_back(*primary);
278         return result;
279     }();
280     return parameters;
281 }
282 
283 class AudioHidlTestWithDeviceParameter : public HidlTest,
284                                          public ::testing::WithParamInterface<DeviceParameter> {
285   protected:
getFactoryName()286     const std::string& getFactoryName() const override {
287         return std::get<PARAM_FACTORY_NAME>(GetParam());
288     }
getDeviceName()289     const std::string& getDeviceName() const override {
290         return std::get<PARAM_DEVICE_NAME>(GetParam());
291     }
292 };
293 
294 class AudioPolicyConfigTest : public AudioHidlTestWithDeviceParameter {
295   public:
SetUp()296     void SetUp() override {
297         ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp());  // setup base
298         auto& policyConfig = getCachedPolicyConfig();
299         ASSERT_EQ(0, policyConfig.getStatus()) << policyConfig.getError();
300     }
301 };
302 
TEST_P(AudioPolicyConfigTest,LoadAudioPolicyXMLConfiguration)303 TEST_P(AudioPolicyConfigTest, LoadAudioPolicyXMLConfiguration) {
304     doc::test("Test parsing audio_policy_configuration.xml (called in SetUp)");
305 }
306 
TEST_P(AudioPolicyConfigTest,HasPrimaryModule)307 TEST_P(AudioPolicyConfigTest, HasPrimaryModule) {
308     auto& policyConfig = getCachedPolicyConfig();
309     ASSERT_TRUE(policyConfig.getPrimaryModule() != nullptr)
310             << "Could not find primary module in configuration file: "
311             << policyConfig.getFilePath();
312 }
313 
314 INSTANTIATE_TEST_CASE_P(AudioHidl, AudioPolicyConfigTest,
315                         ::testing::ValuesIn(getDeviceParametersForFactoryTests()),
316                         &DeviceParameterToString);
317 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
318 // list is empty, this isn't a problem.
319 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPolicyConfigTest);
320 
321 //////////////////////////////////////////////////////////////////////////////
322 ////////////////////// getService audio_devices_factory //////////////////////
323 //////////////////////////////////////////////////////////////////////////////
324 
325 // Test audio devices factory
326 class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
327   public:
328     using IPrimaryDevice = ::android::hardware::audio::CPP_VERSION::IPrimaryDevice;
329 
SetUp()330     void SetUp() override {
331         ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp());  // setup base
332         ASSERT_TRUE(getDevicesFactory() != nullptr);
333     }
334 };
335 
TEST_P(AudioHidlTest,GetAudioDevicesFactoryService)336 TEST_P(AudioHidlTest, GetAudioDevicesFactoryService) {
337     doc::test("Test the getService");
338 }
339 
TEST_P(AudioHidlTest,OpenDeviceInvalidParameter)340 TEST_P(AudioHidlTest, OpenDeviceInvalidParameter) {
341     doc::test("Test passing an invalid parameter to openDevice");
342     Result result;
343     sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IDevice> device;
344 #if MAJOR_VERSION == 2
345     auto invalidDevice = IDevicesFactory::Device(-1);
346 #elif MAJOR_VERSION >= 4
347     auto invalidDevice = "Non existing device";
348 #endif
349     ASSERT_OK(getDevicesFactory()->openDevice(invalidDevice, returnIn(result, device)));
350     ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
351     ASSERT_TRUE(device == nullptr);
352 }
353 
354 INSTANTIATE_TEST_CASE_P(AudioHidl, AudioHidlTest,
355                         ::testing::ValuesIn(getDeviceParametersForFactoryTests()),
356                         &DeviceParameterToString);
357 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
358 // list is empty, this isn't a problem.
359 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioHidlTest);
360 
361 //////////////////////////////////////////////////////////////////////////////
362 /////////////////////////////// openDevice ///////////////////////////////////
363 //////////////////////////////////////////////////////////////////////////////
364 
365 // Test all audio devices
366 class AudioHidlDeviceTest : public AudioHidlTest {
367   public:
SetUp()368     void SetUp() override {
369         ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
370         ASSERT_TRUE(getDevice() != nullptr);
371     }
372 };
373 
TEST_P(AudioHidlDeviceTest,OpenDevice)374 TEST_P(AudioHidlDeviceTest, OpenDevice) {
375     doc::test("Test openDevice (called during setup)");
376 }
377 
TEST_P(AudioHidlDeviceTest,Init)378 TEST_P(AudioHidlDeviceTest, Init) {
379     doc::test("Test that the audio hal initialized correctly");
380     ASSERT_OK(getDevice()->initCheck());
381 }
382 
383 INSTANTIATE_TEST_CASE_P(AudioHidlDevice, AudioHidlDeviceTest,
384                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
385 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
386 // list is empty, this isn't a problem.
387 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioHidlDeviceTest);
388 
389 //////////////////////////////////////////////////////////////////////////////
390 /////////////////////////////// openDevice primary ///////////////////////////
391 //////////////////////////////////////////////////////////////////////////////
392 
393 // Test the primary device
394 class AudioPrimaryHidlTest : public AudioHidlDeviceTest {
395   public:
SetUp()396     void SetUp() override {
397         ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
398         ASSERT_TRUE(getDevice() != nullptr);
399     }
400 
401     // public access to avoid annoyances when using this method in template classes
402     // derived from test classes
getDevice()403     sp<IPrimaryDevice> getDevice() const {
404         return DeviceManager::getInstance().getPrimary(getFactoryName());
405     }
406 };
407 
TEST_P(AudioPrimaryHidlTest,OpenPrimaryDevice)408 TEST_P(AudioPrimaryHidlTest, OpenPrimaryDevice) {
409     doc::test("Test openPrimaryDevice (called during setup)");
410 }
411 
412 INSTANTIATE_TEST_CASE_P(AudioPrimaryHidl, AudioPrimaryHidlTest,
413                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
414                         &DeviceParameterToString);
415 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
416 // list is empty, this isn't a problem.
417 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPrimaryHidlTest);
418 
419 //////////////////////////////////////////////////////////////////////////////
420 ///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
421 //////////////////////////////////////////////////////////////////////////////
422 
423 template <class Property, class BaseTestClass = AudioHidlDeviceTest>
424 class AccessorHidlTest : public BaseTestClass {
425   protected:
426     enum Optionality { REQUIRED, OPTIONAL };
427     struct Initial {  // Initial property value
valueInitial428         Initial(Property value, Optionality check = REQUIRED) : value(value), check(check) {}
429         Property value;
430         Optionality check;  // If this initial value should be checked
431     };
432     using BaseTestClass::res;
433     /** Test a property getter and setter.
434      *  The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
435      */
436     template <Optionality optionality = REQUIRED, class IUTGetter, class Getter, class Setter>
437     void testAccessors(IUTGetter iutGetter, const std::string& propertyName,
438                        const Initial expectedInitial, std::list<Property> valuesToTest,
439                        Setter setter, Getter getter,
440                        const std::vector<Property>& invalidValues = {}) {
441         const auto expectedResults = {Result::OK,
442                                       optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
443 
444         Property initialValue = expectedInitial.value;
445         ASSERT_OK(((this->*iutGetter)().get()->*getter)(returnIn(res, initialValue)));
446         ASSERT_RESULT(expectedResults, res);
447         if (res == Result::OK && expectedInitial.check == REQUIRED) {
448             EXPECT_EQ(expectedInitial.value, initialValue);
449         }
450 
451         valuesToTest.push_front(expectedInitial.value);
452         valuesToTest.push_back(initialValue);
453         for (Property setValue : valuesToTest) {
454             SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
455                          testing::PrintToString(setValue));
456             auto ret = ((this->*iutGetter)().get()->*setter)(setValue);
457             ASSERT_RESULT(expectedResults, ret);
458             if (ret == Result::NOT_SUPPORTED) {
459                 doc::partialTest(propertyName + " setter is not supported");
460                 break;
461             }
462             Property getValue;
463             // Make sure the getter returns the same value just set
464             ASSERT_OK(((this->*iutGetter)().get()->*getter)(returnIn(res, getValue)));
465             ASSERT_RESULT(expectedResults, res);
466             if (res == Result::NOT_SUPPORTED) {
467                 doc::partialTest(propertyName + " getter is not supported");
468                 continue;
469             }
470             EXPECT_EQ(setValue, getValue);
471         }
472 
473         for (Property invalidValue : invalidValues) {
474             SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
475                          testing::PrintToString(invalidValue));
476             EXPECT_RESULT(invalidArgsOrNotSupported,
477                           ((this->*iutGetter)().get()->*setter)(invalidValue));
478         }
479 
480         // Restore initial value
481         EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue));
482     }
483     template <Optionality optionality = REQUIRED, class Getter, class Setter>
484     void testAccessors(const std::string& propertyName, const Initial expectedInitial,
485                        std::list<Property> valuesToTest, Setter setter, Getter getter,
486                        const std::vector<Property>& invalidValues = {}) {
487         testAccessors<optionality>(&BaseTestClass::getDevice, propertyName, expectedInitial,
488                                    valuesToTest, setter, getter, invalidValues);
489     }
490 };
491 
492 using BoolAccessorHidlTest = AccessorHidlTest<bool>;
493 using BoolAccessorPrimaryHidlTest = AccessorHidlTest<bool, AudioPrimaryHidlTest>;
494 
TEST_P(BoolAccessorHidlTest,MicMuteTest)495 TEST_P(BoolAccessorHidlTest, MicMuteTest) {
496     doc::test("Check that the mic can be muted and unmuted");
497     testAccessors<OPTIONAL>("mic mute", Initial{false}, {true}, &IDevice::setMicMute,
498                             &IDevice::getMicMute);
499     // TODO: check that the mic is really muted (all sample are 0)
500 }
501 
TEST_P(BoolAccessorHidlTest,MasterMuteTest)502 TEST_P(BoolAccessorHidlTest, MasterMuteTest) {
503     doc::test("If master mute is supported, try to mute and unmute the master output");
504     testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
505                             &IDevice::getMasterMute);
506     // TODO: check that the master volume is really muted
507 }
508 
509 INSTANTIATE_TEST_CASE_P(BoolAccessorHidl, BoolAccessorHidlTest,
510                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
511 INSTANTIATE_TEST_CASE_P(BoolAccessorPrimaryHidl, BoolAccessorPrimaryHidlTest,
512                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
513                         &DeviceParameterToString);
514 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
515 // list is empty, this isn't a problem.
516 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BoolAccessorHidlTest);
517 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BoolAccessorPrimaryHidlTest);
518 
519 using FloatAccessorHidlTest = AccessorHidlTest<float>;
TEST_P(FloatAccessorHidlTest,MasterVolumeTest)520 TEST_P(FloatAccessorHidlTest, MasterVolumeTest) {
521     doc::test("Test the master volume if supported");
522     testAccessors<OPTIONAL>(
523         "master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
524         {-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()});
525     // TODO: check that the master volume is really changed
526 }
527 
528 INSTANTIATE_TEST_CASE_P(FloatAccessorHidl, FloatAccessorHidlTest,
529                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
530 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
531 // list is empty, this isn't a problem.
532 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FloatAccessorHidlTest);
533 
534 //////////////////////////////////////////////////////////////////////////////
535 //////////////////////////////// AudioPatches ////////////////////////////////
536 //////////////////////////////////////////////////////////////////////////////
537 
538 class AudioPatchHidlTest : public AudioHidlDeviceTest {
539   public:
SetUp()540     void SetUp() override {
541         ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
542         if (!areAudioPatchesSupported()) {
543             GTEST_SKIP() << "Audio patches are not supported";
544         }
545     }
546 };
547 
TEST_P(AudioPatchHidlTest,AudioPatches)548 TEST_P(AudioPatchHidlTest, AudioPatches) {
549     doc::test("Test if audio patches are supported");
550     // TODO: test audio patches
551 }
552 
553 INSTANTIATE_TEST_CASE_P(AudioPatchHidl, AudioPatchHidlTest,
554                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
555 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
556 // list is empty, this isn't a problem.
557 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest);
558 
559 #if MAJOR_VERSION >= 4
SanitizeStringForGTestName(const std::string & s)560 static std::string SanitizeStringForGTestName(const std::string& s) {
561     std::string result = s;
562     for (size_t i = 0; i < result.size(); i++) {
563         // gtest test names must only contain alphanumeric characters
564         if (!std::isalnum(result[i])) result[i] = '_';
565     }
566     return result;
567 }
568 #endif
569 
570 /** Generate a test name based on an audio config.
571  *
572  * As the only parameter changing are channel mask and sample rate,
573  * only print those ones in the test name.
574  */
DeviceConfigParameterToString(const testing::TestParamInfo<DeviceConfigParameter> & info)575 static std::string DeviceConfigParameterToString(
576         const testing::TestParamInfo<DeviceConfigParameter>& info) {
577     const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
578     const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
579             std::get<PARAM_DEVICE>(info.param), info.index});
580     const auto devicePart =
581             (deviceName.empty() ? "" : deviceName + "_") + std::to_string(info.index);
582     // The types had changed a lot between versions 2, 4..6 and 7. Use separate
583     // code sections for easier understanding.
584 #if MAJOR_VERSION == 2
585     const auto configPart =
586             std::to_string(config.sampleRateHz) + "_" +
587             // "MONO" is more clear than "FRONT_LEFT"
588             (config.channelMask == AudioChannelMask::OUT_MONO ||
589                              config.channelMask == AudioChannelMask::IN_MONO
590                      ? "MONO"
591                      : ::testing::PrintToString(config.channelMask)) +
592             "_" +
593             std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
594                        std::get<PARAM_FLAGS>(info.param));
595 #elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
596     const auto configPart =
597             std::to_string(config.sampleRateHz) + "_" +
598             // "MONO" is more clear than "FRONT_LEFT"
599             (config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
600                              config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO)
601                      ? "MONO"
602                      // In V4 and above the channel mask is a bitfield.
603                      // Printing its value using HIDL's toString for a bitfield emits a lot of extra
604                      // text due to overlapping constant values. Instead, we print the bitfield
605                      // value as if it was a single value + its hex representation
606                      : SanitizeStringForGTestName(
607                                ::testing::PrintToString(AudioChannelMask(config.channelMask)) +
608                                "_" + toHexString(config.channelMask))) +
609             "_" +
610             SanitizeStringForGTestName(std::visit(
611                     [](auto&& arg) -> std::string {
612                         using T = std::decay_t<decltype(arg)>;
613                         // Need to use FQN of toString to avoid confusing the compiler
614                         return ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::
615                                 toString<T>(hidl_bitfield<T>(arg));
616                     },
617                     std::get<PARAM_FLAGS>(info.param)));
618 #elif MAJOR_VERSION >= 7
619     const auto configPart =
620             ::testing::PrintToString(std::get<PARAM_ATTACHED_DEV_ADDR>(info.param).deviceType) +
621             "_" + std::to_string(config.base.sampleRateHz) + "_" +
622             // The channel masks and flags are vectors of strings, just need to sanitize them.
623             SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" +
624             SanitizeStringForGTestName(::testing::PrintToString(std::get<PARAM_FLAGS>(info.param)));
625 #endif
626     return devicePart + "__" + configPart;
627 }
628 
629 class AudioHidlTestWithDeviceConfigParameter
630     : public HidlTest,
631       public ::testing::WithParamInterface<DeviceConfigParameter> {
632   protected:
SetUp()633     void SetUp() override {
634         ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
635         ASSERT_TRUE(getDevicesFactory() != nullptr);
636         ASSERT_TRUE(getDevice() != nullptr);
637     }
getFactoryName()638     const std::string& getFactoryName() const override {
639         return std::get<PARAM_FACTORY_NAME>(std::get<PARAM_DEVICE>(GetParam()));
640     }
getDeviceName()641     const std::string& getDeviceName() const override {
642         return std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(GetParam()));
643     }
getConfig()644     const AudioConfig& getConfig() const { return std::get<PARAM_CONFIG>(GetParam()); }
645 #if MAJOR_VERSION == 2
getInputFlags()646     AudioInputFlag getInputFlags() const {
647         return std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam()));
648     }
getOutputFlags()649     AudioOutputFlag getOutputFlags() const {
650         return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
651     }
652 #elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
getInputFlags()653     hidl_bitfield<AudioInputFlag> getInputFlags() const {
654         return hidl_bitfield<AudioInputFlag>(
655                 std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
656     }
getOutputFlags()657     hidl_bitfield<AudioOutputFlag> getOutputFlags() const {
658         return hidl_bitfield<AudioOutputFlag>(
659                 std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
660     }
661 #elif MAJOR_VERSION >= 7
getAttachedDeviceAddress()662     DeviceAddress getAttachedDeviceAddress() const {
663         return std::get<PARAM_ATTACHED_DEV_ADDR>(GetParam());
664     }
getInputFlags()665     hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
getOutputFlags()666     hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
667 #endif
668 };
669 
670 #if MAJOR_VERSION <= 6
671 #define AUDIO_PRIMARY_HIDL_HAL_TEST
672 #include "ConfigHelper.h"
673 #undef AUDIO_PRIMARY_HIDL_HAL_TEST
674 #endif
675 
676 //////////////////////////////////////////////////////////////////////////////
677 ///////////////////////////// getInputBufferSize /////////////////////////////
678 //////////////////////////////////////////////////////////////////////////////
679 
680 // FIXME: execute input test only if platform declares
681 // android.hardware.microphone
682 //        how to get this value ? is it a property ???
683 
684 class AudioCaptureConfigTest : public AudioHidlTestWithDeviceConfigParameter {
685   protected:
inputBufferSizeTest(const AudioConfig & audioConfig,bool supportRequired)686     void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
687         uint64_t bufferSize;
688         ASSERT_OK(getDevice()->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
689 
690         switch (res) {
691             case Result::INVALID_ARGUMENTS:
692                 EXPECT_FALSE(supportRequired);
693                 break;
694             case Result::OK:
695                 // Check that the buffer is of a sane size
696                 // For now only that it is > 0
697                 EXPECT_GT(bufferSize, uint64_t(0));
698                 break;
699             default:
700                 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
701         }
702     }
703 };
704 
705 // Test that the required capture config and those declared in the policy are
706 // indeed supported
707 class RequiredInputBufferSizeTest : public AudioCaptureConfigTest {};
TEST_P(RequiredInputBufferSizeTest,RequiredInputBufferSizeTest)708 TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
709     doc::test(
710         "Input buffer size must be retrievable for a format with required "
711         "support.");
712     inputBufferSizeTest(getConfig(), true);
713 }
714 
715 // Test that the recommended capture config are supported or lead to a
716 // INVALID_ARGUMENTS return
717 class OptionalInputBufferSizeTest : public AudioCaptureConfigTest {};
TEST_P(OptionalInputBufferSizeTest,OptionalInputBufferSizeTest)718 TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
719     doc::test(
720             "Input buffer size should be retrievable for a format with recommended "
721             "support.");
722     inputBufferSizeTest(getConfig(), false);
723 }
724 
725 #if MAJOR_VERSION <= 5
726 // For V2..5 test the primary device according to CDD requirements.
727 INSTANTIATE_TEST_CASE_P(
728         RequiredInputBufferSize, RequiredInputBufferSizeTest,
729         ::testing::Combine(
730                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
731                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
732                 ::testing::Values(AudioInputFlag::NONE)),
733         &DeviceConfigParameterToString);
734 INSTANTIATE_TEST_CASE_P(
735         RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
736         ::testing::Combine(
737                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
738                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
739                 ::testing::Values(AudioInputFlag::NONE)),
740         &DeviceConfigParameterToString);
741 #elif MAJOR_VERSION >= 6
742 INSTANTIATE_TEST_CASE_P(SupportedInputBufferSize, RequiredInputBufferSizeTest,
743                         ::testing::ValuesIn(getInputDeviceConfigParameters()),
744                         &DeviceConfigParameterToString);
745 #endif
746 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
747 // list is empty, this isn't a problem.
748 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OptionalInputBufferSizeTest);
749 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RequiredInputBufferSizeTest);
750 
751 //////////////////////////////////////////////////////////////////////////////
752 /////////////////////////////// setScreenState ///////////////////////////////
753 //////////////////////////////////////////////////////////////////////////////
754 
TEST_P(AudioHidlDeviceTest,setScreenState)755 TEST_P(AudioHidlDeviceTest, setScreenState) {
756     doc::test("Check that the hal can receive the screen state");
757     for (bool turnedOn : {false, true, true, false, false}) {
758         ASSERT_RESULT(okOrNotSupported, getDevice()->setScreenState(turnedOn));
759     }
760 }
761 
762 //////////////////////////////////////////////////////////////////////////////
763 //////////////////////////// {get,set}Parameters /////////////////////////////
764 //////////////////////////////////////////////////////////////////////////////
765 
TEST_P(AudioHidlDeviceTest,getParameters)766 TEST_P(AudioHidlDeviceTest, getParameters) {
767     doc::test("Check that the hal can set and get parameters");
768     hidl_vec<ParameterValue> context;
769     hidl_vec<hidl_string> keys;
770     hidl_vec<ParameterValue> values;
771     ASSERT_OK(Parameters::get(getDevice(), keys, returnIn(res, values)));
772     ASSERT_RESULT(okOrNotSupported, res);
773     ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
774     values.resize(0);
775     ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
776 }
777 
778 //////////////////////////////////////////////////////////////////////////////
779 //////////////////////////////// debugDebug //////////////////////////////////
780 //////////////////////////////////////////////////////////////////////////////
781 
782 template <class DebugDump>
testDebugDump(DebugDump debugDump)783 static void testDebugDump(DebugDump debugDump) {
784     // File descriptors to our pipe. fds[0] corresponds to the read end and
785     // fds[1] to the write end.
786     int fds[2];
787     ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
788 
789     // Make sure that the pipe is at least 1 MB in size. The test process runs
790     // in su domain, so it should be safe to make this call.
791     fcntl(fds[0], F_SETPIPE_SZ, 1 << 20);
792 
793     // Wrap the temporary file file descriptor in a native handle
794     auto* nativeHandle = native_handle_create(1, 0);
795     ASSERT_NE(nullptr, nativeHandle);
796     nativeHandle->data[0] = fds[1];
797 
798     // Wrap this native handle in a hidl handle
799     hidl_handle handle;
800     handle.setTo(nativeHandle, false /*take ownership*/);
801 
802     ASSERT_OK(debugDump(handle));
803 
804     // Check that at least one bit was written by the hal
805     // TODO: debugDump does not return a Result.
806     // This mean that the hal can not report that it not implementing the
807     // function.
808     char buff;
809     if (read(fds[0], &buff, 1) != 1) {
810         doc::note("debugDump does not seem implemented");
811     }
812     EXPECT_EQ(0, close(fds[0])) << errno;
813     EXPECT_EQ(0, close(fds[1])) << errno;
814 }
815 
TEST_P(AudioHidlDeviceTest,DebugDump)816 TEST_P(AudioHidlDeviceTest, DebugDump) {
817     doc::test("Check that the hal can dump its state without error");
818     testDebugDump([this](const auto& handle) { return dump(getDevice(), handle); });
819 }
820 
TEST_P(AudioHidlDeviceTest,DebugDumpInvalidArguments)821 TEST_P(AudioHidlDeviceTest, DebugDumpInvalidArguments) {
822     doc::test("Check that the hal dump doesn't crash on invalid arguments");
823     ASSERT_OK(dump(getDevice(), hidl_handle()));
824 }
825 
826 //////////////////////////////////////////////////////////////////////////////
827 ////////////////////////// open{Output,Input}Stream //////////////////////////
828 //////////////////////////////////////////////////////////////////////////////
829 
getNextIoHandle()830 static inline AudioIoHandle getNextIoHandle() {
831     static AudioIoHandle lastHandle{};
832     return ++lastHandle;
833 }
834 
835 // This class is also used by some device tests.
836 template <class Stream>
837 class StreamHelper {
838   public:
839     // StreamHelper doesn't own the stream, this is for simpler stream lifetime management.
StreamHelper(sp<Stream> & stream)840     explicit StreamHelper(sp<Stream>& stream) : mStream(stream) {}
841     template <class Open>
open(Open openStream,const AudioConfig & config,Result * res,AudioConfig * suggestedConfigPtr)842     void open(Open openStream, const AudioConfig& config, Result* res,
843               AudioConfig* suggestedConfigPtr) {
844         AudioConfig suggestedConfig{};
845         bool retryWithSuggestedConfig = true;
846         if (suggestedConfigPtr == nullptr) {
847             suggestedConfigPtr = &suggestedConfig;
848             retryWithSuggestedConfig = false;
849         }
850         ASSERT_OK(openStream(mIoHandle, config, returnIn(*res, mStream, *suggestedConfigPtr)));
851         switch (*res) {
852             case Result::OK:
853                 ASSERT_TRUE(mStream != nullptr);
854                 *suggestedConfigPtr = config;
855                 break;
856             case Result::INVALID_ARGUMENTS:
857                 ASSERT_TRUE(mStream == nullptr);
858                 if (retryWithSuggestedConfig) {
859                     AudioConfig suggestedConfigRetry;
860                     ASSERT_OK(openStream(mIoHandle, *suggestedConfigPtr,
861                                          returnIn(*res, mStream, suggestedConfigRetry)));
862                     ASSERT_OK(*res);
863                     ASSERT_TRUE(mStream != nullptr);
864                 }
865                 break;
866             default:
867                 FAIL() << "Invalid return status: " << ::testing::PrintToString(*res);
868         }
869     }
close(bool clear,Result * res)870     void close(bool clear, Result* res) {
871         auto ret = mStream->close();
872         EXPECT_TRUE(ret.isOk());
873         *res = ret;
874         if (clear) {
875             mStream.clear();
876 #if MAJOR_VERSION <= 5
877             // FIXME: there is no way to know when the remote IStream is being destroyed
878             //        Binder does not support testing if an object is alive, thus
879             //        wait for 100ms to let the binder destruction propagates and
880             //        the remote device has the time to be destroyed.
881             //        flushCommand makes sure all local command are sent, thus should reduce
882             //        the latency between local and remote destruction.
883             IPCThreadState::self()->flushCommands();
884             usleep(100 * 1000);
885 #endif
886         }
887     }
getIoHandle()888     AudioIoHandle getIoHandle() const { return mIoHandle; }
889 
890   private:
891     const AudioIoHandle mIoHandle = getNextIoHandle();
892     sp<Stream>& mStream;
893 };
894 
895 template <class Stream>
896 class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
897   public:
898     // public access to avoid annoyances when using this method in template classes
899     // derived from test classes
getStream()900     sp<Stream> getStream() const { return stream; }
901 
902   protected:
OpenStreamTest()903     OpenStreamTest() : AudioHidlTestWithDeviceConfigParameter(), helper(stream) {}
904     template <class Open>
testOpen(Open openStream,const AudioConfig & config)905     void testOpen(Open openStream, const AudioConfig& config) {
906         // TODO: only allow failure for RecommendedPlaybackAudioConfig
907         ASSERT_NO_FATAL_FAILURE(helper.open(openStream, config, &res, &audioConfig));
908         open = true;
909     }
910 
911     Result closeStream(bool clear = true) {
912         open = false;
913         helper.close(clear, &res);
914         return res;
915     }
916 
TearDown()917     void TearDown() override {
918         if (open) {
919             ASSERT_OK(closeStream());
920         }
921         AudioHidlTestWithDeviceConfigParameter::TearDown();
922     }
923 
924   protected:
925     AudioConfig audioConfig;
926     DeviceAddress address = {};
927     sp<Stream> stream;
928     StreamHelper<Stream> helper;
929     bool open = false;
930 };
931 
932 ////////////////////////////// openOutputStream //////////////////////////////
933 
934 class StreamWriter : public StreamWorker<StreamWriter> {
935   public:
936     using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
937 
StreamWriter(IStreamOut * stream,size_t bufferSize)938     StreamWriter(IStreamOut* stream, size_t bufferSize)
939         : mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
StreamWriter(IStreamOut * stream,size_t bufferSize,std::vector<uint8_t> && data,std::function<void ()> onDataStart,std::function<bool ()> onDataWrap)940     StreamWriter(IStreamOut* stream, size_t bufferSize, std::vector<uint8_t>&& data,
941                  std::function<void()> onDataStart, std::function<bool()> onDataWrap)
942         : mStream(stream),
943           mBufferSize(bufferSize),
944           mData(std::move(data)),
945           mOnDataStart(onDataStart),
946           mOnDataWrap(onDataWrap) {
947         ALOGI("StreamWriter data size: %d", (int)mData.size());
948     }
~StreamWriter()949     ~StreamWriter() {
950         stop();
951         if (mEfGroup) {
952             EventFlag::deleteEventFlag(&mEfGroup);
953         }
954     }
955 
956     typedef MessageQueue<WriteCommand, ::android::hardware::kSynchronizedReadWrite> CommandMQ;
957     typedef MessageQueue<uint8_t, ::android::hardware::kSynchronizedReadWrite> DataMQ;
958     typedef MessageQueue<WriteStatus, ::android::hardware::kSynchronizedReadWrite> StatusMQ;
959 
workerInit()960     bool workerInit() {
961         std::unique_ptr<CommandMQ> tempCommandMQ;
962         std::unique_ptr<DataMQ> tempDataMQ;
963         std::unique_ptr<StatusMQ> tempStatusMQ;
964         Result retval;
965         Return<void> ret = mStream->prepareForWriting(
966                 1, mBufferSize,
967                 [&](Result r, const CommandMQ::Descriptor& commandMQ,
968                     const DataMQ::Descriptor& dataMQ, const StatusMQ::Descriptor& statusMQ,
969                     const auto& /*halThreadInfo*/) {
970                     retval = r;
971                     if (retval == Result::OK) {
972                         tempCommandMQ.reset(new CommandMQ(commandMQ));
973                         tempDataMQ.reset(new DataMQ(dataMQ));
974                         tempStatusMQ.reset(new StatusMQ(statusMQ));
975                         if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
976                             EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
977                         }
978                     }
979                 });
980         if (!ret.isOk()) {
981             ALOGE("Transport error while calling prepareForWriting: %s", ret.description().c_str());
982             return false;
983         }
984         if (retval != Result::OK) {
985             ALOGE("Error from prepareForWriting: %d", retval);
986             return false;
987         }
988         if (!tempCommandMQ || !tempCommandMQ->isValid() || !tempDataMQ || !tempDataMQ->isValid() ||
989             !tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) {
990             ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for writing");
991             ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
992                      "Command message queue for writing is invalid");
993             ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for writing");
994             ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(),
995                      "Data message queue for writing is invalid");
996             ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for writing");
997             ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
998                      "Status message queue for writing is invalid");
999             ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
1000             return false;
1001         }
1002         mCommandMQ = std::move(tempCommandMQ);
1003         mDataMQ = std::move(tempDataMQ);
1004         mStatusMQ = std::move(tempStatusMQ);
1005         return true;
1006     }
1007 
workerCycle()1008     bool workerCycle() {
1009         WriteCommand cmd = WriteCommand::WRITE;
1010         if (!mCommandMQ->write(&cmd)) {
1011             ALOGE("command message queue write failed");
1012             return false;
1013         }
1014         if (mDataPosition == 0) mOnDataStart();
1015         const size_t dataSize = std::min(mData.size() - mDataPosition, mDataMQ->availableToWrite());
1016         bool success = mDataMQ->write(mData.data() + mDataPosition, dataSize);
1017         bool wrapped = false;
1018         ALOGE_IF(!success, "data message queue write failed");
1019         mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
1020 
1021         uint32_t efState = 0;
1022     retry:
1023         status_t ret =
1024                 mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
1025         if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
1026             WriteStatus writeStatus;
1027             writeStatus.retval = Result::NOT_INITIALIZED;
1028             if (!mStatusMQ->read(&writeStatus)) {
1029                 ALOGE("status message read failed");
1030                 success = false;
1031             }
1032             if (writeStatus.retval != Result::OK) {
1033                 ALOGE("bad write status: %d", writeStatus.retval);
1034                 success = false;
1035             }
1036             mDataPosition += writeStatus.reply.written;
1037             if (mDataPosition >= mData.size()) {
1038                 mDataPosition = 0;
1039                 wrapped = true;
1040             }
1041         }
1042         if (ret == -EAGAIN || ret == -EINTR) {
1043             // Spurious wakeup. This normally retries no more than once.
1044             goto retry;
1045         } else if (ret) {
1046             ALOGE("bad wait status: %d", ret);
1047             success = false;
1048         }
1049         if (wrapped) {
1050             success = mOnDataWrap();
1051         }
1052         return success;
1053     }
1054 
1055   private:
1056     IStreamOut* const mStream;
1057     const size_t mBufferSize;
1058     std::vector<uint8_t> mData;
1059     std::function<void()> mOnDataStart = []() {};
1060     std::function<bool()> mOnDataWrap = []() { return true; };
1061     size_t mDataPosition = 0;
1062     std::unique_ptr<CommandMQ> mCommandMQ;
1063     std::unique_ptr<DataMQ> mDataMQ;
1064     std::unique_ptr<StatusMQ> mStatusMQ;
1065     EventFlag* mEfGroup = nullptr;
1066 };
1067 
1068 class OutputStreamTest
1069     : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamOut> {
1070   protected:
SetUp()1071     void SetUp() override {
1072         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
1073 #if MAJOR_VERSION <= 6
1074         address.device = AudioDevice::OUT_DEFAULT;
1075 #elif MAJOR_VERSION >= 7
1076         address = getAttachedDeviceAddress();
1077 #endif
1078         const AudioConfig& config = getConfig();
1079         auto flags = getOutputFlags();
1080         testOpen(
1081                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
1082 #if MAJOR_VERSION == 2
1083                     return getDevice()->openOutputStream(handle, address, config, flags, cb);
1084 #elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
1085                     return getDevice()->openOutputStream(handle, address, config, flags,
1086                                                          initMetadata, cb);
1087 #elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
1088                     return getDevice()->openOutputStream_7_1(handle, address, config, flags,
1089                                                              initMetadata, cb);
1090 #endif
1091                 },
1092                 config);
1093     }
1094 #if MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
1095 
1096     const SourceMetadata initMetadata = {
1097         { { AudioUsage::MEDIA,
1098             AudioContentType::MUSIC,
1099             1 /* gain */ } }};
1100 #elif MAJOR_VERSION >= 7
1101   protected:
1102     const SourceMetadata initMetadata = {
1103             { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
1104                 toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
1105                 1 /* gain */,
1106                 toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
1107                 {} } }};
1108 #endif
1109 };
TEST_P(OutputStreamTest,OpenOutputStreamTest)1110 TEST_P(OutputStreamTest, OpenOutputStreamTest) {
1111     doc::test(
1112         "Check that output streams can be open with the required and "
1113         "recommended config");
1114     // Open done in SetUp
1115 }
1116 
1117 #if MAJOR_VERSION <= 5
1118 // For V2..5 test the primary device according to CDD requirements.
1119 INSTANTIATE_TEST_CASE_P(
1120         RequiredOutputStreamConfigSupport, OutputStreamTest,
1121         ::testing::Combine(
1122                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1123                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportPlaybackAudioConfig()),
1124                 ::testing::Values(AudioOutputFlag::NONE)),
1125         &DeviceConfigParameterToString);
1126 INSTANTIATE_TEST_CASE_P(
1127         RecommendedOutputStreamConfigSupport, OutputStreamTest,
1128         ::testing::Combine(
1129                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1130                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportPlaybackAudioConfig()),
1131                 ::testing::Values(AudioOutputFlag::NONE)),
1132         &DeviceConfigParameterToString);
1133 #elif MAJOR_VERSION >= 6
1134 // For V6 and above test according to the audio policy manager configuration.
1135 // This is more correct as CDD is written from the apps perspective.
1136 // Audio system provides necessary format conversions for missing configurations.
1137 INSTANTIATE_TEST_CASE_P(DeclaredOutputStreamConfigSupport, OutputStreamTest,
1138                         ::testing::ValuesIn(getOutputDeviceConfigParameters()),
1139                         &DeviceConfigParameterToString);
1140 #endif
1141 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
1142 // list is empty, this isn't a problem.
1143 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamTest);
1144 
1145 ////////////////////////////// openInputStream //////////////////////////////
1146 
1147 class StreamReader : public StreamWorker<StreamReader> {
1148   public:
1149     using IStreamIn = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn;
1150 
StreamReader(IStreamIn * stream,size_t bufferSize)1151     StreamReader(IStreamIn* stream, size_t bufferSize)
1152         : mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
~StreamReader()1153     ~StreamReader() {
1154         stop();
1155         if (mEfGroup) {
1156             EventFlag::deleteEventFlag(&mEfGroup);
1157         }
1158     }
1159 
1160     typedef MessageQueue<ReadParameters, ::android::hardware::kSynchronizedReadWrite> CommandMQ;
1161     typedef MessageQueue<uint8_t, ::android::hardware::kSynchronizedReadWrite> DataMQ;
1162     typedef MessageQueue<ReadStatus, ::android::hardware::kSynchronizedReadWrite> StatusMQ;
1163 
workerInit()1164     bool workerInit() {
1165         std::unique_ptr<CommandMQ> tempCommandMQ;
1166         std::unique_ptr<DataMQ> tempDataMQ;
1167         std::unique_ptr<StatusMQ> tempStatusMQ;
1168         Result retval;
1169         Return<void> ret = mStream->prepareForReading(
1170                 1, mBufferSize,
1171                 [&](Result r, const CommandMQ::Descriptor& commandMQ,
1172                     const DataMQ::Descriptor& dataMQ, const StatusMQ::Descriptor& statusMQ,
1173                     const auto& /*halThreadInfo*/) {
1174                     retval = r;
1175                     if (retval == Result::OK) {
1176                         tempCommandMQ.reset(new CommandMQ(commandMQ));
1177                         tempDataMQ.reset(new DataMQ(dataMQ));
1178                         tempStatusMQ.reset(new StatusMQ(statusMQ));
1179                         if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
1180                             EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
1181                         }
1182                     }
1183                 });
1184         if (!ret.isOk()) {
1185             ALOGE("Transport error while calling prepareForReading: %s", ret.description().c_str());
1186             return false;
1187         }
1188         if (retval != Result::OK) {
1189             ALOGE("Error from prepareForReading: %d", retval);
1190             return false;
1191         }
1192         if (!tempCommandMQ || !tempCommandMQ->isValid() || !tempDataMQ || !tempDataMQ->isValid() ||
1193             !tempStatusMQ || !tempStatusMQ->isValid() || !mEfGroup) {
1194             ALOGE_IF(!tempCommandMQ, "Failed to obtain command message queue for reading");
1195             ALOGE_IF(tempCommandMQ && !tempCommandMQ->isValid(),
1196                      "Command message queue for reading is invalid");
1197             ALOGE_IF(!tempDataMQ, "Failed to obtain data message queue for reading");
1198             ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(),
1199                      "Data message queue for reading is invalid");
1200             ALOGE_IF(!tempStatusMQ, "Failed to obtain status message queue for reading");
1201             ALOGE_IF(tempStatusMQ && !tempStatusMQ->isValid(),
1202                      "Status message queue for reading is invalid");
1203             ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
1204             return false;
1205         }
1206         mCommandMQ = std::move(tempCommandMQ);
1207         mDataMQ = std::move(tempDataMQ);
1208         mStatusMQ = std::move(tempStatusMQ);
1209         return true;
1210     }
1211 
workerCycle()1212     bool workerCycle() {
1213         ReadParameters params;
1214         params.command = IStreamIn::ReadCommand::READ;
1215         params.params.read = mBufferSize;
1216         if (!mCommandMQ->write(&params)) {
1217             ALOGE("command message queue write failed");
1218             return false;
1219         }
1220         mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
1221 
1222         uint32_t efState = 0;
1223         bool success = true;
1224     retry:
1225         status_t ret =
1226                 mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
1227         if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
1228             ReadStatus readStatus;
1229             readStatus.retval = Result::NOT_INITIALIZED;
1230             if (!mStatusMQ->read(&readStatus)) {
1231                 ALOGE("status message read failed");
1232                 success = false;
1233             }
1234             if (readStatus.retval != Result::OK) {
1235                 ALOGE("bad read status: %d", readStatus.retval);
1236                 success = false;
1237             }
1238             const size_t dataSize = std::min(mData.size(), mDataMQ->availableToRead());
1239             if (!mDataMQ->read(mData.data(), dataSize)) {
1240                 ALOGE("data message queue read failed");
1241                 success = false;
1242             }
1243         }
1244         if (ret == -EAGAIN || ret == -EINTR) {
1245             // Spurious wakeup. This normally retries no more than once.
1246             goto retry;
1247         } else if (ret) {
1248             ALOGE("bad wait status: %d", ret);
1249             success = false;
1250         }
1251         return success;
1252     }
1253 
1254   private:
1255     IStreamIn* const mStream;
1256     const size_t mBufferSize;
1257     std::vector<uint8_t> mData;
1258     std::unique_ptr<CommandMQ> mCommandMQ;
1259     std::unique_ptr<DataMQ> mDataMQ;
1260     std::unique_ptr<StatusMQ> mStatusMQ;
1261     EventFlag* mEfGroup = nullptr;
1262 };
1263 
1264 class InputStreamTest
1265     : public OpenStreamTest<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> {
SetUp()1266     void SetUp() override {
1267         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
1268         auto flags = getInputFlags();
1269 #if MAJOR_VERSION <= 6
1270         address.device = AudioDevice::IN_DEFAULT;
1271 #elif MAJOR_VERSION >= 7
1272         address = getAttachedDeviceAddress();
1273         auto& metadata = initMetadata.tracks[0];
1274         if (!xsd::isTelephonyDevice(address.deviceType)) {
1275             metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_UNPROCESSED);
1276             metadata.channelMask = getConfig().base.channelMask;
1277         } else {
1278             address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
1279         }
1280 #if MAJOR_VERSION == 7 && MINOR_VERSION >= 1
1281         auto flagsIt = std::find(flags.begin(), flags.end(),
1282                                  toString(xsd::AudioInOutFlag::AUDIO_INPUT_FLAG_ULTRASOUND));
1283         if (flagsIt != flags.end()) {
1284             metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_ULTRASOUND);
1285         }
1286 #endif  // 7.1
1287 #endif  // MAJOR_VERSION >= 7
1288         const AudioConfig& config = getConfig();
1289         testOpen(
1290                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
1291                     return getDevice()->openInputStream(handle, address, config, flags,
1292                                                         initMetadata, cb);
1293                 },
1294                 config);
1295     }
1296 
1297    protected:
1298 #if MAJOR_VERSION == 2
1299      const AudioSource initMetadata = AudioSource::DEFAULT;
1300 #elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6
1301      const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }};
1302 #elif MAJOR_VERSION >= 7
1303      const std::string& getMixPortName() const { return std::get<PARAM_PORT_NAME>(GetParam()); }
1304      SinkMetadata initMetadata = {
1305              {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT),
1306                .gain = 1,
1307                .tags = {},
1308                .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
1309 #endif
1310 };
1311 
TEST_P(InputStreamTest,OpenInputStreamTest)1312 TEST_P(InputStreamTest, OpenInputStreamTest) {
1313     doc::test(
1314         "Check that input streams can be open with the required and "
1315         "recommended config");
1316     // Open done in setup
1317 }
1318 #if MAJOR_VERSION <= 5
1319 // For V2..5 test the primary device according to CDD requirements.
1320 INSTANTIATE_TEST_CASE_P(
1321         RequiredInputStreamConfigSupport, InputStreamTest,
1322         ::testing::Combine(
1323                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1324                 ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
1325                 ::testing::Values(AudioInputFlag::NONE)),
1326         &DeviceConfigParameterToString);
1327 INSTANTIATE_TEST_CASE_P(
1328         RecommendedInputStreamConfigSupport, InputStreamTest,
1329         ::testing::Combine(
1330                 ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1331                 ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
1332                 ::testing::Values(AudioInputFlag::NONE)),
1333         &DeviceConfigParameterToString);
1334 #elif MAJOR_VERSION >= 6
1335 // For V6 and above test according to the audio policy manager configuration.
1336 // This is more correct as CDD is written from the apps perspective.
1337 // Audio system provides necessary format conversions for missing configurations.
1338 INSTANTIATE_TEST_CASE_P(DeclaredInputStreamConfigSupport, InputStreamTest,
1339                         ::testing::ValuesIn(getInputDeviceConfigParameters()),
1340                         &DeviceConfigParameterToString);
1341 #endif
1342 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
1343 // list is empty, this isn't a problem.
1344 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamTest);
1345 
1346 //////////////////////////////////////////////////////////////////////////////
1347 ////////////////////////////// IStream getters ///////////////////////////////
1348 //////////////////////////////////////////////////////////////////////////////
1349 
1350 /* Could not find a way to write a test for two parametrized class fixure
1351  * thus use this macro do duplicate tests for Input and Output stream */
1352 #define TEST_IO_STREAM(test_name, documentation, code) \
1353     TEST_P(InputStreamTest, test_name) {               \
1354         doc::test(documentation);                      \
1355         code;                                          \
1356     }                                                  \
1357     TEST_P(OutputStreamTest, test_name) {              \
1358         doc::test(documentation);                      \
1359         code;                                          \
1360     }
1361 
1362 TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.",
1363                ASSERT_TRUE(stream->getFrameCount().isOk()))
1364 
1365 #if MAJOR_VERSION <= 6
1366 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
1367                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
1368 
1369 TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
1370                ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
1371 
1372 TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
1373                ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
1374 #endif
1375 
1376 // TODO: for now only check that the framesize is not incoherent
1377 TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
1378                ASSERT_GT(extract(stream->getFrameSize()), 0U))
1379 
1380 TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
1381                ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
1382 
1383 template <class Property, class CapabilityGetter>
1384 static void testCapabilityGetter(const std::string& name, IStream* stream,
1385                                  CapabilityGetter capabilityGetter,
1386                                  Return<Property> (IStream::*getter)(),
1387                                  Return<Result> (IStream::*setter)(Property),
1388                                  bool currentMustBeSupported = true) {
1389     hidl_vec<Property> capabilities;
1390     auto ret = capabilityGetter(stream, capabilities);
1391     ASSERT_RESULT(okOrNotSupported, ret);
1392     bool notSupported = ret == Result::NOT_SUPPORTED;
1393     if (notSupported) {
1394         doc::partialTest(name + " is not supported");
1395         return;
1396     };
1397 
1398     if (currentMustBeSupported) {
1399         ASSERT_NE(0U, capabilities.size()) << name << " must not return an empty list";
1400         Property currentValue = extract((stream->*getter)());
1401         EXPECT_TRUE(std::find(capabilities.begin(), capabilities.end(), currentValue) !=
1402                     capabilities.end())
1403             << "value returned by " << name << "() = " << testing::PrintToString(currentValue)
1404             << " is not in the list of the supported ones " << toString(capabilities);
1405     }
1406 
1407     // Check that all declared supported values are indeed supported
1408     for (auto capability : capabilities) {
1409         auto ret = (stream->*setter)(capability);
1410         ASSERT_TRUE(ret.isOk());
1411         if (ret == Result::NOT_SUPPORTED) {
1412             doc::partialTest("Setter is not supported");
1413             return;
1414         }
1415         ASSERT_OK(ret);
1416         ASSERT_EQ(capability, extract((stream->*getter)()));
1417     }
1418 }
1419 
1420 #if MAJOR_VERSION <= 6
1421 TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
1422                testCapabilityGetter("getSupportedSampleRate", stream.get(),
1423                                     &GetSupported::sampleRates, &IStream::getSampleRate,
1424                                     &IStream::setSampleRate,
1425                                     // getSupportedSampleRate returns the native sampling rates,
1426                                     // (the sampling rates that can be played without resampling)
1427                                     // but other sampling rates can be supported by the HAL.
1428                                     false))
1429 
1430 TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
1431                testCapabilityGetter("getSupportedChannelMask", stream.get(),
1432                                     &GetSupported::channelMasks, &IStream::getChannelMask,
1433                                     &IStream::setChannelMask))
1434 
1435 TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
1436                testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
1437                                     &IStream::getFormat, &IStream::setFormat))
1438 #else
1439 static void testGetSupportedProfiles(IStream* stream) {
1440     Result res;
1441     hidl_vec<AudioProfile> profiles;
1442     auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
1443     EXPECT_TRUE(ret.isOk());
1444     if (res == Result::OK) {
1445         EXPECT_GT(profiles.size(), 0);
1446     } else {
1447         EXPECT_EQ(Result::NOT_SUPPORTED, res);
1448     }
1449 }
1450 
1451 TEST_IO_STREAM(GetSupportedProfiles, "Try to call optional method GetSupportedProfiles",
1452                testGetSupportedProfiles(stream.get()))
1453 
1454 static void testSetAudioProperties(IStream* stream) {
1455     Result res;
1456     hidl_vec<AudioProfile> profiles;
1457     auto ret = stream->getSupportedProfiles(returnIn(res, profiles));
1458     EXPECT_TRUE(ret.isOk());
1459     if (res == Result::NOT_SUPPORTED) {
1460         GTEST_SKIP() << "Retrieving supported profiles is not implemented";
1461     }
1462     for (const auto& profile : profiles) {
1463         for (const auto& sampleRate : profile.sampleRates) {
1464             for (const auto& channelMask : profile.channelMasks) {
1465                 AudioConfigBaseOptional config;
1466                 config.format.value(profile.format);
1467                 config.sampleRateHz.value(sampleRate);
1468                 config.channelMask.value(channelMask);
1469                 auto ret = stream->setAudioProperties(config);
1470                 EXPECT_TRUE(ret.isOk());
1471                 if (ret == Result::NOT_SUPPORTED) {
1472                     GTEST_SKIP() << "setAudioProperties is not supported";
1473                 }
1474                 EXPECT_EQ(Result::OK, ret)
1475                         << profile.format << "; " << sampleRate << "; " << channelMask;
1476             }
1477         }
1478     }
1479 }
1480 
1481 TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles",
1482                testSetAudioProperties(stream.get()))
1483 #endif  // MAJOR_VERSION <= 6
1484 
testGetAudioProperties(IStream * stream,AudioConfig expectedConfig)1485 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
1486 #if MAJOR_VERSION <= 6
1487     uint32_t sampleRateHz;
1488     auto mask = mkEnumBitfield<AudioChannelMask>({});
1489     AudioFormat format;
1490 
1491     auto ret = stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
1492     EXPECT_TRUE(ret.isOk());
1493 
1494     // FIXME: the qcom hal it does not currently negotiate the sampleRate &
1495     // channel mask
1496     EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
1497     EXPECT_EQ(expectedConfig.channelMask, mask);
1498     EXPECT_EQ(expectedConfig.format, format);
1499 #elif MAJOR_VERSION >= 7
1500     Result res;
1501     AudioConfigBase actualConfig{};
1502     auto ret = stream->getAudioProperties(returnIn(res, actualConfig));
1503     EXPECT_TRUE(ret.isOk());
1504     EXPECT_EQ(Result::OK, res);
1505     EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz);
1506     EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask);
1507     EXPECT_EQ(expectedConfig.base.format, actualConfig.format);
1508 #endif
1509 }
1510 
1511 TEST_IO_STREAM(GetAudioProperties,
1512                "Check that the stream audio properties == the ones it was opened with",
1513                testGetAudioProperties(stream.get(), audioConfig))
1514 
1515 TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
1516                ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
1517 
checkGetNoParameter(IStream * stream,hidl_vec<hidl_string> keys,std::initializer_list<Result> expectedResults)1518 static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
1519                                 std::initializer_list<Result> expectedResults) {
1520     hidl_vec<ParameterValue> parameters;
1521     Result res;
1522     ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
1523     ASSERT_RESULT(expectedResults, res);
1524     if (res == Result::OK) {
1525         for (auto& parameter : parameters) {
1526             ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
1527         }
1528     }
1529 }
1530 
1531 /* Get/Set parameter is intended to be an opaque channel between vendors app and
1532  * their HALs.
1533  * Thus can not be meaningfully tested.
1534  */
1535 TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
1536                checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
1537 
1538 TEST_IO_STREAM(getNonExistingParameter, "Retrieve the values of an non existing parameter",
1539                checkGetNoParameter(stream.get(), {"Non existing key"} /* keys */,
1540                                    {Result::NOT_SUPPORTED}))
1541 
1542 TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
1543                ASSERT_RESULT(Result::OK, Parameters::set(stream, {})))
1544 
1545 TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
1546                // Unfortunately, the set_parameter legacy interface did not return any
1547                // error code when a key is not supported.
1548                // To allow implementation to just wrapped the legacy one, consider OK as a
1549                // valid result for setting a non existing parameter.
1550                ASSERT_RESULT(okOrNotSupportedOrInvalidArgs,
1551                              Parameters::set(stream, {{"non existing key", "0"}})))
1552 
1553 TEST_IO_STREAM(DebugDump, "Check that a stream can dump its state without error",
1554                testDebugDump([this](const auto& handle) { return dump(stream, handle); }))
1555 
1556 TEST_IO_STREAM(DebugDumpInvalidArguments,
1557                "Check that the stream dump doesn't crash on invalid arguments",
1558                ASSERT_OK(dump(stream, hidl_handle())))
1559 
1560 //////////////////////////////////////////////////////////////////////////////
1561 ////////////////////////////// addRemoveEffect ///////////////////////////////
1562 //////////////////////////////////////////////////////////////////////////////
1563 
1564 TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
1565                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
1566 TEST_IO_STREAM(RemoveNonExistingEffect, "Removing a non existing effect should fail",
1567                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->removeEffect(666)))
1568 
1569 // TODO: positive tests
1570 
1571 //////////////////////////////////////////////////////////////////////////////
1572 /////////////////////////////// Control ////////////////////////////////
1573 //////////////////////////////////////////////////////////////////////////////
1574 
1575 TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
1576                ASSERT_OK(stream->standby()))  // can not fail
1577 
1578 TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
1579                ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
1580 
1581 TEST_IO_STREAM(stopNoMmap, "Stopping a mmaped stream before mapping it should fail",
1582                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
1583 
1584 TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping it should fail",
1585                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
1586 
1587 TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
1588 // clang-format off
1589 TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
1590         ASSERT_OK(closeStream(false /*clear*/));
1591         ASSERT_EQ(Result::INVALID_STATE, closeStream()))
1592 // clang-format on
1593 
testMmapBufferOfInvalidSize(IStream * stream)1594 static void testMmapBufferOfInvalidSize(IStream* stream) {
1595     for (int32_t value : {-1, 0, std::numeric_limits<int32_t>::max()}) {
1596         MmapBufferInfo info;
1597         Result res;
1598         EXPECT_OK(stream->createMmapBuffer(value, returnIn(res, info)));
1599         EXPECT_RESULT(invalidArgsOrNotSupported, res) << "value=" << value;
1600     }
1601 }
1602 
1603 TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer of invalid size must fail",
1604                testMmapBufferOfInvalidSize(stream.get()))
1605 
testGetMmapPositionOfNonMmapedStream(IStream * stream)1606 static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
1607     Result res;
1608     MmapPosition position;
1609     ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
1610     ASSERT_RESULT(invalidArgsOrNotSupported, res);
1611 }
1612 
1613 TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream,
1614                "Retrieving the mmap position of a non mmaped stream should fail",
1615                testGetMmapPositionOfNonMmapedStream(stream.get()))
1616 
1617 //////////////////////////////////////////////////////////////////////////////
1618 ///////////////////////////////// StreamIn ///////////////////////////////////
1619 //////////////////////////////////////////////////////////////////////////////
1620 
TEST_P(InputStreamTest,GetAudioSource)1621 TEST_P(InputStreamTest, GetAudioSource) {
1622     doc::test("Retrieving the audio source of an input stream should always succeed");
1623     AudioSource source;
1624     ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
1625     if (res == Result::NOT_SUPPORTED) {
1626         doc::partialTest("getAudioSource is not supported");
1627         return;
1628     }
1629     ASSERT_OK(res);
1630 #if MAJOR_VERSION <= 6
1631     ASSERT_EQ(AudioSource::DEFAULT, source);
1632 #elif MAJOR_VERSION >= 7
1633     ASSERT_EQ(xsd::AudioSource::AUDIO_SOURCE_DEFAULT, xsd::stringToAudioSource(source));
1634 #endif
1635 }
1636 
testUnitaryGain(std::function<Return<Result> (float)> setGain)1637 static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
1638     for (float value : (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(), 2.0,
1639                                  INFINITY, NAN}) {
1640         EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value=" << value;
1641     }
1642     // Do not consider -0.0 as an invalid value as it is == with 0.0
1643     for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
1644         EXPECT_OK(setGain(value)) << "value=" << value;
1645     }
1646 }
1647 
testOptionalUnitaryGain(std::function<Return<Result> (float)> setGain,std::string debugName)1648 static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain,
1649                                     std::string debugName) {
1650     auto result = setGain(1);
1651     ASSERT_IS_OK(result);
1652     if (result == Result::NOT_SUPPORTED) {
1653         doc::partialTest(debugName + " is not supported");
1654         return;
1655     }
1656     testUnitaryGain(setGain);
1657 }
1658 
TEST_P(InputStreamTest,SetGain)1659 TEST_P(InputStreamTest, SetGain) {
1660     doc::test("The gain of an input stream should only be set between [0,1]");
1661     testOptionalUnitaryGain([this](float volume) { return stream->setGain(volume); },
1662                             "InputStream::setGain");
1663 }
1664 
testPrepareForReading(::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn * stream,uint32_t frameSize,uint32_t framesCount)1665 static void testPrepareForReading(
1666         ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn* stream, uint32_t frameSize,
1667         uint32_t framesCount) {
1668     Result res;
1669     // Ignore output parameters as the call should fail
1670     ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
1671                                         [&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
1672     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1673 }
1674 
TEST_P(InputStreamTest,PrepareForReadingWithZeroBuffer)1675 TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
1676     doc::test("Preparing a stream for reading with a 0 sized buffer should fail");
1677     testPrepareForReading(stream.get(), 0, 0);
1678 }
1679 
TEST_P(InputStreamTest,PrepareForReadingWithHugeBuffer)1680 TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
1681     doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail");
1682     testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max());
1683 }
1684 
TEST_P(InputStreamTest,PrepareForReadingCheckOverflow)1685 TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
1686     doc::test(
1687         "Preparing a stream for reading with a overflowing sized buffer should "
1688         "fail");
1689     auto uintMax = std::numeric_limits<uint32_t>::max();
1690     testPrepareForReading(stream.get(), uintMax, uintMax);
1691 }
1692 
TEST_P(InputStreamTest,GetInputFramesLost)1693 TEST_P(InputStreamTest, GetInputFramesLost) {
1694     doc::test("The number of frames lost on a never started stream should be 0");
1695     auto ret = stream->getInputFramesLost();
1696     ASSERT_IS_OK(ret);
1697     uint32_t framesLost{ret};
1698     ASSERT_EQ(0U, framesLost);
1699 }
1700 
1701 //////////////////////////////////////////////////////////////////////////////
1702 ///////////////////////////////// StreamOut //////////////////////////////////
1703 //////////////////////////////////////////////////////////////////////////////
1704 
TEST_P(OutputStreamTest,getLatency)1705 TEST_P(OutputStreamTest, getLatency) {
1706     doc::test("Make sure latency is over 0");
1707     auto result = stream->getLatency();
1708     ASSERT_IS_OK(result);
1709     ASSERT_GT(result, 0U);
1710 }
1711 
TEST_P(OutputStreamTest,setVolume)1712 TEST_P(OutputStreamTest, setVolume) {
1713     doc::test("Try to set the output volume");
1714     testOptionalUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); },
1715                             "setVolume");
1716 }
1717 
testPrepareForWriting(::android::hardware::audio::CPP_VERSION::IStreamOut * stream,uint32_t frameSize,uint32_t framesCount)1718 static void testPrepareForWriting(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
1719                                   uint32_t frameSize, uint32_t framesCount) {
1720     Result res;
1721     // Ignore output parameters as the call should fail
1722     ASSERT_OK(stream->prepareForWriting(frameSize, framesCount,
1723                                         [&res](auto r, auto&, auto&, auto&, auto) { res = r; }));
1724     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1725 }
1726 
TEST_P(OutputStreamTest,PrepareForWriteWithZeroBuffer)1727 TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
1728     doc::test("Preparing a stream for writing with a 0 sized buffer should fail");
1729     testPrepareForWriting(stream.get(), 0, 0);
1730 }
1731 
TEST_P(OutputStreamTest,PrepareForWriteWithHugeBuffer)1732 TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
1733     doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail");
1734     testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max());
1735 }
1736 
TEST_P(OutputStreamTest,PrepareForWritingCheckOverflow)1737 TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
1738     doc::test(
1739         "Preparing a stream for writing with a overflowing sized buffer should "
1740         "fail");
1741     auto uintMax = std::numeric_limits<uint32_t>::max();
1742     testPrepareForWriting(stream.get(), uintMax, uintMax);
1743 }
1744 
1745 struct Capability {
1746     using IStreamOut = ::android::hardware::audio::CPP_VERSION::IStreamOut;
1747 
CapabilityCapability1748     Capability(IStreamOut* stream) {
1749         EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
1750         drain = extract(stream->supportsDrain());
1751     }
1752     bool pause = false;
1753     bool resume = false;
1754     bool drain = false;
1755 };
1756 
TEST_P(OutputStreamTest,SupportsPauseAndResumeAndDrain)1757 TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
1758     doc::test("Implementation must expose pause, resume and drain capabilities");
1759     Capability(stream.get());
1760 }
1761 
TEST_P(OutputStreamTest,GetRenderPosition)1762 TEST_P(OutputStreamTest, GetRenderPosition) {
1763     doc::test("A new stream render position should be 0 or INVALID_STATE");
1764     uint32_t dspFrames;
1765     ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
1766     if (res == Result::NOT_SUPPORTED) {
1767         doc::partialTest("getRenderPosition is not supported");
1768         return;
1769     }
1770     expectValueOrFailure(res, 0U, dspFrames, Result::INVALID_STATE);
1771 }
1772 
TEST_P(OutputStreamTest,GetNextWriteTimestamp)1773 TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
1774     doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
1775     uint64_t timestampUs;
1776     ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
1777     if (res == Result::NOT_SUPPORTED) {
1778         doc::partialTest("getNextWriteTimestamp is not supported");
1779         return;
1780     }
1781     expectValueOrFailure(res, uint64_t{0}, timestampUs, Result::INVALID_STATE);
1782 }
1783 
1784 /** Stub implementation of out stream callback. */
1785 class MockOutCallbacks : public IStreamOutCallback {
onWriteReady()1786     Return<void> onWriteReady() override { return {}; }
onDrainReady()1787     Return<void> onDrainReady() override { return {}; }
onError()1788     Return<void> onError() override { return {}; }
1789 };
1790 
isAsyncModeSupported(::android::hardware::audio::CPP_VERSION::IStreamOut * stream)1791 static bool isAsyncModeSupported(::android::hardware::audio::CPP_VERSION::IStreamOut* stream) {
1792     auto res = stream->setCallback(new MockOutCallbacks);
1793     stream->clearCallback();  // try to restore the no callback state, ignore
1794                               // any error
1795     EXPECT_RESULT(okOrNotSupported, res);
1796     return res.isOk() ? res == Result::OK : false;
1797 }
1798 
TEST_P(OutputStreamTest,SetCallback)1799 TEST_P(OutputStreamTest, SetCallback) {
1800     doc::test(
1801         "If supported, registering callback for async operation should never "
1802         "fail");
1803     if (!isAsyncModeSupported(stream.get())) {
1804         doc::partialTest("The stream does not support async operations");
1805         return;
1806     }
1807     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1808     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1809 }
1810 
TEST_P(OutputStreamTest,clearCallback)1811 TEST_P(OutputStreamTest, clearCallback) {
1812     doc::test(
1813         "If supported, clearing a callback to go back to sync operation should "
1814         "not fail");
1815     if (!isAsyncModeSupported(stream.get())) {
1816         doc::partialTest("The stream does not support async operations");
1817         return;
1818     }
1819     // TODO: Clarify if clearing a non existing callback should fail
1820     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1821     ASSERT_OK(stream->clearCallback());
1822 }
1823 
TEST_P(OutputStreamTest,Resume)1824 TEST_P(OutputStreamTest, Resume) {
1825     doc::test(
1826         "If supported, a stream should fail to resume if not previously "
1827         "paused");
1828     if (!Capability(stream.get()).resume) {
1829         doc::partialTest("The output stream does not support resume");
1830         return;
1831     }
1832     ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1833 }
1834 
TEST_P(OutputStreamTest,Pause)1835 TEST_P(OutputStreamTest, Pause) {
1836     doc::test(
1837         "If supported, a stream should fail to pause if not previously "
1838         "started");
1839     if (!Capability(stream.get()).pause) {
1840         doc::partialTest("The output stream does not support pause");
1841         return;
1842     }
1843     ASSERT_RESULT(Result::INVALID_STATE, stream->pause());
1844 }
1845 
testDrain(::android::hardware::audio::CPP_VERSION::IStreamOut * stream,AudioDrain type)1846 static void testDrain(::android::hardware::audio::CPP_VERSION::IStreamOut* stream,
1847                       AudioDrain type) {
1848     if (!Capability(stream).drain) {
1849         doc::partialTest("The output stream does not support drain");
1850         return;
1851     }
1852     ASSERT_RESULT(Result::OK, stream->drain(type));
1853 }
1854 
TEST_P(OutputStreamTest,DrainAll)1855 TEST_P(OutputStreamTest, DrainAll) {
1856     doc::test("If supported, a stream should always succeed to drain");
1857     testDrain(stream.get(), AudioDrain::ALL);
1858 }
1859 
TEST_P(OutputStreamTest,DrainEarlyNotify)1860 TEST_P(OutputStreamTest, DrainEarlyNotify) {
1861     doc::test("If supported, a stream should always succeed to drain");
1862     testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
1863 }
1864 
TEST_P(OutputStreamTest,FlushStop)1865 TEST_P(OutputStreamTest, FlushStop) {
1866     doc::test("If supported, a stream should always succeed to flush");
1867     auto ret = stream->flush();
1868     ASSERT_IS_OK(ret);
1869     if (ret == Result::NOT_SUPPORTED) {
1870         doc::partialTest("Flush is not supported");
1871         return;
1872     }
1873     ASSERT_OK(ret);
1874 }
1875 
TEST_P(OutputStreamTest,GetPresentationPositionStop)1876 TEST_P(OutputStreamTest, GetPresentationPositionStop) {
1877     doc::test(
1878         "If supported, a stream should always succeed to retrieve the "
1879         "presentation position");
1880     uint64_t frames;
1881     TimeSpec measureTS;
1882     ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, measureTS)));
1883 #if MAJOR_VERSION <= 6
1884     if (res == Result::NOT_SUPPORTED) {
1885         doc::partialTest("getPresentationPosition is not supported");
1886         return;
1887     }
1888 #else
1889     ASSERT_NE(Result::NOT_SUPPORTED, res) << "getPresentationPosition is mandatory in V7";
1890 #endif
1891     ASSERT_EQ(0U, frames);
1892 
1893     if (measureTS.tvNSec == 0 && measureTS.tvSec == 0) {
1894         // As the stream has never written a frame yet,
1895         // the timestamp does not really have a meaning, allow to return 0
1896         return;
1897     }
1898 
1899     // Make sure the return measure is not more than 1s old.
1900     struct timespec currentTS;
1901     ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
1902 
1903     auto toMicroSec = [](uint64_t sec, auto nsec) { return sec * 1e+6 + nsec / 1e+3; };
1904     auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
1905     auto measureTime = toMicroSec(measureTS.tvSec, measureTS.tvNSec);
1906     ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime, measureTime);
1907 }
1908 
1909 //////////////////////////////////////////////////////////////////////////////
1910 /////////////////////////////// PrimaryDevice ////////////////////////////////
1911 //////////////////////////////////////////////////////////////////////////////
1912 
TEST_P(AudioPrimaryHidlTest,setVoiceVolume)1913 TEST_P(AudioPrimaryHidlTest, setVoiceVolume) {
1914     doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
1915     testUnitaryGain([this](float volume) { return getDevice()->setVoiceVolume(volume); });
1916 }
1917 
TEST_P(BoolAccessorPrimaryHidlTest,BtScoNrecEnabled)1918 TEST_P(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
1919     doc::test("Query and set the BT SCO NR&EC state");
1920     testAccessors<OPTIONAL>("BtScoNrecEnabled", Initial{false, OPTIONAL}, {true},
1921                             &IPrimaryDevice::setBtScoNrecEnabled,
1922                             &IPrimaryDevice::getBtScoNrecEnabled);
1923 }
1924 
TEST_P(BoolAccessorPrimaryHidlTest,setGetBtScoWidebandEnabled)1925 TEST_P(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
1926     doc::test("Query and set the SCO whideband state");
1927     testAccessors<OPTIONAL>("BtScoWideband", Initial{false, OPTIONAL}, {true},
1928                             &IPrimaryDevice::setBtScoWidebandEnabled,
1929                             &IPrimaryDevice::getBtScoWidebandEnabled);
1930 }
1931 
1932 using TtyModeAccessorPrimaryHidlTest =
1933         AccessorHidlTest<::android::hardware::audio::CPP_VERSION::IPrimaryDevice::TtyMode,
1934                          AudioPrimaryHidlTest>;
TEST_P(TtyModeAccessorPrimaryHidlTest,setGetTtyMode)1935 TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
1936     doc::test("Query and set the TTY mode state");
1937     testAccessors<OPTIONAL>(
1938         "TTY mode", Initial{IPrimaryDevice::TtyMode::OFF},
1939         {IPrimaryDevice::TtyMode::HCO, IPrimaryDevice::TtyMode::VCO, IPrimaryDevice::TtyMode::FULL},
1940         &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
1941 }
1942 INSTANTIATE_TEST_CASE_P(TtyModeAccessorPrimaryHidl, TtyModeAccessorPrimaryHidlTest,
1943                         ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
1944                         &DeviceParameterToString);
1945 // When the VTS test runs on a device lacking the corresponding HAL version the parameter
1946 // list is empty, this isn't a problem.
1947 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TtyModeAccessorPrimaryHidlTest);
1948 
TEST_P(BoolAccessorPrimaryHidlTest,setGetHac)1949 TEST_P(BoolAccessorPrimaryHidlTest, setGetHac) {
1950     doc::test("Query and set the HAC state");
1951     testAccessors<OPTIONAL>("HAC", Initial{false}, {true}, &IPrimaryDevice::setHacEnabled,
1952                             &IPrimaryDevice::getHacEnabled);
1953 }
1954