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