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