blob: d8967881a3ae44cd0c01bd2385e2b35a7c16cad4 [file] [log] [blame]
Kevin Rocardf0357882017-02-10 16:19:28 -08001/*
2 * Copyright (C) 2017 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 "VtsHalAudioV2_0TargetTest"
18
19#include <algorithm>
20#include <cmath>
21#include <cstddef>
22#include <cstdio>
23#include <limits>
24#include <list>
25#include <string>
26#include <type_traits>
27#include <vector>
28
29#include <gtest/gtest.h>
30
31#include <android-base/logging.h>
32
33#include <android/hardware/audio/2.0/IDevice.h>
34#include <android/hardware/audio/2.0/IDevicesFactory.h>
35#include <android/hardware/audio/2.0/types.h>
36#include <android/hardware/audio/common/2.0/types.h>
37
38#include "utility/ReturnIn.h"
39#include "utility/AssertOk.h"
40#include "utility/PrettyPrintAudioTypes.h"
41
42using std::string;
43using std::to_string;
44using std::vector;
45
46using ::android::sp;
47using ::android::hardware::Return;
48using ::android::hardware::hidl_handle;
49using ::android::hardware::hidl_string;
50using ::android::hardware::hidl_vec;
51using ::android::hardware::audio::V2_0::DeviceAddress;
52using ::android::hardware::audio::V2_0::IDevice;
53using ::android::hardware::audio::V2_0::IDevicesFactory;
54using ::android::hardware::audio::V2_0::IStream;
55using ::android::hardware::audio::V2_0::IStreamIn;
56using ::android::hardware::audio::V2_0::IStreamOut;
57using ::android::hardware::audio::V2_0::ParameterValue;
58using ::android::hardware::audio::V2_0::Result;
59using ::android::hardware::audio::common::V2_0::AudioChannelMask;
60using ::android::hardware::audio::common::V2_0::AudioConfig;
61using ::android::hardware::audio::common::V2_0::AudioDevice;
62using ::android::hardware::audio::common::V2_0::AudioFormat;
63using ::android::hardware::audio::common::V2_0::AudioHandleConsts;
64using ::android::hardware::audio::common::V2_0::AudioInputFlag;
65using ::android::hardware::audio::common::V2_0::AudioIoHandle;
66using ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
67using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
68using ::android::hardware::audio::common::V2_0::AudioSource;
69
70using utility::returnIn;
71
72namespace doc {
73/** Document the current test case.
74 * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test will output:
75 * <testcase name="debugDump" status="run" time="6" classname="AudioPrimaryHidlTest"
76 description="Dump the state of the hal." />
77 * see https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
78 */
79void test(const std::string& testCaseDocumentation) {
80 ::testing::Test::RecordProperty("description", testCaseDocumentation);
81}
82
83/** Document why a test was not fully run. Usually due to an optional feature not implemented. */
84void partialTest(const std::string& reason) {
85 ::testing::Test::RecordProperty("partialyRunTest", reason);
86}
87}
88
89// Register callback for static object destruction
90// Avoid destroying static objects after main return.
91// Post main return destruction leads to incorrect gtest timing measurements as well as harder
92// debuging if anything goes wrong during destruction.
93class Environment : public ::testing::Environment {
94public:
95 using TearDownFunc = std::function<void ()>;
96 void registerTearDown(TearDownFunc&& tearDown) {
97 tearDowns.push_back(std::move(tearDown));
98 }
99
100private:
101 void TearDown() override {
102 // Call the tear downs in reverse order of insertion
103 for (auto& tearDown : tearDowns) {
104 tearDown();
105 }
106 }
107 std::list<TearDownFunc> tearDowns;
108};
109// Instance to register global tearDown
110static Environment* environment;
111
112class HidlTest : public ::testing::Test {
113protected:
114 // Convenient member to store results
115 Result res;
116};
117
118//////////////////////////////////////////////////////////////////////////////
119////////////////////// getService audio_devices_factory //////////////////////
120//////////////////////////////////////////////////////////////////////////////
121
122// Test all audio devices
123class AudioHidlTest : public HidlTest {
124public:
125 void SetUp() override {
126 ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
127
128 if (devicesFactory == nullptr) {
129 environment->registerTearDown([]{ devicesFactory.clear(); });
130 devicesFactory = IDevicesFactory::getService();
131 }
132 ASSERT_TRUE(devicesFactory != nullptr);
133 }
134
135protected:
136 // Cache the devicesFactory retrieval to speed up each test by ~0.5s
137 static sp<IDevicesFactory> devicesFactory;
138};
139sp<IDevicesFactory> AudioHidlTest::devicesFactory;
140
141TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
142 doc::test("test the getService (called in SetUp)");
143}
144
145//////////////////////////////////////////////////////////////////////////////
146/////////////////////////////// openDevice primary ///////////////////////////
147//////////////////////////////////////////////////////////////////////////////
148
149// Test the primary device
150class AudioPrimaryHidlTest : public AudioHidlTest {
151public:
152 /** Primary HAL test are NOT thread safe. */
153 void SetUp() override {
154 ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
155
156 if (device == nullptr) {
157 environment->registerTearDown([]{ device.clear(); });
158 IDevicesFactory::Result result;
159 ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
160 returnIn(result, device)));
161 }
162 ASSERT_TRUE(device != nullptr);
163 }
164
165protected:
166 // Cache the device opening to speed up each test by ~0.5s
167 static sp<IDevice> device;
168};
169sp<IDevice> AudioPrimaryHidlTest::device;
170
171TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
172 doc::test("Test the openDevice (called in SetUp)");
173}
174
175TEST_F(AudioPrimaryHidlTest, Init) {
176 doc::test("Test that the audio primary hal initialized correctly");
177 ASSERT_OK(device->initCheck());
178}
179
180//////////////////////////////////////////////////////////////////////////////
181//////////////////////////// {set,get}MasterVolume ///////////////////////////
182//////////////////////////////////////////////////////////////////////////////
183
184class MasterVolumeTest : public AudioPrimaryHidlTest {
185protected:
186 void testSetGetConsistency(float volume, Result expectedSetResult, float expectedGetVolume) {
187 SCOPED_TRACE("Test set/get consistency for " + to_string(volume));
188 auto ret = device->setMasterVolume(volume);
189 ASSERT_TRUE(ret.isOk());
190 ASSERT_EQ(expectedSetResult, ret);
191
192 float observedVolume;
193 ASSERT_OK(device->getMasterVolume(returnIn(res, observedVolume)));
194 ASSERT_OK(res);
195
196 // Check that `get` returned the expected value
197 EXPECT_EQ(expectedGetVolume, observedVolume);
198 }
199};
200
201TEST_F(MasterVolumeTest, MasterVolumeTest) {
202 doc::test("Test the master volume if supported");
203 {
204 SCOPED_TRACE("Check for master volume support");
205 auto ret = device->setMasterVolume(1);
206 ASSERT_TRUE(ret.isOk());
207 if (ret == Result::NOT_SUPPORTED) {
208 doc::partialTest("Master volume is not supported");
209 return;
210 }
211 }
212 // NOTE: this code has never been tested on a platform supporting MasterVolume
213 float lastValidVolumeSet;
214 using Volumes = float[];
215 SCOPED_TRACE("As set/get master volume are supported...");
216 {
217 SCOPED_TRACE("...test them with valid values");
218 for (float validVolume : Volumes{0, 0.5, 1}) {
219 ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(validVolume, Result::OK, validVolume));
220 lastValidVolumeSet = validVolume;
221 }
222 }{
223 SCOPED_TRACE("...test them with tricky values");
224 for (float outOfBoundVolume :Volumes{-0.1, 1.1, NAN, INFINITY, -INFINITY,
225 1 + std::numeric_limits<float>::epsilon()}) {
226 ASSERT_NO_FATAL_FAILURE(testSetGetConsistency(outOfBoundVolume,
227 Result::INVALID_ARGUMENTS,
228 lastValidVolumeSet));
229 }
230 }
231}
232
233//////////////////////////////////////////////////////////////////////////////
234////////////////////////// {set,get}{Master,Mic}Mute /////////////////////////
235//////////////////////////////////////////////////////////////////////////////
236
237class BoolAccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
238protected:
239 template <class Getter, class Setter>
240 void testBoolAccessors(const string& propertyName, const vector<bool>& valuesToTest,
241 Setter setter, Getter getter) {
242 for (bool setState : valuesToTest) {
243 SCOPED_TRACE("Test " + propertyName + " state: " + to_string(setState));
244 ASSERT_OK((device.get()->*setter)(setState));
245 bool getState;
246 ASSERT_OK((device.get()->*getter)(returnIn(res, getState)));
247 ASSERT_OK(res);
248 ASSERT_EQ(setState, getState);
249 }
250 }
251};
252
253TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
254 doc::test("Check that the mic can be muted and unmuted");
255 testBoolAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
256 // TODO: check that the mic is really muted (all sample are 0)
257}
258
259TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
260 doc::test("If master mute is supported, try to mute and unmute the master output");
261 {
262 SCOPED_TRACE("Check for master mute support");
263 auto ret = device->setMasterMute(false);
264 ASSERT_TRUE(ret.isOk());
265 if (ret == Result::NOT_SUPPORTED) {
266 doc::partialTest("Master mute is not supported");
267 return;
268 }
269 }
270 // NOTE: this code has never been tested on a platform supporting MasterMute
271 testBoolAccessors("master mute", {true, false, true},
272 &IDevice::setMasterMute, &IDevice::getMasterMute);
273 // TODO: check that the master volume is really muted
274}
275
276//////////////////////////////////////////////////////////////////////////////
277//////////////// Required and recommended audio format support ///////////////
278// From: https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
279// From: https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
280/////////// TODO: move to the beginning of the file for easier update ////////
281//////////////////////////////////////////////////////////////////////////////
282
283class AudioConfigPrimaryTest : public AudioPrimaryHidlTest {
284public:
285 // Cache result ?
286 static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
287 return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
288 {8000, 11025, 16000, 22050, 32000, 44100},
289 {AudioFormat::PCM_16_BIT});
290 }
291
292 static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
293 return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
294 {24000, 48000},
295 {AudioFormat::PCM_16_BIT});
296 }
297
298 static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
299 // TODO: retrieve audio config supported by the platform
300 // as declared in the policy configuration
301 return {};
302 }
303
304 static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
305 return combineAudioConfig({AudioChannelMask::IN_MONO},
306 {8000, 11025, 16000, 44100},
307 {AudioFormat::PCM_16_BIT});
308 }
309 static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
310 return combineAudioConfig({AudioChannelMask::IN_STEREO},
311 {22050, 48000},
312 {AudioFormat::PCM_16_BIT});
313 }
314 static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
315 // TODO: retrieve audio config supported by the platform
316 // as declared in the policy configuration
317 return {};
318 }
319private:
320 static const vector<AudioConfig> combineAudioConfig(
321 vector<AudioChannelMask> channelMasks,
322 vector<uint32_t> sampleRates,
323 vector<AudioFormat> formats) {
324 vector<AudioConfig> configs;
325 for (auto channelMask: channelMasks) {
326 for (auto sampleRate : sampleRates) {
327 for (auto format : formats) {
328 AudioConfig config{};
329 // leave offloadInfo to 0
330 config.channelMask = channelMask;
331 config.sampleRateHz = sampleRate;
332 config.format = format;
333 // FIXME: leave frameCount to 0 ?
334 configs.push_back(config);
335 }
336 }
337 }
338 return configs;
339 }
340};
341
342//////////////////////////////////////////////////////////////////////////////
343///////////////////////////// getInputBufferSize /////////////////////////////
344//////////////////////////////////////////////////////////////////////////////
345
346// FIXME: execute input test only if platform declares android.hardware.microphone
347// how to get this value ? is it a property ???
348
349class AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest,
350 public ::testing::WithParamInterface<AudioConfig> {
351protected:
352 void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
353 uint64_t bufferSize;
354 ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
355
356 switch (res) {
357 case Result::INVALID_ARGUMENTS:
358 EXPECT_FALSE(supportRequired);
359 break;
360 case Result::OK:
361 // Check that the buffer is of a sane size
362 // For now only that it is > 0
363 EXPECT_GT(bufferSize, uint64_t(0));
364 break;
365 default:
366 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
367 }
368 }
369};
370
371// Test that the required capture config and those declared in the policy are indeed supported
372class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
373TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
374 doc::test("Input buffer size must be retrievable for a format with required support.");
375 inputBufferSizeTest(GetParam(), true);
376}
377INSTANTIATE_TEST_CASE_P(
378 RequiredInputBufferSize, RequiredInputBufferSizeTest,
379 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
380INSTANTIATE_TEST_CASE_P(
381 SupportedInputBufferSize, RequiredInputBufferSizeTest,
382 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
383
384// Test that the recommended capture config are supported or lead to a INVALID_ARGUMENTS return
385class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
386TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
387 doc::test("Input buffer size should be retrievable for a format with recommended support.");
388 inputBufferSizeTest(GetParam(), false);
389}
390INSTANTIATE_TEST_CASE_P(
391 RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
392 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
393
394//////////////////////////////////////////////////////////////////////////////
395/////////////////////////////// setScreenState ///////////////////////////////
396//////////////////////////////////////////////////////////////////////////////
397
398TEST_F(AudioPrimaryHidlTest, setScreenState) {
399 doc::test("Check that the hal can receive the screen state");
400 for (bool turnedOn : {false, true, true, false, false}) {
401 auto ret = device->setScreenState(turnedOn);
402 ASSERT_TRUE(ret.isOk());
403 Result result = ret;
404 ASSERT_TRUE(result == Result::OK || result == Result::NOT_SUPPORTED) << toString(result);
405 }
406}
407
408//////////////////////////////////////////////////////////////////////////////
409//////////////////////////// {get,set}Parameters /////////////////////////////
410//////////////////////////////////////////////////////////////////////////////
411
412TEST_F(AudioPrimaryHidlTest, getParameters) {
413 doc::test("Check that the hal can set and get parameters");
414 hidl_vec<hidl_string> keys;
415 hidl_vec<ParameterValue> values;
416 ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
417 ASSERT_OK(device->setParameters(values));
418 values.resize(0);
419 ASSERT_OK(device->setParameters(values));
420}
421
422//////////////////////////////////////////////////////////////////////////////
423//////////////////////////////// debugDebug //////////////////////////////////
424//////////////////////////////////////////////////////////////////////////////
425
426TEST_F(AudioPrimaryHidlTest, debugDump) {
427 doc::test("Check that the hal can dump its state without error");
428 FILE* file = tmpfile();
429 ASSERT_NE(nullptr, file) << errno;
430
431 auto* nativeHandle = native_handle_create(1, 0);
432 ASSERT_NE(nullptr, nativeHandle);
433 nativeHandle->data[0] = fileno(file);
434
435 hidl_handle handle;
436 handle.setTo(nativeHandle, true /*take ownership*/);
437
438 auto ret = device->debugDump(handle);
439 ASSERT_TRUE(ret.isOk());
440
441 // FIXME: debugDump does not return a Result.
442 // This mean that the hal can not report that it not implementing the function.
443 // As the default hal does not implement debugDump, the function can not be tested.
444 /*
445 res = ret;
446 if (res == Result::NOT_SUPPORTED) {
447 doc::partialTest("debugDump is not implemented");
448 return;
449 }
450 ASSERT_OK(res);
451 rewind(file);
452
453 // Check that at least one bit was written by the hal
454 char buff;
455 ASSERT_EQ(1, fread(&buff, sizeof(buff), 1, file));
456 */
457 EXPECT_EQ(0, fclose(file)) << errno;
458}
459
460//////////////////////////////////////////////////////////////////////////////
461////////////////////////// open{Output,Input}Stream //////////////////////////
462//////////////////////////////////////////////////////////////////////////////
463
464template <class Stream>
465class OpenStreamTest : public AudioConfigPrimaryTest,
466 public ::testing::WithParamInterface<AudioConfig> {
467protected:
468 template <class Open>
469 void testOpen(Open openStream, const AudioConfig& config) {
470 // FIXME: Open a stream without an IOHandle
471 // This is not required to be accepted by hal implementations
472 AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
473 AudioConfig suggestedConfig{};
474 ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
475
476 // TODO: only allow failure for RecommendedPlaybackAudioConfig
477 switch (res) {
478 case Result::OK:
479 ASSERT_TRUE(stream != nullptr);
480 audioConfig = config;
481 break;
482 case Result::INVALID_ARGUMENTS:
483 ASSERT_TRUE(stream == nullptr);
484 AudioConfig suggestedConfigRetry;
485 // Could not open stream with config, try again with the suggested one
486 ASSERT_OK(openStream(ioHandle, suggestedConfig,
487 returnIn(res, stream, suggestedConfigRetry)));
488 // This time it must succeed
489 ASSERT_OK(res);
490 ASSERT_TRUE(stream == nullptr);
491 audioConfig = suggestedConfig;
492 break;
493 default:
494 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
495 }
496 open = true;
497 }
498
499private:
500 void TearDown() override {
501 if (open) {
502 ASSERT_OK(stream->close());
503 }
504 }
505
506protected:
507
508 AudioConfig audioConfig;
509 sp<Stream> stream;
510 bool open = false;
511};
512
513////////////////////////////// openOutputStream //////////////////////////////
514
515class OutputStreamTest : public OpenStreamTest<IStreamOut> {
516 virtual void SetUp() override {
517 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
518
519 const AudioConfig& config = GetParam();
520 DeviceAddress deviceAddr{}; // Ignored by primary hal
521 AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
522 testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
523 { return device->openOutputStream(handle, deviceAddr, config, flags, cb); },
524 config);
525 }
526};
527TEST_P(OutputStreamTest, OpenOutputStreamTest) {
528 doc::test("Check that output streams can be open with the required and recommended config");
529 // Open done in SetUp
530}
531INSTANTIATE_TEST_CASE_P(
532 RequiredOutputStreamConfigSupport, OutputStreamTest,
533 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()));
534INSTANTIATE_TEST_CASE_P(
535 SupportedOutputStreamConfig, OutputStreamTest,
536 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()));
537
538INSTANTIATE_TEST_CASE_P(
539 RecommendedOutputStreamConfigSupport, OutputStreamTest,
540 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()));
541
542////////////////////////////// openInputStream //////////////////////////////
543
544class InputStreamTest : public OpenStreamTest<IStreamIn> {
545
546 virtual void SetUp() override {
547 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
548
549 const AudioConfig& config = GetParam();
550 DeviceAddress deviceAddr{}; // TODO: test all devices
551 AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
552 AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
553 testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
554 { return device->openInputStream(handle, deviceAddr, config, flags, source, cb); },
555 config);
556 }
557};
558
559TEST_P(InputStreamTest, OpenInputStreamTest) {
560 doc::test("Check that input streams can be open with the required and recommended config");
561 // Open done in setup
562}
563INSTANTIATE_TEST_CASE_P(
564 RequiredInputStreamConfigSupport, InputStreamTest,
565 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()));
566INSTANTIATE_TEST_CASE_P(
567 SupportedInputStreamConfig, InputStreamTest,
568 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()));
569
570INSTANTIATE_TEST_CASE_P(
571 RecommendedInputStreamConfigSupport, InputStreamTest,
572 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()));
573
574//////////////////////////////////////////////////////////////////////////////
575////////////////////////////// IStream getters ///////////////////////////////
576//////////////////////////////////////////////////////////////////////////////
577
578/** Unpack the provided result.
579 * If the result is not OK, register a failure and return an undefined value. */
580template <class R>
581static R extract(Return<R> ret) {
582 if (!ret.isOk()) {
583 ADD_FAILURE();
584 return R{};
585 }
586 return ret;
587}
588
589template <class Property, class CapabilityGetter, class Getter, class Setter>
590static void testCapabilityGetter(const string& name,IStream* stream, Property currentValue,
591 CapabilityGetter capablityGetter, Getter getter, Setter setter) {
592 hidl_vec<Property> capabilities;
593 ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
594 if (capabilities.size() == 0) {
595 // The default hal should probably return a NOT_SUPPORTED if the hal does not expose
596 // capability retrieval. For now it returns an empty list if not implemented
597 doc::partialTest(name + " is not supported");
598 return;
599 };
600 // TODO: This code has never been tested on a hal that supports getSupportedSampleRates
601 EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
602 capabilities.end())
603 << "current " << name << " is not in the list of the supported ones "
604 << toString(capabilities);
605
606 // Check that all declared supported values are indeed supported
607 for (auto capability : capabilities) {
608 ASSERT_OK((stream->*setter)(capability));
609 ASSERT_EQ(capability, extract((stream->*getter)()));
610 }
611}
612
613static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
614 uint32_t sampleRateHz;
615 AudioChannelMask mask;
616 AudioFormat format;
617
618 stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
619
620 // FIXME: the qcom hal it does not currently negotiate the sampleRate & channel mask
Kevin Rocardd1e98ae2017-03-08 17:17:25 -0800621 EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
622 EXPECT_EQ(expectedConfig.channelMask, mask);
Kevin Rocardf0357882017-02-10 16:19:28 -0800623 EXPECT_EQ(expectedConfig.format, format);
624}
625
626static void testAccessors(IStream* stream, AudioConfig audioConfig) {
627 doc::test("Test IStream getters and setters that can be called in the stop state");
628
629 auto frameCount = extract(stream->getFrameCount());
630 ASSERT_EQ(audioConfig.frameCount, frameCount);
631
632 auto sampleRate = extract(stream->getSampleRate());
633 // FIXME: the qcom hal it does not currently negotiate the sampleRate
Kevin Rocardd1e98ae2017-03-08 17:17:25 -0800634 ASSERT_EQ(audioConfig.sampleRateHz, sampleRate);
Kevin Rocardf0357882017-02-10 16:19:28 -0800635
636 auto channelMask = extract(stream->getChannelMask());
637 // FIXME: the qcom hal it does not currently negotiate the channelMask
Kevin Rocardd1e98ae2017-03-08 17:17:25 -0800638 ASSERT_EQ(audioConfig.channelMask, channelMask);
Kevin Rocardf0357882017-02-10 16:19:28 -0800639
640 auto frameSize = extract(stream->getFrameSize());
641 ASSERT_GE(frameSize, 0U);
642
643 auto bufferSize = extract(stream->getBufferSize());
644 ASSERT_GE(bufferSize, frameSize);
645
646 testCapabilityGetter("getSupportedsampleRate", stream, sampleRate,
647 &IStream::getSupportedSampleRates,
648 &IStream::getSampleRate, &IStream::setSampleRate);
649
650 testCapabilityGetter("getSupportedChannelMask", stream, channelMask,
651 &IStream::getSupportedChannelMasks,
652 &IStream::getChannelMask, &IStream::setChannelMask);
653
654 AudioFormat format = extract(stream->getFormat());
655 ASSERT_EQ(audioConfig.format, format);
656
657 testCapabilityGetter("getSupportedFormats", stream, format,
658 &IStream::getSupportedFormats, &IStream::getFormat, &IStream::setFormat);
659
660 testGetAudioProperties(stream, audioConfig);
661
Kevin Rocardfd067c32017-03-08 16:43:29 -0800662 auto ret = stream->getDevice();
663 ASSERT_TRUE(ret.isOk());
664 AudioDevice device = ret;
665 ASSERT_EQ(AudioDevice::OUT_DEFAULT, device);
Kevin Rocardf0357882017-02-10 16:19:28 -0800666}
667
668TEST_P(InputStreamTest, GettersTest) {
669 testAccessors(stream.get(), audioConfig);
670}
671TEST_P(OutputStreamTest, GettersTest) {
672 testAccessors(stream.get(), audioConfig);
673}
674
675//////////////////////////////////////////////////////////////////////////////
676//////////////////////////////// AudioPatches ////////////////////////////////
677//////////////////////////////////////////////////////////////////////////////
678
679
680TEST_F(AudioPrimaryHidlTest, AudioPatches) {
681 doc::test("Test if audio patches are supported");
682 auto result = device->supportsAudioPatches();
683 ASSERT_TRUE(result.isOk());
684 bool supportsAudioPatch = result;
685 if (!supportsAudioPatch) {
686 doc::partialTest("Audio patches are not supported");
687 return;
688 }
689 // TODO: test audio patches
690}
691
692//////////////////////////////////////////////////////////////////////////////
693//////////////////// Clean caches on global tear down ////////////////////////
694//////////////////////////////////////////////////////////////////////////////
695
696int main(int argc, char** argv) {
697 environment = new Environment;
698 ::testing::AddGlobalTestEnvironment(environment);
699 ::testing::InitGoogleTest(&argc, argv);
700 int status = RUN_ALL_TESTS();
701 LOG(INFO) << "Test result = " << status;
702 return status;
703}