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