OSDN Git Service

Merge "Vts AudioDec Test: Disable EOSTest_M" into oc-dev
[android-x86/hardware-interfaces.git] / audio / 2.0 / vts / functional / AudioPrimaryHidlHalTest.cpp
1 /*
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 <string>
25 #include <vector>
26
27 #include <VtsHalHidlTargetTestBase.h>
28
29 #include <android-base/logging.h>
30
31 #include <android/hardware/audio/2.0/IDevice.h>
32 #include <android/hardware/audio/2.0/IDevicesFactory.h>
33 #include <android/hardware/audio/2.0/IPrimaryDevice.h>
34 #include <android/hardware/audio/2.0/types.h>
35 #include <android/hardware/audio/common/2.0/types.h>
36
37 #include "utility/AssertOk.h"
38 #include "utility/Documentation.h"
39 #include "utility/EnvironmentTearDown.h"
40 #include "utility/PrettyPrintAudioTypes.h"
41 #include "utility/ReturnIn.h"
42
43 using std::string;
44 using std::to_string;
45 using std::vector;
46
47 using ::android::sp;
48 using ::android::hardware::Return;
49 using ::android::hardware::hidl_handle;
50 using ::android::hardware::hidl_string;
51 using ::android::hardware::hidl_vec;
52 using ::android::hardware::MQDescriptorSync;
53 using ::android::hardware::audio::V2_0::AudioDrain;
54 using ::android::hardware::audio::V2_0::DeviceAddress;
55 using ::android::hardware::audio::V2_0::IDevice;
56 using ::android::hardware::audio::V2_0::IPrimaryDevice;
57 using TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode;
58 using ::android::hardware::audio::V2_0::IDevicesFactory;
59 using ::android::hardware::audio::V2_0::IStream;
60 using ::android::hardware::audio::V2_0::IStreamIn;
61 using ::android::hardware::audio::V2_0::TimeSpec;
62 using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
63 using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
64 using ::android::hardware::audio::V2_0::IStreamOut;
65 using ::android::hardware::audio::V2_0::IStreamOutCallback;
66 using ::android::hardware::audio::V2_0::MmapBufferInfo;
67 using ::android::hardware::audio::V2_0::MmapPosition;
68 using ::android::hardware::audio::V2_0::ParameterValue;
69 using ::android::hardware::audio::V2_0::Result;
70 using ::android::hardware::audio::common::V2_0::AudioChannelMask;
71 using ::android::hardware::audio::common::V2_0::AudioConfig;
72 using ::android::hardware::audio::common::V2_0::AudioDevice;
73 using ::android::hardware::audio::common::V2_0::AudioFormat;
74 using ::android::hardware::audio::common::V2_0::AudioHandleConsts;
75 using ::android::hardware::audio::common::V2_0::AudioInputFlag;
76 using ::android::hardware::audio::common::V2_0::AudioIoHandle;
77 using ::android::hardware::audio::common::V2_0::AudioMode;
78 using ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
79 using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
80 using ::android::hardware::audio::common::V2_0::AudioSource;
81 using ::android::hardware::audio::common::V2_0::ThreadInfo;
82
83 using namespace ::android::hardware::audio::common::test::utility;
84
85 // Instance to register global tearDown
86 static Environment* environment;
87
88 class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
89    protected:
90     // Convenient member to store results
91     Result res;
92 };
93
94 //////////////////////////////////////////////////////////////////////////////
95 ////////////////////// getService audio_devices_factory //////////////////////
96 //////////////////////////////////////////////////////////////////////////////
97
98 // Test all audio devices
99 class AudioHidlTest : public HidlTest {
100    public:
101     void SetUp() override {
102         ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
103
104         if (devicesFactory == nullptr) {
105             environment->registerTearDown([] { devicesFactory.clear(); });
106             devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<
107                 IDevicesFactory>();
108         }
109         ASSERT_TRUE(devicesFactory != nullptr);
110     }
111
112    protected:
113     // Cache the devicesFactory retrieval to speed up each test by ~0.5s
114     static sp<IDevicesFactory> devicesFactory;
115 };
116 sp<IDevicesFactory> AudioHidlTest::devicesFactory;
117
118 TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
119     doc::test("test the getService (called in SetUp)");
120 }
121
122 TEST_F(AudioHidlTest, OpenDeviceInvalidParameter) {
123     doc::test("test passing an invalid parameter to openDevice");
124     IDevicesFactory::Result result;
125     sp<IDevice> device;
126     ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device(-1),
127                                          returnIn(result, device)));
128     ASSERT_EQ(IDevicesFactory::Result::INVALID_ARGUMENTS, result);
129     ASSERT_TRUE(device == nullptr);
130 }
131
132 //////////////////////////////////////////////////////////////////////////////
133 /////////////////////////////// openDevice primary ///////////////////////////
134 //////////////////////////////////////////////////////////////////////////////
135
136 // Test the primary device
137 class AudioPrimaryHidlTest : public AudioHidlTest {
138    public:
139     /** Primary HAL test are NOT thread safe. */
140     void SetUp() override {
141         ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
142
143         if (device == nullptr) {
144             IDevicesFactory::Result result;
145             sp<IDevice> baseDevice;
146             ASSERT_OK(
147                 devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
148                                            returnIn(result, baseDevice)));
149             ASSERT_OK(result);
150             ASSERT_TRUE(baseDevice != nullptr);
151
152             environment->registerTearDown([] { device.clear(); });
153             device = IPrimaryDevice::castFrom(baseDevice);
154             ASSERT_TRUE(device != nullptr);
155         }
156     }
157
158    protected:
159     // Cache the device opening to speed up each test by ~0.5s
160     static sp<IPrimaryDevice> device;
161 };
162 sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
163
164 TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
165     doc::test("Test the openDevice (called in SetUp)");
166 }
167
168 TEST_F(AudioPrimaryHidlTest, Init) {
169     doc::test("Test that the audio primary hal initialized correctly");
170     ASSERT_OK(device->initCheck());
171 }
172
173 //////////////////////////////////////////////////////////////////////////////
174 ///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
175 //////////////////////////////////////////////////////////////////////////////
176
177 template <class Property>
178 class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
179    protected:
180     /** Test a property getter and setter. */
181     template <class Getter, class Setter>
182     void testAccessors(const string& propertyName,
183                        const vector<Property>& valuesToTest, Setter setter,
184                        Getter getter,
185                        const vector<Property>& invalidValues = {}) {
186         Property initialValue;  // Save initial value to restore it at the end
187                                 // of the test
188         ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
189         ASSERT_OK(res);
190
191         for (Property setValue : valuesToTest) {
192             SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
193                          testing::PrintToString(setValue));
194             ASSERT_OK((device.get()->*setter)(setValue));
195             Property getValue;
196             // Make sure the getter returns the same value just set
197             ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
198             ASSERT_OK(res);
199             EXPECT_EQ(setValue, getValue);
200         }
201
202         for (Property invalidValue : invalidValues) {
203             SCOPED_TRACE("Try to set " + propertyName +
204                          " with the invalid value " +
205                          testing::PrintToString(invalidValue));
206             EXPECT_RESULT(Result::INVALID_ARGUMENTS,
207                           (device.get()->*setter)(invalidValue));
208         }
209
210         ASSERT_OK(
211             (device.get()->*setter)(initialValue));  // restore initial value
212     }
213
214     /** Test the getter and setter of an optional feature. */
215     template <class Getter, class Setter>
216     void testOptionalAccessors(const string& propertyName,
217                                const vector<Property>& valuesToTest,
218                                Setter setter, Getter getter,
219                                const vector<Property>& invalidValues = {}) {
220         doc::test("Test the optional " + propertyName + " getters and setter");
221         {
222             SCOPED_TRACE("Test feature support by calling the getter");
223             Property initialValue;
224             ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
225             if (res == Result::NOT_SUPPORTED) {
226                 doc::partialTest(propertyName + " getter is not supported");
227                 return;
228             }
229             ASSERT_OK(res);  // If it is supported it must succeed
230         }
231         // The feature is supported, test it
232         testAccessors(propertyName, valuesToTest, setter, getter,
233                       invalidValues);
234     }
235 };
236
237 using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
238
239 TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
240     doc::test("Check that the mic can be muted and unmuted");
241     testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute,
242                   &IDevice::getMicMute);
243     // TODO: check that the mic is really muted (all sample are 0)
244 }
245
246 TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
247     doc::test(
248         "If master mute is supported, try to mute and unmute the master "
249         "output");
250     testOptionalAccessors("master mute", {true, false, true},
251                           &IDevice::setMasterMute, &IDevice::getMasterMute);
252     // TODO: check that the master volume is really muted
253 }
254
255 using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
256 TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
257     doc::test("Test the master volume if supported");
258     testOptionalAccessors("master volume", {0, 0.5, 1},
259                           &IDevice::setMasterVolume, &IDevice::getMasterVolume,
260                           {-0.1, 1.1, NAN, INFINITY, -INFINITY,
261                            1 + std::numeric_limits<float>::epsilon()});
262     // TODO: check that the master volume is really changed
263 }
264
265 //////////////////////////////////////////////////////////////////////////////
266 //////////////////////////////// AudioPatches ////////////////////////////////
267 //////////////////////////////////////////////////////////////////////////////
268
269 class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
270    protected:
271     bool areAudioPatchesSupported() {
272         auto result = device->supportsAudioPatches();
273         EXPECT_IS_OK(result);
274         return result;
275     }
276 };
277
278 TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
279     doc::test("Test if audio patches are supported");
280     if (!areAudioPatchesSupported()) {
281         doc::partialTest("Audio patches are not supported");
282         return;
283     }
284     // TODO: test audio patches
285 }
286
287 //////////////////////////////////////////////////////////////////////////////
288 //////////////// Required and recommended audio format support ///////////////
289 // From:
290 // https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
291 // From:
292 // https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
293 /////////// TODO: move to the beginning of the file for easier update ////////
294 //////////////////////////////////////////////////////////////////////////////
295
296 class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
297    public:
298     // Cache result ?
299     static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
300         return combineAudioConfig(
301             {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
302             {8000, 11025, 16000, 22050, 32000, 44100},
303             {AudioFormat::PCM_16_BIT});
304     }
305
306     static const vector<AudioConfig>
307     getRecommendedSupportPlaybackAudioConfig() {
308         return combineAudioConfig(
309             {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
310             {24000, 48000}, {AudioFormat::PCM_16_BIT});
311     }
312
313     static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
314         // TODO: retrieve audio config supported by the platform
315         // as declared in the policy configuration
316         return {};
317     }
318
319     static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
320         return combineAudioConfig({AudioChannelMask::IN_MONO},
321                                   {8000, 11025, 16000, 44100},
322                                   {AudioFormat::PCM_16_BIT});
323     }
324     static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
325         return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
326                                   {AudioFormat::PCM_16_BIT});
327     }
328     static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
329         // TODO: retrieve audio config supported by the platform
330         // as declared in the policy configuration
331         return {};
332     }
333
334    private:
335     static const vector<AudioConfig> combineAudioConfig(
336         vector<AudioChannelMask> channelMasks, vector<uint32_t> sampleRates,
337         vector<AudioFormat> formats) {
338         vector<AudioConfig> configs;
339         for (auto channelMask : channelMasks) {
340             for (auto sampleRate : sampleRates) {
341                 for (auto format : formats) {
342                     AudioConfig config{};
343                     // leave offloadInfo to 0
344                     config.channelMask = channelMask;
345                     config.sampleRateHz = sampleRate;
346                     config.format = format;
347                     // FIXME: leave frameCount to 0 ?
348                     configs.push_back(config);
349                 }
350             }
351         }
352         return configs;
353     }
354 };
355
356 /** Generate a test name based on an audio config.
357  *
358  * As the only parameter changing are channel mask and sample rate,
359  * only print those ones in the test name.
360  */
361 static string generateTestName(
362     const testing::TestParamInfo<AudioConfig>& info) {
363     const AudioConfig& config = info.param;
364     return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
365            // "MONO" is more clear than "FRONT_LEFT"
366            ((config.channelMask == AudioChannelMask::OUT_MONO ||
367              config.channelMask == AudioChannelMask::IN_MONO)
368                 ? "MONO"
369                 : toString(config.channelMask));
370 }
371
372 //////////////////////////////////////////////////////////////////////////////
373 ///////////////////////////// getInputBufferSize /////////////////////////////
374 //////////////////////////////////////////////////////////////////////////////
375
376 // FIXME: execute input test only if platform declares
377 // android.hardware.microphone
378 //        how to get this value ? is it a property ???
379
380 class AudioCaptureConfigPrimaryTest
381     : public AudioConfigPrimaryTest,
382       public ::testing::WithParamInterface<AudioConfig> {
383    protected:
384     void inputBufferSizeTest(const AudioConfig& audioConfig,
385                              bool supportRequired) {
386         uint64_t bufferSize;
387         ASSERT_OK(
388             device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
389
390         switch (res) {
391             case Result::INVALID_ARGUMENTS:
392                 EXPECT_FALSE(supportRequired);
393                 break;
394             case Result::OK:
395                 // Check that the buffer is of a sane size
396                 // For now only that it is > 0
397                 EXPECT_GT(bufferSize, uint64_t(0));
398                 break;
399             default:
400                 FAIL() << "Invalid return status: "
401                        << ::testing::PrintToString(res);
402         }
403     }
404 };
405
406 // Test that the required capture config and those declared in the policy are
407 // indeed supported
408 class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
409 TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
410     doc::test(
411         "Input buffer size must be retrievable for a format with required "
412         "support.");
413     inputBufferSizeTest(GetParam(), true);
414 }
415 INSTANTIATE_TEST_CASE_P(
416     RequiredInputBufferSize, RequiredInputBufferSizeTest,
417     ::testing::ValuesIn(
418         AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
419     &generateTestName);
420 INSTANTIATE_TEST_CASE_P(
421     SupportedInputBufferSize, RequiredInputBufferSizeTest,
422     ::testing::ValuesIn(
423         AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
424     &generateTestName);
425
426 // Test that the recommended capture config are supported or lead to a
427 // INVALID_ARGUMENTS return
428 class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
429 TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
430     doc::test(
431         "Input buffer size should be retrievable for a format with recommended "
432         "support.");
433     inputBufferSizeTest(GetParam(), false);
434 }
435 INSTANTIATE_TEST_CASE_P(
436     RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
437     ::testing::ValuesIn(
438         AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
439     &generateTestName);
440
441 //////////////////////////////////////////////////////////////////////////////
442 /////////////////////////////// setScreenState ///////////////////////////////
443 //////////////////////////////////////////////////////////////////////////////
444
445 TEST_F(AudioPrimaryHidlTest, setScreenState) {
446     doc::test("Check that the hal can receive the screen state");
447     for (bool turnedOn : {false, true, true, false, false}) {
448         auto ret = device->setScreenState(turnedOn);
449         ASSERT_IS_OK(ret);
450         Result result = ret;
451         auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
452         ASSERT_RESULT(okOrNotSupported, result);
453     }
454 }
455
456 //////////////////////////////////////////////////////////////////////////////
457 //////////////////////////// {get,set}Parameters /////////////////////////////
458 //////////////////////////////////////////////////////////////////////////////
459
460 TEST_F(AudioPrimaryHidlTest, getParameters) {
461     doc::test("Check that the hal can set and get parameters");
462     hidl_vec<hidl_string> keys;
463     hidl_vec<ParameterValue> values;
464     ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
465     ASSERT_OK(device->setParameters(values));
466     values.resize(0);
467     ASSERT_OK(device->setParameters(values));
468 }
469
470 //////////////////////////////////////////////////////////////////////////////
471 //////////////////////////////// debugDebug //////////////////////////////////
472 //////////////////////////////////////////////////////////////////////////////
473
474 template <class DebugDump>
475 static void testDebugDump(DebugDump debugDump) {
476     // Dump in a temporary file
477     // Note that SELinux must be deactivate for this test to work
478     FILE* file = tmpfile();
479     ASSERT_NE(nullptr, file) << errno;
480
481     // Wrap the temporary file file descriptor in a native handle
482     auto* nativeHandle = native_handle_create(1, 0);
483     ASSERT_NE(nullptr, nativeHandle);
484     nativeHandle->data[0] = fileno(file);
485
486     // Wrap this native handle in a hidl handle
487     hidl_handle handle;
488     handle.setTo(nativeHandle, true /*take ownership*/);
489
490     ASSERT_OK(debugDump(handle));
491
492     // Check that at least one bit was written by the hal
493     // TODO: debugDump does not return a Result.
494     // This mean that the hal can not report that it not implementing the
495     // function.
496     rewind(file);  // can not fail
497     char buff;
498     if (fread(&buff, sizeof(buff), 1, file) != 1) {
499         doc::note("debugDump does not seem implemented");
500     }
501     EXPECT_EQ(0, fclose(file)) << errno;
502 }
503
504 TEST_F(AudioPrimaryHidlTest, DebugDump) {
505     doc::test("Check that the hal can dump its state without error");
506     testDebugDump([](const auto& handle) { return device->debugDump(handle); });
507 }
508
509 TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
510     doc::test("Check that the hal dump doesn't crash on invalid arguments");
511     ASSERT_OK(device->debugDump(hidl_handle()));
512 }
513
514 //////////////////////////////////////////////////////////////////////////////
515 ////////////////////////// open{Output,Input}Stream //////////////////////////
516 //////////////////////////////////////////////////////////////////////////////
517
518 template <class Stream>
519 class OpenStreamTest : public AudioConfigPrimaryTest,
520                        public ::testing::WithParamInterface<AudioConfig> {
521    protected:
522     template <class Open>
523     void testOpen(Open openStream, const AudioConfig& config) {
524         // FIXME: Open a stream without an IOHandle
525         //        This is not required to be accepted by hal implementations
526         AudioIoHandle ioHandle =
527             (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
528         AudioConfig suggestedConfig{};
529         ASSERT_OK(openStream(ioHandle, config,
530                              returnIn(res, stream, suggestedConfig)));
531
532         // TODO: only allow failure for RecommendedPlaybackAudioConfig
533         switch (res) {
534             case Result::OK:
535                 ASSERT_TRUE(stream != nullptr);
536                 audioConfig = config;
537                 break;
538             case Result::INVALID_ARGUMENTS:
539                 ASSERT_TRUE(stream == nullptr);
540                 AudioConfig suggestedConfigRetry;
541                 // Could not open stream with config, try again with the
542                 // suggested one
543                 ASSERT_OK(
544                     openStream(ioHandle, suggestedConfig,
545                                returnIn(res, stream, suggestedConfigRetry)));
546                 // This time it must succeed
547                 ASSERT_OK(res);
548                 ASSERT_TRUE(stream != nullptr);
549                 audioConfig = suggestedConfig;
550                 break;
551             default:
552                 FAIL() << "Invalid return status: "
553                        << ::testing::PrintToString(res);
554         }
555         open = true;
556     }
557
558     Return<Result> closeStream() {
559         open = false;
560         return stream->close();
561     }
562
563    private:
564     void TearDown() override {
565         if (open) {
566             ASSERT_OK(stream->close());
567         }
568     }
569
570    protected:
571     AudioConfig audioConfig;
572     DeviceAddress address = {};
573     sp<Stream> stream;
574     bool open = false;
575 };
576
577 ////////////////////////////// openOutputStream //////////////////////////////
578
579 class OutputStreamTest : public OpenStreamTest<IStreamOut> {
580     virtual void SetUp() override {
581         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
582         address.device = AudioDevice::OUT_DEFAULT;
583         const AudioConfig& config = GetParam();
584         AudioOutputFlag flags =
585             AudioOutputFlag::NONE;  // TODO: test all flag combination
586         testOpen(
587             [&](AudioIoHandle handle, AudioConfig config, auto cb) {
588                 return device->openOutputStream(handle, address, config, flags,
589                                                 cb);
590             },
591             config);
592     }
593 };
594 TEST_P(OutputStreamTest, OpenOutputStreamTest) {
595     doc::test(
596         "Check that output streams can be open with the required and "
597         "recommended config");
598     // Open done in SetUp
599 }
600 INSTANTIATE_TEST_CASE_P(
601     RequiredOutputStreamConfigSupport, OutputStreamTest,
602     ::testing::ValuesIn(
603         AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
604     &generateTestName);
605 INSTANTIATE_TEST_CASE_P(
606     SupportedOutputStreamConfig, OutputStreamTest,
607     ::testing::ValuesIn(
608         AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
609     &generateTestName);
610
611 INSTANTIATE_TEST_CASE_P(
612     RecommendedOutputStreamConfigSupport, OutputStreamTest,
613     ::testing::ValuesIn(
614         AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
615     &generateTestName);
616
617 ////////////////////////////// openInputStream //////////////////////////////
618
619 class InputStreamTest : public OpenStreamTest<IStreamIn> {
620     virtual void SetUp() override {
621         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
622         address.device = AudioDevice::IN_DEFAULT;
623         const AudioConfig& config = GetParam();
624         AudioInputFlag flags =
625             AudioInputFlag::NONE;  // TODO: test all flag combination
626         AudioSource source =
627             AudioSource::DEFAULT;  // TODO: test all flag combination
628         testOpen(
629             [&](AudioIoHandle handle, AudioConfig config, auto cb) {
630                 return device->openInputStream(handle, address, config, flags,
631                                                source, cb);
632             },
633             config);
634     }
635 };
636
637 TEST_P(InputStreamTest, OpenInputStreamTest) {
638     doc::test(
639         "Check that input streams can be open with the required and "
640         "recommended config");
641     // Open done in setup
642 }
643 INSTANTIATE_TEST_CASE_P(
644     RequiredInputStreamConfigSupport, InputStreamTest,
645     ::testing::ValuesIn(
646         AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
647     &generateTestName);
648 INSTANTIATE_TEST_CASE_P(
649     SupportedInputStreamConfig, InputStreamTest,
650     ::testing::ValuesIn(
651         AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
652     &generateTestName);
653
654 INSTANTIATE_TEST_CASE_P(
655     RecommendedInputStreamConfigSupport, InputStreamTest,
656     ::testing::ValuesIn(
657         AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
658     &generateTestName);
659
660 //////////////////////////////////////////////////////////////////////////////
661 ////////////////////////////// IStream getters ///////////////////////////////
662 //////////////////////////////////////////////////////////////////////////////
663
664 /** Unpack the provided result.
665  * If the result is not OK, register a failure and return an undefined value. */
666 template <class R>
667 static R extract(Return<R> ret) {
668     if (!ret.isOk()) {
669         EXPECT_IS_OK(ret);
670         return R{};
671     }
672     return ret;
673 }
674
675 /* Could not find a way to write a test for two parametrized class fixure
676  * thus use this macro do duplicate tests for Input and Output stream */
677 #define TEST_IO_STREAM(test_name, documentation, code) \
678     TEST_P(InputStreamTest, test_name) {               \
679         doc::test(documentation);                      \
680         code;                                          \
681     }                                                  \
682     TEST_P(OutputStreamTest, test_name) {              \
683         doc::test(documentation);                      \
684         code;                                          \
685     }
686
687 TEST_IO_STREAM(
688     GetFrameCount,
689     "Check that the stream frame count == the one it was opened with",
690     ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
691
692 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
693                ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
694
695 TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
696                ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
697
698 TEST_IO_STREAM(GetFormat,
699                "Check that the stream format == the one it was opened with",
700                ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
701
702 // TODO: for now only check that the framesize is not incoherent
703 TEST_IO_STREAM(GetFrameSize,
704                "Check that the stream frame size == the one it was opened with",
705                ASSERT_GT(extract(stream->getFrameSize()), 0U))
706
707 TEST_IO_STREAM(GetBufferSize,
708                "Check that the stream buffer size== the one it was opened with",
709                ASSERT_GE(extract(stream->getBufferSize()),
710                          extract(stream->getFrameSize())));
711
712 template <class Property, class CapabilityGetter, class Getter, class Setter>
713 static void testCapabilityGetter(const string& name, IStream* stream,
714                                  Property currentValue,
715                                  CapabilityGetter capablityGetter,
716                                  Getter getter, Setter setter) {
717     hidl_vec<Property> capabilities;
718     ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
719     if (capabilities.size() == 0) {
720         // The default hal should probably return a NOT_SUPPORTED if the hal
721         // does not expose
722         // capability retrieval. For now it returns an empty list if not
723         // implemented
724         doc::partialTest(name + " is not supported");
725         return;
726     };
727     // TODO: This code has never been tested on a hal that supports
728     // getSupportedSampleRates
729     EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
730               capabilities.end())
731         << "current " << name << " is not in the list of the supported ones "
732         << toString(capabilities);
733
734     // Check that all declared supported values are indeed supported
735     for (auto capability : capabilities) {
736         ASSERT_OK((stream->*setter)(capability));
737         ASSERT_EQ(capability, extract((stream->*getter)()));
738     }
739 }
740
741 TEST_IO_STREAM(SupportedSampleRate,
742                "Check that the stream sample rate is declared as supported",
743                testCapabilityGetter("getSupportedSampleRate", stream.get(),
744                                     extract(stream->getSampleRate()),
745                                     &IStream::getSupportedSampleRates,
746                                     &IStream::getSampleRate,
747                                     &IStream::setSampleRate))
748
749 TEST_IO_STREAM(SupportedChannelMask,
750                "Check that the stream channel mask is declared as supported",
751                testCapabilityGetter("getSupportedChannelMask", stream.get(),
752                                     extract(stream->getChannelMask()),
753                                     &IStream::getSupportedChannelMasks,
754                                     &IStream::getChannelMask,
755                                     &IStream::setChannelMask))
756
757 TEST_IO_STREAM(SupportedFormat,
758                "Check that the stream format is declared as supported",
759                testCapabilityGetter("getSupportedFormat", stream.get(),
760                                     extract(stream->getFormat()),
761                                     &IStream::getSupportedFormats,
762                                     &IStream::getFormat, &IStream::setFormat))
763
764 static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
765     // Unfortunately the interface does not allow the implementation to return
766     // NOT_SUPPORTED
767     // Thus allow NONE as signaling that the call is not supported.
768     auto ret = stream->getDevice();
769     ASSERT_IS_OK(ret);
770     AudioDevice device = ret;
771     ASSERT_TRUE(device == expectedDevice || device == AudioDevice::NONE)
772         << "Expected: " << ::testing::PrintToString(expectedDevice)
773         << "\n  Actual: " << ::testing::PrintToString(device);
774 }
775
776 TEST_IO_STREAM(GetDevice,
777                "Check that the stream device == the one it was opened with",
778                areAudioPatchesSupported()
779                    ? doc::partialTest("Audio patches are supported")
780                    : testGetDevice(stream.get(), address.device))
781
782 static void testSetDevice(IStream* stream, const DeviceAddress& address) {
783     DeviceAddress otherAddress = address;
784     otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0
785                               ? AudioDevice::OUT_SPEAKER
786                               : AudioDevice::IN_BUILTIN_MIC;
787     EXPECT_OK(stream->setDevice(otherAddress));
788
789     ASSERT_OK(stream->setDevice(address));  // Go back to the original value
790 }
791
792 TEST_IO_STREAM(
793     SetDevice,
794     "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
795     areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
796                                : testSetDevice(stream.get(), address))
797
798 static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
799     uint32_t sampleRateHz;
800     AudioChannelMask mask;
801     AudioFormat format;
802
803     stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
804
805     // FIXME: the qcom hal it does not currently negotiate the sampleRate &
806     // channel mask
807     EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
808     EXPECT_EQ(expectedConfig.channelMask, mask);
809     EXPECT_EQ(expectedConfig.format, format);
810 }
811
812 TEST_IO_STREAM(GetAudioProperties,
813                "Check that the stream audio properties == the ones it was opened with",
814                testGetAudioProperties(stream.get(), audioConfig))
815
816 static void testConnectedState(IStream* stream) {
817     DeviceAddress address = {};
818     using AD = AudioDevice;
819     for (auto device :
820          {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
821         address.device = device;
822
823         ASSERT_OK(stream->setConnectedState(address, true));
824         ASSERT_OK(stream->setConnectedState(address, false));
825     }
826 }
827 TEST_IO_STREAM(SetConnectedState,
828                "Check that the stream can be notified of device connection and "
829                "deconnection",
830                testConnectedState(stream.get()))
831
832 static auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS,
833                                              Result::NOT_SUPPORTED, Result::OK};
834 TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
835                ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
836                              stream->setHwAvSync(666)))
837
838 TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
839                ASSERT_IS_OK(device->getHwAvSync()));
840
841 static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
842                                 vector<Result> expectedResults) {
843     hidl_vec<ParameterValue> parameters;
844     Result res;
845     ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
846     ASSERT_RESULT(expectedResults, res);
847     if (res == Result::OK) {
848         for (auto& parameter : parameters) {
849             ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
850         }
851     }
852 }
853
854 /* Get/Set parameter is intended to be an opaque channel between vendors app and
855  * their HALs.
856  * Thus can not be meaningfully tested.
857  */
858 TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
859                checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
860
861 TEST_IO_STREAM(getNonExistingParameter,
862                "Retrieve the values of an non existing parameter",
863                checkGetNoParameter(stream.get(),
864                                    {"Non existing key"} /* keys */,
865                                    {Result::NOT_SUPPORTED}))
866
867 TEST_IO_STREAM(setEmptySetParameter,
868                "Set the values of an empty set of parameters",
869                ASSERT_RESULT(Result::OK, stream->setParameters({})))
870
871 TEST_IO_STREAM(
872     setNonExistingParameter, "Set the values of an non existing parameter",
873     // Unfortunately, the set_parameter legacy interface did not return any
874     // error code when a key is not supported.
875     // To allow implementation to just wrapped the legacy one, consider OK as a
876     // valid result for setting a non existing parameter.
877     ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
878                   stream->setParameters({{"non existing key", "0"}})))
879
880 TEST_IO_STREAM(DebugDump,
881                "Check that a stream can dump its state without error",
882                testDebugDump([this](const auto& handle) {
883                    return stream->debugDump(handle);
884                }))
885
886 TEST_IO_STREAM(DebugDumpInvalidArguments,
887                "Check that the stream dump doesn't crash on invalid arguments",
888                ASSERT_OK(stream->debugDump(hidl_handle())))
889
890 //////////////////////////////////////////////////////////////////////////////
891 ////////////////////////////// addRemoveEffect ///////////////////////////////
892 //////////////////////////////////////////////////////////////////////////////
893
894 TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
895                ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
896 TEST_IO_STREAM(RemoveNonExistingEffect,
897                "Removing a non existing effect should fail",
898                ASSERT_RESULT(Result::INVALID_ARGUMENTS,
899                              stream->removeEffect(666)))
900
901 // TODO: positive tests
902
903 //////////////////////////////////////////////////////////////////////////////
904 /////////////////////////////// Control ////////////////////////////////
905 //////////////////////////////////////////////////////////////////////////////
906
907 TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
908                ASSERT_OK(stream->standby()))  // can not fail
909
910 static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE,
911                                                     Result::NOT_SUPPORTED};
912
913 TEST_IO_STREAM(startNoMmap,
914                "Starting a mmaped stream before mapping it should fail",
915                ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
916
917 TEST_IO_STREAM(stopNoMmap,
918                "Stopping a mmaped stream before mapping it should fail",
919                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
920
921 TEST_IO_STREAM(getMmapPositionNoMmap,
922                "Get a stream Mmap position before mapping it should fail",
923                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
924
925 TEST_IO_STREAM(close, "Make sure a stream can be closed",
926                ASSERT_OK(closeStream()))
927 TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
928                ASSERT_OK(closeStream());
929                ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
930
931 static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS,
932                                          Result::NOT_SUPPORTED};
933 static void testCreateTooBigMmapBuffer(IStream* stream) {
934     MmapBufferInfo info;
935     Result res;
936     // Assume that int max is a value too big to be allocated
937     // This is true currently with a 32bit media server, but might not when it
938     // will run in 64 bit
939     auto minSizeFrames = std::numeric_limits<int32_t>::max();
940     ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
941     ASSERT_RESULT(invalidArgsOrNotSupported, res);
942 }
943
944 TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
945                testCreateTooBigMmapBuffer(stream.get()))
946
947 static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
948     Result res;
949     MmapPosition position;
950     ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
951     ASSERT_RESULT(invalidArgsOrNotSupported, res);
952 }
953
954 TEST_IO_STREAM(
955     GetMmapPositionOfNonMmapedStream,
956     "Retrieving the mmap position of a non mmaped stream should fail",
957     testGetMmapPositionOfNonMmapedStream(stream.get()))
958
959 //////////////////////////////////////////////////////////////////////////////
960 ///////////////////////////////// StreamIn ///////////////////////////////////
961 //////////////////////////////////////////////////////////////////////////////
962
963 TEST_P(InputStreamTest, GetAudioSource) {
964     doc::test(
965         "Retrieving the audio source of an input stream should always succeed");
966     AudioSource source;
967     ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
968     if (res == Result::NOT_SUPPORTED) {
969         doc::partialTest("getAudioSource is not supported");
970         return;
971     }
972     ASSERT_OK(res);
973     ASSERT_EQ(AudioSource::DEFAULT, source);
974 }
975
976 static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
977     for (float value :
978          (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(),
979                    2.0, INFINITY, NAN}) {
980         EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value="
981                                                                  << value;
982     }
983     // Do not consider -0.0 as an invalid value as it is == with 0.0
984     for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
985         EXPECT_OK(setGain(value)) << "value=" << value;
986     }
987 }
988
989 static void testOptionalUnitaryGain(
990     std::function<Return<Result>(float)> setGain, string debugName) {
991     auto result = setGain(1);
992     ASSERT_IS_OK(result);
993     if (result == Result::NOT_SUPPORTED) {
994         doc::partialTest(debugName + " is not supported");
995         return;
996     }
997     testUnitaryGain(setGain);
998 }
999
1000 TEST_P(InputStreamTest, SetGain) {
1001     doc::test("The gain of an input stream should only be set between [0,1]");
1002     testOptionalUnitaryGain(
1003         [this](float volume) { return stream->setGain(volume); },
1004         "InputStream::setGain");
1005 }
1006
1007 static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize,
1008                                   uint32_t framesCount) {
1009     Result res;
1010     // Ignore output parameters as the call should fail
1011     ASSERT_OK(stream->prepareForReading(
1012         frameSize, framesCount,
1013         [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1014     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1015 }
1016
1017 TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
1018     doc::test(
1019         "Preparing a stream for reading with a 0 sized buffer should fail");
1020     testPrepareForReading(stream.get(), 0, 0);
1021 }
1022
1023 TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
1024     doc::test(
1025         "Preparing a stream for reading with a 2^32 sized buffer should fail");
1026     testPrepareForReading(stream.get(), 1,
1027                           std::numeric_limits<uint32_t>::max());
1028 }
1029
1030 TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
1031     doc::test(
1032         "Preparing a stream for reading with a overflowing sized buffer should "
1033         "fail");
1034     auto uintMax = std::numeric_limits<uint32_t>::max();
1035     testPrepareForReading(stream.get(), uintMax, uintMax);
1036 }
1037
1038 TEST_P(InputStreamTest, GetInputFramesLost) {
1039     doc::test(
1040         "The number of frames lost on a never started stream should be 0");
1041     auto ret = stream->getInputFramesLost();
1042     ASSERT_IS_OK(ret);
1043     uint32_t framesLost{ret};
1044     ASSERT_EQ(0U, framesLost);
1045 }
1046
1047 TEST_P(InputStreamTest, getCapturePosition) {
1048     doc::test(
1049         "The capture position of a non prepared stream should not be "
1050         "retrievable");
1051     uint64_t frames;
1052     uint64_t time;
1053     ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
1054     ASSERT_RESULT(invalidStateOrNotSupported, res);
1055 }
1056
1057 //////////////////////////////////////////////////////////////////////////////
1058 ///////////////////////////////// StreamIn ///////////////////////////////////
1059 //////////////////////////////////////////////////////////////////////////////
1060
1061 TEST_P(OutputStreamTest, getLatency) {
1062     doc::test("Make sure latency is over 0");
1063     auto result = stream->getLatency();
1064     ASSERT_IS_OK(result);
1065     ASSERT_GT(result, 0U);
1066 }
1067
1068 TEST_P(OutputStreamTest, setVolume) {
1069     doc::test("Try to set the output volume");
1070     testOptionalUnitaryGain(
1071         [this](float volume) { return stream->setVolume(volume, volume); },
1072         "setVolume");
1073 }
1074
1075 static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize,
1076                                   uint32_t framesCount) {
1077     Result res;
1078     // Ignore output parameters as the call should fail
1079     ASSERT_OK(stream->prepareForWriting(
1080         frameSize, framesCount,
1081         [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
1082     EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
1083 }
1084
1085 TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
1086     doc::test(
1087         "Preparing a stream for writing with a 0 sized buffer should fail");
1088     testPrepareForWriting(stream.get(), 0, 0);
1089 }
1090
1091 TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
1092     doc::test(
1093         "Preparing a stream for writing with a 2^32 sized buffer should fail");
1094     testPrepareForWriting(stream.get(), 1,
1095                           std::numeric_limits<uint32_t>::max());
1096 }
1097
1098 TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
1099     doc::test(
1100         "Preparing a stream for writing with a overflowing sized buffer should "
1101         "fail");
1102     auto uintMax = std::numeric_limits<uint32_t>::max();
1103     testPrepareForWriting(stream.get(), uintMax, uintMax);
1104 }
1105
1106 struct Capability {
1107     Capability(IStreamOut* stream) {
1108         EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
1109         auto ret = stream->supportsDrain();
1110         EXPECT_IS_OK(ret);
1111         if (ret.isOk()) {
1112             drain = ret;
1113         }
1114     }
1115     bool pause = false;
1116     bool resume = false;
1117     bool drain = false;
1118 };
1119
1120 TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
1121     doc::test(
1122         "Implementation must expose pause, resume and drain capabilities");
1123     Capability(stream.get());
1124 }
1125
1126 template <class Value>
1127 static void checkInvalidStateOr0(Result res, Value value) {
1128     switch (res) {
1129         case Result::INVALID_STATE:
1130             break;
1131         case Result::OK:
1132             ASSERT_EQ(0U, value);
1133             break;
1134         default:
1135             FAIL() << "Unexpected result " << toString(res);
1136     }
1137 }
1138
1139 TEST_P(OutputStreamTest, GetRenderPosition) {
1140     doc::test("A new stream render position should be 0 or INVALID_STATE");
1141     uint32_t dspFrames;
1142     ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
1143     if (res == Result::NOT_SUPPORTED) {
1144         doc::partialTest("getRenderPosition is not supported");
1145         return;
1146     }
1147     checkInvalidStateOr0(res, dspFrames);
1148 }
1149
1150 TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
1151     doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
1152     uint64_t timestampUs;
1153     ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
1154     if (res == Result::NOT_SUPPORTED) {
1155         doc::partialTest("getNextWriteTimestamp is not supported");
1156         return;
1157     }
1158     checkInvalidStateOr0(res, timestampUs);
1159 }
1160
1161 /** Stub implementation of out stream callback. */
1162 class MockOutCallbacks : public IStreamOutCallback {
1163     Return<void> onWriteReady() override { return {}; }
1164     Return<void> onDrainReady() override { return {}; }
1165     Return<void> onError() override { return {}; }
1166 };
1167
1168 static bool isAsyncModeSupported(IStreamOut* stream) {
1169     auto res = stream->setCallback(new MockOutCallbacks);
1170     stream->clearCallback();  // try to restore the no callback state, ignore
1171                               // any error
1172     auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
1173     EXPECT_RESULT(okOrNotSupported, res);
1174     return res.isOk() ? res == Result::OK : false;
1175 }
1176
1177 TEST_P(OutputStreamTest, SetCallback) {
1178     doc::test(
1179         "If supported, registering callback for async operation should never "
1180         "fail");
1181     if (!isAsyncModeSupported(stream.get())) {
1182         doc::partialTest("The stream does not support async operations");
1183         return;
1184     }
1185     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1186     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1187 }
1188
1189 TEST_P(OutputStreamTest, clearCallback) {
1190     doc::test(
1191         "If supported, clearing a callback to go back to sync operation should "
1192         "not fail");
1193     if (!isAsyncModeSupported(stream.get())) {
1194         doc::partialTest("The stream does not support async operations");
1195         return;
1196     }
1197     // TODO: Clarify if clearing a non existing callback should fail
1198     ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1199     ASSERT_OK(stream->clearCallback());
1200 }
1201
1202 TEST_P(OutputStreamTest, Resume) {
1203     doc::test(
1204         "If supported, a stream should fail to resume if not previously "
1205         "paused");
1206     if (!Capability(stream.get()).resume) {
1207         doc::partialTest("The output stream does not support resume");
1208         return;
1209     }
1210     ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1211 }
1212
1213 TEST_P(OutputStreamTest, Pause) {
1214     doc::test(
1215         "If supported, a stream should fail to pause if not previously "
1216         "started");
1217     if (!Capability(stream.get()).pause) {
1218         doc::partialTest("The output stream does not support pause");
1219         return;
1220     }
1221     ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1222 }
1223
1224 static void testDrain(IStreamOut* stream, AudioDrain type) {
1225     if (!Capability(stream).drain) {
1226         doc::partialTest("The output stream does not support drain");
1227         return;
1228     }
1229     ASSERT_RESULT(Result::OK, stream->drain(type));
1230 }
1231
1232 TEST_P(OutputStreamTest, DrainAll) {
1233     doc::test("If supported, a stream should always succeed to drain");
1234     testDrain(stream.get(), AudioDrain::ALL);
1235 }
1236
1237 TEST_P(OutputStreamTest, DrainEarlyNotify) {
1238     doc::test("If supported, a stream should always succeed to drain");
1239     testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
1240 }
1241
1242 TEST_P(OutputStreamTest, FlushStop) {
1243     doc::test("If supported, a stream should always succeed to flush");
1244     auto ret = stream->flush();
1245     ASSERT_IS_OK(ret);
1246     if (ret == Result::NOT_SUPPORTED) {
1247         doc::partialTest("Flush is not supported");
1248         return;
1249     }
1250     ASSERT_OK(ret);
1251 }
1252
1253 TEST_P(OutputStreamTest, GetPresentationPositionStop) {
1254     doc::test(
1255         "If supported, a stream should always succeed to retrieve the "
1256         "presentation position");
1257     uint64_t frames;
1258     TimeSpec mesureTS;
1259     ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
1260     if (res == Result::NOT_SUPPORTED) {
1261         doc::partialTest("getpresentationPosition is not supported");
1262         return;
1263     }
1264     ASSERT_EQ(0U, frames);
1265
1266     if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) {
1267         // As the stream has never written a frame yet,
1268         // the timestamp does not really have a meaning, allow to return 0
1269         return;
1270     }
1271
1272     // Make sure the return measure is not more than 1s old.
1273     struct timespec currentTS;
1274     ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
1275
1276     auto toMicroSec = [](uint64_t sec, auto nsec) {
1277         return sec * 1e+6 + nsec / 1e+3;
1278     };
1279     auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
1280     auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
1281     ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime,
1282                  mesureTime);
1283 }
1284
1285 //////////////////////////////////////////////////////////////////////////////
1286 /////////////////////////////// PrimaryDevice ////////////////////////////////
1287 //////////////////////////////////////////////////////////////////////////////
1288
1289 TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
1290     doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
1291     testUnitaryGain([](float volume) { return device->setVoiceVolume(volume); });
1292 }
1293
1294 TEST_F(AudioPrimaryHidlTest, setMode) {
1295     doc::test(
1296         "Make sure setMode always succeeds if mode is valid "
1297         "and fails otherwise");
1298     // Test Invalid values
1299     for (AudioMode mode :
1300          {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
1301         SCOPED_TRACE("mode=" + toString(mode));
1302         ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
1303     }
1304     // Test valid values
1305     for (AudioMode mode :
1306          {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
1307           AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
1308         SCOPED_TRACE("mode=" + toString(mode));
1309         ASSERT_OK(device->setMode(mode));
1310     }
1311 }
1312
1313 TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
1314     doc::test("Query and set the BT SCO NR&EC state");
1315     testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
1316                           &IPrimaryDevice::setBtScoNrecEnabled,
1317                           &IPrimaryDevice::getBtScoNrecEnabled);
1318 }
1319
1320 TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
1321     doc::test("Query and set the SCO whideband state");
1322     testOptionalAccessors("BtScoWideband", {true, false, true},
1323                           &IPrimaryDevice::setBtScoWidebandEnabled,
1324                           &IPrimaryDevice::getBtScoWidebandEnabled);
1325 }
1326
1327 using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
1328 TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
1329     doc::test("Query and set the TTY mode state");
1330     testOptionalAccessors(
1331         "TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
1332         &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
1333 }
1334
1335 TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
1336     doc::test("Query and set the HAC state");
1337     testOptionalAccessors("HAC", {true, false, true},
1338                           &IPrimaryDevice::setHacEnabled,
1339                           &IPrimaryDevice::getHacEnabled);
1340 }
1341
1342 //////////////////////////////////////////////////////////////////////////////
1343 //////////////////// Clean caches on global tear down ////////////////////////
1344 //////////////////////////////////////////////////////////////////////////////
1345
1346 int main(int argc, char** argv) {
1347     environment = new Environment;
1348     ::testing::AddGlobalTestEnvironment(environment);
1349     ::testing::InitGoogleTest(&argc, argv);
1350     int status = RUN_ALL_TESTS();
1351     return status;
1352 }