blob: eec2b10d847f10c846a503a3934d2616b62bc870 [file] [log] [blame]
Kevin Rocardf0357882017-02-10 16:19:28 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "VtsHalAudioV2_0TargetTest"
18
19#include <algorithm>
20#include <cmath>
21#include <cstddef>
22#include <cstdio>
23#include <limits>
Kevin Rocardf0357882017-02-10 16:19:28 -080024#include <string>
Kevin Rocardf0357882017-02-10 16:19:28 -080025#include <vector>
26
Yuexi Ma161b5642017-03-10 13:44:22 -080027#include <VtsHalHidlTargetTestBase.h>
Kevin Rocardf0357882017-02-10 16:19:28 -080028
29#include <android-base/logging.h>
30
31#include <android/hardware/audio/2.0/IDevice.h>
32#include <android/hardware/audio/2.0/IDevicesFactory.h>
Kevin Rocard3c405a72017-03-08 16:46:51 -080033#include <android/hardware/audio/2.0/IPrimaryDevice.h>
Kevin Rocardf0357882017-02-10 16:19:28 -080034#include <android/hardware/audio/2.0/types.h>
35#include <android/hardware/audio/common/2.0/types.h>
36
Kevin Rocardf0357882017-02-10 16:19:28 -080037#include "utility/AssertOk.h"
Kevin Rocardb6d79ff2017-06-02 11:44:06 -070038#include "utility/Documentation.h"
39#include "utility/EnvironmentTearDown.h"
Kevin Rocardf0357882017-02-10 16:19:28 -080040#include "utility/PrettyPrintAudioTypes.h"
Kevin Rocard72e50e22017-05-05 14:02:55 -070041#include "utility/ReturnIn.h"
Kevin Rocardf0357882017-02-10 16:19:28 -080042
43using std::string;
44using std::to_string;
45using std::vector;
46
47using ::android::sp;
48using ::android::hardware::Return;
49using ::android::hardware::hidl_handle;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
Kevin Rocardc9963522017-03-10 18:47:37 -080052using ::android::hardware::MQDescriptorSync;
Kevin Rocard624800c2017-03-10 18:47:37 -080053using ::android::hardware::audio::V2_0::AudioDrain;
Kevin Rocardf0357882017-02-10 16:19:28 -080054using ::android::hardware::audio::V2_0::DeviceAddress;
55using ::android::hardware::audio::V2_0::IDevice;
Kevin Rocard3c405a72017-03-08 16:46:51 -080056using ::android::hardware::audio::V2_0::IPrimaryDevice;
57using TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode;
Kevin Rocardf0357882017-02-10 16:19:28 -080058using ::android::hardware::audio::V2_0::IDevicesFactory;
59using ::android::hardware::audio::V2_0::IStream;
60using ::android::hardware::audio::V2_0::IStreamIn;
Kevin Rocard624800c2017-03-10 18:47:37 -080061using ::android::hardware::audio::V2_0::TimeSpec;
Kevin Rocardb6d79ff2017-06-02 11:44:06 -070062using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
Kevin Rocardc9963522017-03-10 18:47:37 -080063using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
Kevin Rocardf0357882017-02-10 16:19:28 -080064using ::android::hardware::audio::V2_0::IStreamOut;
Kevin Rocard624800c2017-03-10 18:47:37 -080065using ::android::hardware::audio::V2_0::IStreamOutCallback;
Kevin Rocard8878b4b2017-03-10 18:47:37 -080066using ::android::hardware::audio::V2_0::MmapBufferInfo;
67using ::android::hardware::audio::V2_0::MmapPosition;
Kevin Rocardf0357882017-02-10 16:19:28 -080068using ::android::hardware::audio::V2_0::ParameterValue;
69using ::android::hardware::audio::V2_0::Result;
70using ::android::hardware::audio::common::V2_0::AudioChannelMask;
71using ::android::hardware::audio::common::V2_0::AudioConfig;
72using ::android::hardware::audio::common::V2_0::AudioDevice;
73using ::android::hardware::audio::common::V2_0::AudioFormat;
74using ::android::hardware::audio::common::V2_0::AudioHandleConsts;
75using ::android::hardware::audio::common::V2_0::AudioInputFlag;
76using ::android::hardware::audio::common::V2_0::AudioIoHandle;
Kevin Rocard3c405a72017-03-08 16:46:51 -080077using ::android::hardware::audio::common::V2_0::AudioMode;
Kevin Rocardf0357882017-02-10 16:19:28 -080078using ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
79using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
80using ::android::hardware::audio::common::V2_0::AudioSource;
Kevin Rocardc9963522017-03-10 18:47:37 -080081using ::android::hardware::audio::common::V2_0::ThreadInfo;
Kevin Rocardf0357882017-02-10 16:19:28 -080082
Kevin Rocardb6d79ff2017-06-02 11:44:06 -070083using namespace ::android::hardware::audio::common::test::utility;
Kevin Rocardf0357882017-02-10 16:19:28 -080084
Kevin Rocardf0357882017-02-10 16:19:28 -080085// Instance to register global tearDown
86static Environment* environment;
87
Yuexi Ma161b5642017-03-10 13:44:22 -080088class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
Kevin Rocard72e50e22017-05-05 14:02:55 -070089 protected:
Kevin Rocardf0357882017-02-10 16:19:28 -080090 // Convenient member to store results
91 Result res;
92};
93
94//////////////////////////////////////////////////////////////////////////////
95////////////////////// getService audio_devices_factory //////////////////////
96//////////////////////////////////////////////////////////////////////////////
97
98// Test all audio devices
99class AudioHidlTest : public HidlTest {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700100 public:
Kevin Rocardf0357882017-02-10 16:19:28 -0800101 void SetUp() override {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700102 ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
Kevin Rocardf0357882017-02-10 16:19:28 -0800103
104 if (devicesFactory == nullptr) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700105 environment->registerTearDown([] { devicesFactory.clear(); });
106 devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<
107 IDevicesFactory>();
Kevin Rocardf0357882017-02-10 16:19:28 -0800108 }
109 ASSERT_TRUE(devicesFactory != nullptr);
110 }
111
Kevin Rocard72e50e22017-05-05 14:02:55 -0700112 protected:
Kevin Rocardf0357882017-02-10 16:19:28 -0800113 // Cache the devicesFactory retrieval to speed up each test by ~0.5s
114 static sp<IDevicesFactory> devicesFactory;
115};
116sp<IDevicesFactory> AudioHidlTest::devicesFactory;
117
118TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
119 doc::test("test the getService (called in SetUp)");
120}
121
Mikhail Naganov8604a732017-04-24 09:29:22 -0700122TEST_F(AudioHidlTest, OpenDeviceInvalidParameter) {
123 doc::test("test passing an invalid parameter to openDevice");
124 IDevicesFactory::Result result;
125 sp<IDevice> device;
126 ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device(-1),
127 returnIn(result, device)));
128 ASSERT_EQ(IDevicesFactory::Result::INVALID_ARGUMENTS, result);
129 ASSERT_TRUE(device == nullptr);
130}
131
Kevin Rocardf0357882017-02-10 16:19:28 -0800132//////////////////////////////////////////////////////////////////////////////
133/////////////////////////////// openDevice primary ///////////////////////////
134//////////////////////////////////////////////////////////////////////////////
135
136// Test the primary device
137class AudioPrimaryHidlTest : public AudioHidlTest {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700138 public:
Kevin Rocardf0357882017-02-10 16:19:28 -0800139 /** Primary HAL test are NOT thread safe. */
140 void SetUp() override {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700141 ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
Kevin Rocardf0357882017-02-10 16:19:28 -0800142
143 if (device == nullptr) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800144 IDevicesFactory::Result result;
Kevin Rocard3c405a72017-03-08 16:46:51 -0800145 sp<IDevice> baseDevice;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700146 ASSERT_OK(
147 devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
148 returnIn(result, baseDevice)));
Kevin Rocardfba442a2017-03-31 19:34:41 -0700149 ASSERT_OK(result);
Kevin Rocard3c405a72017-03-08 16:46:51 -0800150 ASSERT_TRUE(baseDevice != nullptr);
151
Kevin Rocard72e50e22017-05-05 14:02:55 -0700152 environment->registerTearDown([] { device.clear(); });
Kevin Rocard3c405a72017-03-08 16:46:51 -0800153 device = IPrimaryDevice::castFrom(baseDevice);
154 ASSERT_TRUE(device != nullptr);
Kevin Rocardf0357882017-02-10 16:19:28 -0800155 }
Kevin Rocardf0357882017-02-10 16:19:28 -0800156 }
157
Kevin Rocard72e50e22017-05-05 14:02:55 -0700158 protected:
Kevin Rocardf0357882017-02-10 16:19:28 -0800159 // Cache the device opening to speed up each test by ~0.5s
Kevin Rocard3c405a72017-03-08 16:46:51 -0800160 static sp<IPrimaryDevice> device;
Kevin Rocardf0357882017-02-10 16:19:28 -0800161};
Kevin Rocard3c405a72017-03-08 16:46:51 -0800162sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
Kevin Rocardf0357882017-02-10 16:19:28 -0800163
164TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
165 doc::test("Test the openDevice (called in SetUp)");
166}
167
168TEST_F(AudioPrimaryHidlTest, Init) {
169 doc::test("Test that the audio primary hal initialized correctly");
170 ASSERT_OK(device->initCheck());
171}
172
173//////////////////////////////////////////////////////////////////////////////
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800174///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800175//////////////////////////////////////////////////////////////////////////////
176
Kevin Rocard3c405a72017-03-08 16:46:51 -0800177template <class Property>
178class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700179 protected:
Kevin Rocard3c405a72017-03-08 16:46:51 -0800180 /** Test a property getter and setter. */
Kevin Rocardf0357882017-02-10 16:19:28 -0800181 template <class Getter, class Setter>
Kevin Rocard72e50e22017-05-05 14:02:55 -0700182 void testAccessors(const string& propertyName,
183 const vector<Property>& valuesToTest, Setter setter,
184 Getter getter,
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800185 const vector<Property>& invalidValues = {}) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700186 Property initialValue; // Save initial value to restore it at the end
187 // of the test
Kevin Rocard3c405a72017-03-08 16:46:51 -0800188 ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
189 ASSERT_OK(res);
190
191 for (Property setValue : valuesToTest) {
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800192 SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
193 testing::PrintToString(setValue));
Kevin Rocard3c405a72017-03-08 16:46:51 -0800194 ASSERT_OK((device.get()->*setter)(setValue));
195 Property getValue;
196 // Make sure the getter returns the same value just set
197 ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
Kevin Rocardf0357882017-02-10 16:19:28 -0800198 ASSERT_OK(res);
Kevin Rocard3c405a72017-03-08 16:46:51 -0800199 EXPECT_EQ(setValue, getValue);
Kevin Rocardf0357882017-02-10 16:19:28 -0800200 }
Kevin Rocard3c405a72017-03-08 16:46:51 -0800201
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800202 for (Property invalidValue : invalidValues) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700203 SCOPED_TRACE("Try to set " + propertyName +
204 " with the invalid value " +
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800205 testing::PrintToString(invalidValue));
Kevin Rocard72e50e22017-05-05 14:02:55 -0700206 EXPECT_RESULT(Result::INVALID_ARGUMENTS,
207 (device.get()->*setter)(invalidValue));
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800208 }
209
Kevin Rocard72e50e22017-05-05 14:02:55 -0700210 ASSERT_OK(
211 (device.get()->*setter)(initialValue)); // restore initial value
Kevin Rocard3c405a72017-03-08 16:46:51 -0800212 }
213
214 /** Test the getter and setter of an optional feature. */
215 template <class Getter, class Setter>
Kevin Rocard72e50e22017-05-05 14:02:55 -0700216 void testOptionalAccessors(const string& propertyName,
217 const vector<Property>& valuesToTest,
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800218 Setter setter, Getter getter,
219 const vector<Property>& invalidValues = {}) {
Kevin Rocard3c405a72017-03-08 16:46:51 -0800220 doc::test("Test the optional " + propertyName + " getters and setter");
221 {
222 SCOPED_TRACE("Test feature support by calling the getter");
223 Property initialValue;
224 ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
225 if (res == Result::NOT_SUPPORTED) {
226 doc::partialTest(propertyName + " getter is not supported");
227 return;
228 }
Kevin Rocard72e50e22017-05-05 14:02:55 -0700229 ASSERT_OK(res); // If it is supported it must succeed
Kevin Rocard3c405a72017-03-08 16:46:51 -0800230 }
231 // The feature is supported, test it
Kevin Rocard72e50e22017-05-05 14:02:55 -0700232 testAccessors(propertyName, valuesToTest, setter, getter,
233 invalidValues);
Kevin Rocardf0357882017-02-10 16:19:28 -0800234 }
235};
236
Kevin Rocard3c405a72017-03-08 16:46:51 -0800237using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
238
Kevin Rocardf0357882017-02-10 16:19:28 -0800239TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
240 doc::test("Check that the mic can be muted and unmuted");
Kevin Rocard72e50e22017-05-05 14:02:55 -0700241 testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute,
242 &IDevice::getMicMute);
Kevin Rocardf0357882017-02-10 16:19:28 -0800243 // TODO: check that the mic is really muted (all sample are 0)
244}
245
246TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700247 doc::test(
248 "If master mute is supported, try to mute and unmute the master "
249 "output");
Kevin Rocard3c405a72017-03-08 16:46:51 -0800250 testOptionalAccessors("master mute", {true, false, true},
251 &IDevice::setMasterMute, &IDevice::getMasterMute);
Kevin Rocardf0357882017-02-10 16:19:28 -0800252 // TODO: check that the master volume is really muted
253}
254
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800255using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
256TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
257 doc::test("Test the master volume if supported");
Kevin Rocard72e50e22017-05-05 14:02:55 -0700258 testOptionalAccessors("master volume", {0, 0.5, 1},
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800259 &IDevice::setMasterVolume, &IDevice::getMasterVolume,
260 {-0.1, 1.1, NAN, INFINITY, -INFINITY,
261 1 + std::numeric_limits<float>::epsilon()});
262 // TODO: check that the master volume is really changed
263}
264
Kevin Rocardf0357882017-02-10 16:19:28 -0800265//////////////////////////////////////////////////////////////////////////////
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800266//////////////////////////////// AudioPatches ////////////////////////////////
267//////////////////////////////////////////////////////////////////////////////
268
269class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700270 protected:
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800271 bool areAudioPatchesSupported() {
272 auto result = device->supportsAudioPatches();
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700273 EXPECT_IS_OK(result);
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800274 return result;
275 }
276};
277
278TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
279 doc::test("Test if audio patches are supported");
280 if (!areAudioPatchesSupported()) {
281 doc::partialTest("Audio patches are not supported");
282 return;
283 }
284 // TODO: test audio patches
285}
286
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800287//////////////////////////////////////////////////////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800288//////////////// Required and recommended audio format support ///////////////
Kevin Rocard72e50e22017-05-05 14:02:55 -0700289// From:
290// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
291// From:
292// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
Kevin Rocardf0357882017-02-10 16:19:28 -0800293/////////// TODO: move to the beginning of the file for easier update ////////
294//////////////////////////////////////////////////////////////////////////////
295
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800296class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700297 public:
Kevin Rocardf0357882017-02-10 16:19:28 -0800298 // Cache result ?
299 static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700300 return combineAudioConfig(
301 {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
302 {8000, 11025, 16000, 22050, 32000, 44100},
303 {AudioFormat::PCM_16_BIT});
Kevin Rocardf0357882017-02-10 16:19:28 -0800304 }
305
Kevin Rocard72e50e22017-05-05 14:02:55 -0700306 static const vector<AudioConfig>
307 getRecommendedSupportPlaybackAudioConfig() {
308 return combineAudioConfig(
309 {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
310 {24000, 48000}, {AudioFormat::PCM_16_BIT});
Kevin Rocardf0357882017-02-10 16:19:28 -0800311 }
312
313 static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
314 // TODO: retrieve audio config supported by the platform
315 // as declared in the policy configuration
316 return {};
317 }
318
319 static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
320 return combineAudioConfig({AudioChannelMask::IN_MONO},
321 {8000, 11025, 16000, 44100},
322 {AudioFormat::PCM_16_BIT});
323 }
324 static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700325 return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
Kevin Rocardf0357882017-02-10 16:19:28 -0800326 {AudioFormat::PCM_16_BIT});
327 }
328 static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
329 // TODO: retrieve audio config supported by the platform
330 // as declared in the policy configuration
331 return {};
332 }
Kevin Rocard72e50e22017-05-05 14:02:55 -0700333
334 private:
Kevin Rocardf0357882017-02-10 16:19:28 -0800335 static const vector<AudioConfig> combineAudioConfig(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700336 vector<AudioChannelMask> channelMasks, vector<uint32_t> sampleRates,
337 vector<AudioFormat> formats) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800338 vector<AudioConfig> configs;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700339 for (auto channelMask : channelMasks) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800340 for (auto sampleRate : sampleRates) {
341 for (auto format : formats) {
342 AudioConfig config{};
343 // leave offloadInfo to 0
344 config.channelMask = channelMask;
345 config.sampleRateHz = sampleRate;
346 config.format = format;
347 // FIXME: leave frameCount to 0 ?
348 configs.push_back(config);
349 }
350 }
351 }
352 return configs;
353 }
354};
355
Kevin Rocard9c369142017-03-08 17:17:25 -0800356/** Generate a test name based on an audio config.
357 *
358 * As the only parameter changing are channel mask and sample rate,
359 * only print those ones in the test name.
360 */
Kevin Rocard72e50e22017-05-05 14:02:55 -0700361static string generateTestName(
362 const testing::TestParamInfo<AudioConfig>& info) {
Kevin Rocard9c369142017-03-08 17:17:25 -0800363 const AudioConfig& config = info.param;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700364 return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
365 // "MONO" is more clear than "FRONT_LEFT"
366 ((config.channelMask == AudioChannelMask::OUT_MONO ||
367 config.channelMask == AudioChannelMask::IN_MONO)
368 ? "MONO"
369 : toString(config.channelMask));
Kevin Rocard9c369142017-03-08 17:17:25 -0800370}
371
Kevin Rocardf0357882017-02-10 16:19:28 -0800372//////////////////////////////////////////////////////////////////////////////
373///////////////////////////// getInputBufferSize /////////////////////////////
374//////////////////////////////////////////////////////////////////////////////
375
Kevin Rocard72e50e22017-05-05 14:02:55 -0700376// FIXME: execute input test only if platform declares
377// android.hardware.microphone
Kevin Rocardf0357882017-02-10 16:19:28 -0800378// how to get this value ? is it a property ???
379
Kevin Rocard72e50e22017-05-05 14:02:55 -0700380class AudioCaptureConfigPrimaryTest
381 : public AudioConfigPrimaryTest,
382 public ::testing::WithParamInterface<AudioConfig> {
383 protected:
384 void inputBufferSizeTest(const AudioConfig& audioConfig,
385 bool supportRequired) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800386 uint64_t bufferSize;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700387 ASSERT_OK(
388 device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
Kevin Rocardf0357882017-02-10 16:19:28 -0800389
390 switch (res) {
391 case Result::INVALID_ARGUMENTS:
392 EXPECT_FALSE(supportRequired);
393 break;
394 case Result::OK:
395 // Check that the buffer is of a sane size
396 // For now only that it is > 0
397 EXPECT_GT(bufferSize, uint64_t(0));
398 break;
399 default:
Kevin Rocard72e50e22017-05-05 14:02:55 -0700400 FAIL() << "Invalid return status: "
401 << ::testing::PrintToString(res);
Kevin Rocardf0357882017-02-10 16:19:28 -0800402 }
403 }
404};
405
Kevin Rocard72e50e22017-05-05 14:02:55 -0700406// Test that the required capture config and those declared in the policy are
407// indeed supported
Kevin Rocardf0357882017-02-10 16:19:28 -0800408class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
409TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700410 doc::test(
411 "Input buffer size must be retrievable for a format with required "
412 "support.");
Kevin Rocardf0357882017-02-10 16:19:28 -0800413 inputBufferSizeTest(GetParam(), true);
414}
415INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700416 RequiredInputBufferSize, RequiredInputBufferSizeTest,
417 ::testing::ValuesIn(
418 AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
419 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800420INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700421 SupportedInputBufferSize, RequiredInputBufferSizeTest,
422 ::testing::ValuesIn(
423 AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
424 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800425
Kevin Rocard72e50e22017-05-05 14:02:55 -0700426// Test that the recommended capture config are supported or lead to a
427// INVALID_ARGUMENTS return
Kevin Rocardf0357882017-02-10 16:19:28 -0800428class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
429TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700430 doc::test(
431 "Input buffer size should be retrievable for a format with recommended "
432 "support.");
Kevin Rocardf0357882017-02-10 16:19:28 -0800433 inputBufferSizeTest(GetParam(), false);
434}
435INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700436 RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
437 ::testing::ValuesIn(
438 AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
439 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800440
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 auto ret = device->setScreenState(turnedOn);
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700449 ASSERT_IS_OK(ret);
Kevin Rocardf0357882017-02-10 16:19:28 -0800450 Result result = ret;
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700451 auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
452 ASSERT_RESULT(okOrNotSupported, result);
Kevin Rocardf0357882017-02-10 16:19:28 -0800453 }
454}
455
456//////////////////////////////////////////////////////////////////////////////
457//////////////////////////// {get,set}Parameters /////////////////////////////
458//////////////////////////////////////////////////////////////////////////////
459
460TEST_F(AudioPrimaryHidlTest, getParameters) {
461 doc::test("Check that the hal can set and get parameters");
462 hidl_vec<hidl_string> keys;
463 hidl_vec<ParameterValue> values;
464 ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
465 ASSERT_OK(device->setParameters(values));
466 values.resize(0);
467 ASSERT_OK(device->setParameters(values));
468}
469
470//////////////////////////////////////////////////////////////////////////////
471//////////////////////////////// debugDebug //////////////////////////////////
472//////////////////////////////////////////////////////////////////////////////
473
Kevin Rocardb9031242017-03-13 12:20:54 -0700474template <class DebugDump>
475static void testDebugDump(DebugDump debugDump) {
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700476 // Dump in a temporary file
477 // Note that SELinux must be deactivate for this test to work
Kevin Rocardf0357882017-02-10 16:19:28 -0800478 FILE* file = tmpfile();
479 ASSERT_NE(nullptr, file) << errno;
480
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700481 // Wrap the temporary file file descriptor in a native handle
Kevin Rocardf0357882017-02-10 16:19:28 -0800482 auto* nativeHandle = native_handle_create(1, 0);
483 ASSERT_NE(nullptr, nativeHandle);
484 nativeHandle->data[0] = fileno(file);
485
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700486 // Wrap this native handle in a hidl handle
Kevin Rocardf0357882017-02-10 16:19:28 -0800487 hidl_handle handle;
488 handle.setTo(nativeHandle, true /*take ownership*/);
489
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700490 ASSERT_OK(debugDump(handle));
491
492 // Check that at least one bit was written by the hal
Kevin Rocardee771e92017-03-08 17:17:25 -0800493 // TODO: debugDump does not return a Result.
Kevin Rocard72e50e22017-05-05 14:02:55 -0700494 // This mean that the hal can not report that it not implementing the
495 // function.
Kevin Rocard72e50e22017-05-05 14:02:55 -0700496 rewind(file); // can not fail
Kevin Rocardf0357882017-02-10 16:19:28 -0800497 char buff;
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700498 if (fread(&buff, sizeof(buff), 1, file) != 1) {
499 doc::note("debugDump does not seem implemented");
500 }
Kevin Rocardf0357882017-02-10 16:19:28 -0800501 EXPECT_EQ(0, fclose(file)) << errno;
502}
503
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700504TEST_F(AudioPrimaryHidlTest, DebugDump) {
Kevin Rocardb9031242017-03-13 12:20:54 -0700505 doc::test("Check that the hal can dump its state without error");
Chih-Hung Hsieh7eb57b62017-05-15 12:31:25 -0700506 testDebugDump([](const auto& handle) { return device->debugDump(handle); });
Kevin Rocardb9031242017-03-13 12:20:54 -0700507}
508
Kevin Rocard5e5783d2017-05-02 18:41:46 -0700509TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
Mikhail Naganov3e6fe752017-04-24 10:44:08 -0700510 doc::test("Check that the hal dump doesn't crash on invalid arguments");
511 ASSERT_OK(device->debugDump(hidl_handle()));
512}
513
Kevin Rocardf0357882017-02-10 16:19:28 -0800514//////////////////////////////////////////////////////////////////////////////
515////////////////////////// open{Output,Input}Stream //////////////////////////
516//////////////////////////////////////////////////////////////////////////////
517
518template <class Stream>
519class OpenStreamTest : public AudioConfigPrimaryTest,
520 public ::testing::WithParamInterface<AudioConfig> {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700521 protected:
Kevin Rocardf0357882017-02-10 16:19:28 -0800522 template <class Open>
523 void testOpen(Open openStream, const AudioConfig& config) {
524 // FIXME: Open a stream without an IOHandle
525 // This is not required to be accepted by hal implementations
Kevin Rocard72e50e22017-05-05 14:02:55 -0700526 AudioIoHandle ioHandle =
527 (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
Kevin Rocardf0357882017-02-10 16:19:28 -0800528 AudioConfig suggestedConfig{};
Kevin Rocard72e50e22017-05-05 14:02:55 -0700529 ASSERT_OK(openStream(ioHandle, config,
530 returnIn(res, stream, suggestedConfig)));
Kevin Rocardf0357882017-02-10 16:19:28 -0800531
532 // TODO: only allow failure for RecommendedPlaybackAudioConfig
533 switch (res) {
534 case Result::OK:
535 ASSERT_TRUE(stream != nullptr);
536 audioConfig = config;
537 break;
538 case Result::INVALID_ARGUMENTS:
539 ASSERT_TRUE(stream == nullptr);
540 AudioConfig suggestedConfigRetry;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700541 // Could not open stream with config, try again with the
542 // suggested one
543 ASSERT_OK(
544 openStream(ioHandle, suggestedConfig,
545 returnIn(res, stream, suggestedConfigRetry)));
Kevin Rocardf0357882017-02-10 16:19:28 -0800546 // This time it must succeed
547 ASSERT_OK(res);
Kevin Rocard4aefd1c2017-05-02 18:58:58 -0700548 ASSERT_TRUE(stream != nullptr);
Kevin Rocardf0357882017-02-10 16:19:28 -0800549 audioConfig = suggestedConfig;
550 break;
551 default:
Kevin Rocard72e50e22017-05-05 14:02:55 -0700552 FAIL() << "Invalid return status: "
553 << ::testing::PrintToString(res);
Kevin Rocardf0357882017-02-10 16:19:28 -0800554 }
555 open = true;
556 }
557
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800558 Return<Result> closeStream() {
559 open = false;
560 return stream->close();
561 }
Kevin Rocard72e50e22017-05-05 14:02:55 -0700562
563 private:
Kevin Rocardf0357882017-02-10 16:19:28 -0800564 void TearDown() override {
565 if (open) {
566 ASSERT_OK(stream->close());
567 }
568 }
569
Kevin Rocard72e50e22017-05-05 14:02:55 -0700570 protected:
Kevin Rocardf0357882017-02-10 16:19:28 -0800571 AudioConfig audioConfig;
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800572 DeviceAddress address = {};
Kevin Rocardf0357882017-02-10 16:19:28 -0800573 sp<Stream> stream;
574 bool open = false;
575};
576
577////////////////////////////// openOutputStream //////////////////////////////
578
579class OutputStreamTest : public OpenStreamTest<IStreamOut> {
580 virtual void SetUp() override {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700581 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800582 address.device = AudioDevice::OUT_DEFAULT;
Kevin Rocardf0357882017-02-10 16:19:28 -0800583 const AudioConfig& config = GetParam();
Kevin Rocard72e50e22017-05-05 14:02:55 -0700584 AudioOutputFlag flags =
585 AudioOutputFlag::NONE; // TODO: test all flag combination
586 testOpen(
587 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
588 return device->openOutputStream(handle, address, config, flags,
589 cb);
590 },
591 config);
Kevin Rocardf0357882017-02-10 16:19:28 -0800592 }
593};
594TEST_P(OutputStreamTest, OpenOutputStreamTest) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700595 doc::test(
596 "Check that output streams can be open with the required and "
597 "recommended config");
Kevin Rocardf0357882017-02-10 16:19:28 -0800598 // Open done in SetUp
599}
600INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700601 RequiredOutputStreamConfigSupport, OutputStreamTest,
602 ::testing::ValuesIn(
603 AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
604 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800605INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700606 SupportedOutputStreamConfig, OutputStreamTest,
607 ::testing::ValuesIn(
608 AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
609 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800610
611INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700612 RecommendedOutputStreamConfigSupport, OutputStreamTest,
613 ::testing::ValuesIn(
614 AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
615 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800616
617////////////////////////////// openInputStream //////////////////////////////
618
619class InputStreamTest : public OpenStreamTest<IStreamIn> {
Kevin Rocardf0357882017-02-10 16:19:28 -0800620 virtual void SetUp() override {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700621 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800622 address.device = AudioDevice::IN_DEFAULT;
Kevin Rocardf0357882017-02-10 16:19:28 -0800623 const AudioConfig& config = GetParam();
Kevin Rocard72e50e22017-05-05 14:02:55 -0700624 AudioInputFlag flags =
625 AudioInputFlag::NONE; // TODO: test all flag combination
626 AudioSource source =
627 AudioSource::DEFAULT; // TODO: test all flag combination
628 testOpen(
629 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
630 return device->openInputStream(handle, address, config, flags,
631 source, cb);
632 },
633 config);
Kevin Rocardf0357882017-02-10 16:19:28 -0800634 }
635};
636
637TEST_P(InputStreamTest, OpenInputStreamTest) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700638 doc::test(
639 "Check that input streams can be open with the required and "
640 "recommended config");
Kevin Rocardf0357882017-02-10 16:19:28 -0800641 // Open done in setup
642}
643INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700644 RequiredInputStreamConfigSupport, InputStreamTest,
645 ::testing::ValuesIn(
646 AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
647 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800648INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700649 SupportedInputStreamConfig, InputStreamTest,
650 ::testing::ValuesIn(
651 AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
652 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800653
654INSTANTIATE_TEST_CASE_P(
Kevin Rocard72e50e22017-05-05 14:02:55 -0700655 RecommendedInputStreamConfigSupport, InputStreamTest,
656 ::testing::ValuesIn(
657 AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
658 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800659
660//////////////////////////////////////////////////////////////////////////////
661////////////////////////////// IStream getters ///////////////////////////////
662//////////////////////////////////////////////////////////////////////////////
663
664/** Unpack the provided result.
665 * If the result is not OK, register a failure and return an undefined value. */
666template <class R>
667static R extract(Return<R> ret) {
668 if (!ret.isOk()) {
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700669 EXPECT_IS_OK(ret);
Kevin Rocardf0357882017-02-10 16:19:28 -0800670 return R{};
671 }
672 return ret;
673}
674
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800675/* Could not find a way to write a test for two parametrized class fixure
676 * thus use this macro do duplicate tests for Input and Output stream */
677#define TEST_IO_STREAM(test_name, documentation, code) \
Kevin Rocard72e50e22017-05-05 14:02:55 -0700678 TEST_P(InputStreamTest, test_name) { \
679 doc::test(documentation); \
680 code; \
681 } \
682 TEST_P(OutputStreamTest, test_name) { \
683 doc::test(documentation); \
684 code; \
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800685 }
686
Kevin Rocard72e50e22017-05-05 14:02:55 -0700687TEST_IO_STREAM(
688 GetFrameCount,
689 "Check that the stream frame count == the one it was opened with",
690 ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800691
Kevin Rocard07fb7362017-05-26 17:23:07 -0700692TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
693 ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800694
Kevin Rocard07fb7362017-05-26 17:23:07 -0700695TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
696 ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800697
Kevin Rocard72e50e22017-05-05 14:02:55 -0700698TEST_IO_STREAM(GetFormat,
699 "Check that the stream format == the one it was opened with",
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800700 ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
701
702// TODO: for now only check that the framesize is not incoherent
Kevin Rocard72e50e22017-05-05 14:02:55 -0700703TEST_IO_STREAM(GetFrameSize,
704 "Check that the stream frame size == the one it was opened with",
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800705 ASSERT_GT(extract(stream->getFrameSize()), 0U))
706
Kevin Rocard72e50e22017-05-05 14:02:55 -0700707TEST_IO_STREAM(GetBufferSize,
708 "Check that the stream buffer size== the one it was opened with",
709 ASSERT_GE(extract(stream->getBufferSize()),
710 extract(stream->getFrameSize())));
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800711
Kevin Rocardf0357882017-02-10 16:19:28 -0800712template <class Property, class CapabilityGetter, class Getter, class Setter>
Kevin Rocard72e50e22017-05-05 14:02:55 -0700713static void testCapabilityGetter(const string& name, IStream* stream,
714 Property currentValue,
715 CapabilityGetter capablityGetter,
716 Getter getter, Setter setter) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800717 hidl_vec<Property> capabilities;
718 ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
719 if (capabilities.size() == 0) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700720 // The default hal should probably return a NOT_SUPPORTED if the hal
721 // does not expose
722 // capability retrieval. For now it returns an empty list if not
723 // implemented
Kevin Rocardf0357882017-02-10 16:19:28 -0800724 doc::partialTest(name + " is not supported");
725 return;
726 };
Kevin Rocard72e50e22017-05-05 14:02:55 -0700727 // TODO: This code has never been tested on a hal that supports
728 // getSupportedSampleRates
Kevin Rocardf0357882017-02-10 16:19:28 -0800729 EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
Kevin Rocard72e50e22017-05-05 14:02:55 -0700730 capabilities.end())
Kevin Rocardf0357882017-02-10 16:19:28 -0800731 << "current " << name << " is not in the list of the supported ones "
732 << toString(capabilities);
733
734 // Check that all declared supported values are indeed supported
735 for (auto capability : capabilities) {
736 ASSERT_OK((stream->*setter)(capability));
737 ASSERT_EQ(capability, extract((stream->*getter)()));
738 }
739}
740
Kevin Rocard72e50e22017-05-05 14:02:55 -0700741TEST_IO_STREAM(SupportedSampleRate,
742 "Check that the stream sample rate is declared as supported",
743 testCapabilityGetter("getSupportedSampleRate", stream.get(),
744 extract(stream->getSampleRate()),
745 &IStream::getSupportedSampleRates,
746 &IStream::getSampleRate,
747 &IStream::setSampleRate))
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800748
Kevin Rocard72e50e22017-05-05 14:02:55 -0700749TEST_IO_STREAM(SupportedChannelMask,
750 "Check that the stream channel mask is declared as supported",
751 testCapabilityGetter("getSupportedChannelMask", stream.get(),
752 extract(stream->getChannelMask()),
753 &IStream::getSupportedChannelMasks,
754 &IStream::getChannelMask,
755 &IStream::setChannelMask))
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800756
Kevin Rocard72e50e22017-05-05 14:02:55 -0700757TEST_IO_STREAM(SupportedFormat,
758 "Check that the stream format is declared as supported",
759 testCapabilityGetter("getSupportedFormat", stream.get(),
760 extract(stream->getFormat()),
761 &IStream::getSupportedFormats,
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800762 &IStream::getFormat, &IStream::setFormat))
763
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800764static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
Kevin Rocard8f8730c2017-05-02 19:34:29 -0700765 // Unfortunately the interface does not allow the implementation to return
766 // NOT_SUPPORTED
767 // Thus allow NONE as signaling that the call is not supported.
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800768 auto ret = stream->getDevice();
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700769 ASSERT_IS_OK(ret);
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800770 AudioDevice device = ret;
Kevin Rocard8f8730c2017-05-02 19:34:29 -0700771 ASSERT_TRUE(device == expectedDevice || device == AudioDevice::NONE)
772 << "Expected: " << ::testing::PrintToString(expectedDevice)
773 << "\n Actual: " << ::testing::PrintToString(device);
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800774}
775
Kevin Rocard72e50e22017-05-05 14:02:55 -0700776TEST_IO_STREAM(GetDevice,
777 "Check that the stream device == the one it was opened with",
778 areAudioPatchesSupported()
779 ? doc::partialTest("Audio patches are supported")
780 : testGetDevice(stream.get(), address.device))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800781
782static void testSetDevice(IStream* stream, const DeviceAddress& address) {
783 DeviceAddress otherAddress = address;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700784 otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0
785 ? AudioDevice::OUT_SPEAKER
786 : AudioDevice::IN_BUILTIN_MIC;
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800787 EXPECT_OK(stream->setDevice(otherAddress));
788
Kevin Rocard72e50e22017-05-05 14:02:55 -0700789 ASSERT_OK(stream->setDevice(address)); // Go back to the original value
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800790}
791
Kevin Rocard72e50e22017-05-05 14:02:55 -0700792TEST_IO_STREAM(
793 SetDevice,
794 "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
795 areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
796 : testSetDevice(stream.get(), address))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800797
Kevin Rocard07fb7362017-05-26 17:23:07 -0700798static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800799 uint32_t sampleRateHz;
800 AudioChannelMask mask;
801 AudioFormat format;
Kevin Rocard07fb7362017-05-26 17:23:07 -0700802
Kevin Rocardf0357882017-02-10 16:19:28 -0800803 stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
Kevin Rocard07fb7362017-05-26 17:23:07 -0700804
805 // FIXME: the qcom hal it does not currently negotiate the sampleRate &
806 // channel mask
807 EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
808 EXPECT_EQ(expectedConfig.channelMask, mask);
809 EXPECT_EQ(expectedConfig.format, format);
Kevin Rocardf0357882017-02-10 16:19:28 -0800810}
811
Kevin Rocard07fb7362017-05-26 17:23:07 -0700812TEST_IO_STREAM(GetAudioProperties,
813 "Check that the stream audio properties == the ones it was opened with",
814 testGetAudioProperties(stream.get(), audioConfig))
Kevin Rocardf0357882017-02-10 16:19:28 -0800815
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800816static void testConnectedState(IStream* stream) {
817 DeviceAddress address = {};
818 using AD = AudioDevice;
Kevin Rocard72e50e22017-05-05 14:02:55 -0700819 for (auto device :
820 {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800821 address.device = device;
822
823 ASSERT_OK(stream->setConnectedState(address, true));
824 ASSERT_OK(stream->setConnectedState(address, false));
825 }
826}
827TEST_IO_STREAM(SetConnectedState,
Kevin Rocard72e50e22017-05-05 14:02:55 -0700828 "Check that the stream can be notified of device connection and "
829 "deconnection",
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800830 testConnectedState(stream.get()))
831
Kevin Rocardf8500dc2017-05-03 10:43:21 -0700832static auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS,
833 Result::NOT_SUPPORTED, Result::OK};
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800834TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
Kevin Rocardf8500dc2017-05-03 10:43:21 -0700835 ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
Kevin Rocard72e50e22017-05-05 14:02:55 -0700836 stream->setHwAvSync(666)))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800837
Kevin Rocarde9a8fb72017-03-21 11:39:55 -0700838TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700839 ASSERT_IS_OK(device->getHwAvSync()));
Kevin Rocarde9a8fb72017-03-21 11:39:55 -0700840
Kevin Rocardfa3b4a92017-05-02 17:38:34 -0700841static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
842 vector<Result> expectedResults) {
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800843 hidl_vec<ParameterValue> parameters;
844 Result res;
845 ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
846 ASSERT_RESULT(expectedResults, res);
847 if (res == Result::OK) {
Kevin Rocard4aefd1c2017-05-02 18:58:58 -0700848 for (auto& parameter : parameters) {
849 ASSERT_EQ(0U, parameter.value.size()) << toString(parameter);
850 }
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800851 }
852}
853
Kevin Rocard72e50e22017-05-05 14:02:55 -0700854/* Get/Set parameter is intended to be an opaque channel between vendors app and
855 * their HALs.
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800856 * Thus can not be meaningfully tested.
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800857 */
858TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
Kevin Rocardfa3b4a92017-05-02 17:38:34 -0700859 checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK}))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800860
Kevin Rocard72e50e22017-05-05 14:02:55 -0700861TEST_IO_STREAM(getNonExistingParameter,
862 "Retrieve the values of an non existing parameter",
Kevin Rocardfa3b4a92017-05-02 17:38:34 -0700863 checkGetNoParameter(stream.get(),
864 {"Non existing key"} /* keys */,
865 {Result::NOT_SUPPORTED}))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800866
Kevin Rocard72e50e22017-05-05 14:02:55 -0700867TEST_IO_STREAM(setEmptySetParameter,
868 "Set the values of an empty set of parameters",
Kevin Rocardf8500dc2017-05-03 10:43:21 -0700869 ASSERT_RESULT(Result::OK, stream->setParameters({})))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800870
Kevin Rocard72e50e22017-05-05 14:02:55 -0700871TEST_IO_STREAM(
872 setNonExistingParameter, "Set the values of an non existing parameter",
Kevin Rocardf8500dc2017-05-03 10:43:21 -0700873 // Unfortunately, the set_parameter legacy interface did not return any
874 // error code when a key is not supported.
875 // To allow implementation to just wrapped the legacy one, consider OK as a
876 // valid result for setting a non existing parameter.
877 ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
Kevin Rocard72e50e22017-05-05 14:02:55 -0700878 stream->setParameters({{"non existing key", "0"}})))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800879
Kevin Rocardb9031242017-03-13 12:20:54 -0700880TEST_IO_STREAM(DebugDump,
881 "Check that a stream can dump its state without error",
Kevin Rocard72e50e22017-05-05 14:02:55 -0700882 testDebugDump([this](const auto& handle) {
883 return stream->debugDump(handle);
884 }))
Kevin Rocardb9031242017-03-13 12:20:54 -0700885
Mikhail Naganov3e6fe752017-04-24 10:44:08 -0700886TEST_IO_STREAM(DebugDumpInvalidArguments,
887 "Check that the stream dump doesn't crash on invalid arguments",
888 ASSERT_OK(stream->debugDump(hidl_handle())))
889
Kevin Rocardf0357882017-02-10 16:19:28 -0800890//////////////////////////////////////////////////////////////////////////////
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800891////////////////////////////// addRemoveEffect ///////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800892//////////////////////////////////////////////////////////////////////////////
893
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800894TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
895 ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
Kevin Rocard72e50e22017-05-05 14:02:55 -0700896TEST_IO_STREAM(RemoveNonExistingEffect,
897 "Removing a non existing effect should fail",
898 ASSERT_RESULT(Result::INVALID_ARGUMENTS,
899 stream->removeEffect(666)))
Kevin Rocardf0357882017-02-10 16:19:28 -0800900
Kevin Rocard72e50e22017-05-05 14:02:55 -0700901// TODO: positive tests
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800902
903//////////////////////////////////////////////////////////////////////////////
904/////////////////////////////// Control ////////////////////////////////
905//////////////////////////////////////////////////////////////////////////////
906
907TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
Kevin Rocard72e50e22017-05-05 14:02:55 -0700908 ASSERT_OK(stream->standby())) // can not fail
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800909
Kevin Rocard72e50e22017-05-05 14:02:55 -0700910static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE,
911 Result::NOT_SUPPORTED};
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800912
Kevin Rocard72e50e22017-05-05 14:02:55 -0700913TEST_IO_STREAM(startNoMmap,
914 "Starting a mmaped stream before mapping it should fail",
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800915 ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
916
Kevin Rocard72e50e22017-05-05 14:02:55 -0700917TEST_IO_STREAM(stopNoMmap,
918 "Stopping a mmaped stream before mapping it should fail",
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800919 ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
920
Kevin Rocard72e50e22017-05-05 14:02:55 -0700921TEST_IO_STREAM(getMmapPositionNoMmap,
922 "Get a stream Mmap position before mapping it should fail",
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800923 ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
924
Kevin Rocard72e50e22017-05-05 14:02:55 -0700925TEST_IO_STREAM(close, "Make sure a stream can be closed",
926 ASSERT_OK(closeStream()))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800927TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
Kevin Rocard72e50e22017-05-05 14:02:55 -0700928 ASSERT_OK(closeStream());
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800929 ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
930
Kevin Rocardf8500dc2017-05-03 10:43:21 -0700931static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS,
932 Result::NOT_SUPPORTED};
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800933static void testCreateTooBigMmapBuffer(IStream* stream) {
934 MmapBufferInfo info;
935 Result res;
936 // Assume that int max is a value too big to be allocated
Kevin Rocard72e50e22017-05-05 14:02:55 -0700937 // This is true currently with a 32bit media server, but might not when it
938 // will run in 64 bit
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800939 auto minSizeFrames = std::numeric_limits<int32_t>::max();
940 ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
941 ASSERT_RESULT(invalidArgsOrNotSupported, res);
Kevin Rocardf0357882017-02-10 16:19:28 -0800942}
943
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800944TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
945 testCreateTooBigMmapBuffer(stream.get()))
946
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800947static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
948 Result res;
949 MmapPosition position;
950 ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
951 ASSERT_RESULT(invalidArgsOrNotSupported, res);
952}
953
Kevin Rocard72e50e22017-05-05 14:02:55 -0700954TEST_IO_STREAM(
955 GetMmapPositionOfNonMmapedStream,
956 "Retrieving the mmap position of a non mmaped stream should fail",
957 testGetMmapPositionOfNonMmapedStream(stream.get()))
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800958
Kevin Rocardf0357882017-02-10 16:19:28 -0800959//////////////////////////////////////////////////////////////////////////////
Kevin Rocardc9963522017-03-10 18:47:37 -0800960///////////////////////////////// StreamIn ///////////////////////////////////
961//////////////////////////////////////////////////////////////////////////////
962
963TEST_P(InputStreamTest, GetAudioSource) {
Kevin Rocard72e50e22017-05-05 14:02:55 -0700964 doc::test(
965 "Retrieving the audio source of an input stream should always succeed");
Kevin Rocardc9963522017-03-10 18:47:37 -0800966 AudioSource source;
967 ASSERT_OK(stream->getAudioSource(returnIn(res, source)));
Kevin Rocard98390a62017-05-03 11:16:05 -0700968 if (res == Result::NOT_SUPPORTED) {
969 doc::partialTest("getAudioSource is not supported");
970 return;
971 }
Kevin Rocardc9963522017-03-10 18:47:37 -0800972 ASSERT_OK(res);
973 ASSERT_EQ(AudioSource::DEFAULT, source);
974}
975
Kevin Rocard72e50e22017-05-05 14:02:55 -0700976static void testUnitaryGain(std::function<Return<Result>(float)> setGain) {
Kevin Rocardc4f1b2f2017-05-03 11:19:25 -0700977 for (float value :
978 (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(),
979 2.0, INFINITY, NAN}) {
Kevin Rocarda1d6ea42017-05-08 17:08:11 -0700980 EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value="
981 << value;
Kevin Rocardc9963522017-03-10 18:47:37 -0800982 }
Kevin Rocardc4f1b2f2017-05-03 11:19:25 -0700983 // Do not consider -0.0 as an invalid value as it is == with 0.0
984 for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) {
Kevin Rocarda1d6ea42017-05-08 17:08:11 -0700985 EXPECT_OK(setGain(value)) << "value=" << value;
Kevin Rocardc4f1b2f2017-05-03 11:19:25 -0700986 }
Kevin Rocardc9963522017-03-10 18:47:37 -0800987}
988
Kevin Rocard98390a62017-05-03 11:16:05 -0700989static void testOptionalUnitaryGain(
990 std::function<Return<Result>(float)> setGain, string debugName) {
991 auto result = setGain(1);
Kevin Rocardf26f67a2017-05-02 19:21:58 -0700992 ASSERT_IS_OK(result);
Kevin Rocard98390a62017-05-03 11:16:05 -0700993 if (result == Result::NOT_SUPPORTED) {
994 doc::partialTest(debugName + " is not supported");
995 return;
996 }
997 testUnitaryGain(setGain);
998}
999
Kevin Rocardc9963522017-03-10 18:47:37 -08001000TEST_P(InputStreamTest, SetGain) {
1001 doc::test("The gain of an input stream should only be set between [0,1]");
Kevin Rocard98390a62017-05-03 11:16:05 -07001002 testOptionalUnitaryGain(
1003 [this](float volume) { return stream->setGain(volume); },
1004 "InputStream::setGain");
Kevin Rocardc9963522017-03-10 18:47:37 -08001005}
1006
Kevin Rocard72e50e22017-05-05 14:02:55 -07001007static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize,
1008 uint32_t framesCount) {
Kevin Rocardc9963522017-03-10 18:47:37 -08001009 Result res;
1010 // Ignore output parameters as the call should fail
Kevin Rocard72e50e22017-05-05 14:02:55 -07001011 ASSERT_OK(stream->prepareForReading(
1012 frameSize, framesCount,
1013 [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
Kevin Rocardfcf186b2017-05-03 11:16:05 -07001014 EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
Kevin Rocardc9963522017-03-10 18:47:37 -08001015}
1016
Kevin Rocard195205b2017-05-02 18:34:59 -07001017TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
1018 doc::test(
1019 "Preparing a stream for reading with a 0 sized buffer should fail");
1020 testPrepareForReading(stream.get(), 0, 0);
1021}
1022
Kevin Rocardc9963522017-03-10 18:47:37 -08001023TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001024 doc::test(
1025 "Preparing a stream for reading with a 2^32 sized buffer should fail");
1026 testPrepareForReading(stream.get(), 1,
1027 std::numeric_limits<uint32_t>::max());
Kevin Rocardc9963522017-03-10 18:47:37 -08001028}
1029
1030TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001031 doc::test(
1032 "Preparing a stream for reading with a overflowing sized buffer should "
1033 "fail");
Kevin Rocardc9963522017-03-10 18:47:37 -08001034 auto uintMax = std::numeric_limits<uint32_t>::max();
1035 testPrepareForReading(stream.get(), uintMax, uintMax);
1036}
1037
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001038TEST_P(InputStreamTest, GetInputFramesLost) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001039 doc::test(
1040 "The number of frames lost on a never started stream should be 0");
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001041 auto ret = stream->getInputFramesLost();
Kevin Rocardf26f67a2017-05-02 19:21:58 -07001042 ASSERT_IS_OK(ret);
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001043 uint32_t framesLost{ret};
1044 ASSERT_EQ(0U, framesLost);
1045}
1046
Kevin Rocardc9963522017-03-10 18:47:37 -08001047TEST_P(InputStreamTest, getCapturePosition) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001048 doc::test(
1049 "The capture position of a non prepared stream should not be "
1050 "retrievable");
Kevin Rocardc9963522017-03-10 18:47:37 -08001051 uint64_t frames;
1052 uint64_t time;
1053 ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
1054 ASSERT_RESULT(invalidStateOrNotSupported, res);
1055}
1056
1057//////////////////////////////////////////////////////////////////////////////
Kevin Rocard624800c2017-03-10 18:47:37 -08001058///////////////////////////////// StreamIn ///////////////////////////////////
1059//////////////////////////////////////////////////////////////////////////////
1060
1061TEST_P(OutputStreamTest, getLatency) {
1062 doc::test("Make sure latency is over 0");
1063 auto result = stream->getLatency();
Kevin Rocardf26f67a2017-05-02 19:21:58 -07001064 ASSERT_IS_OK(result);
Kevin Rocard624800c2017-03-10 18:47:37 -08001065 ASSERT_GT(result, 0U);
1066}
1067
1068TEST_P(OutputStreamTest, setVolume) {
1069 doc::test("Try to set the output volume");
Kevin Rocard98390a62017-05-03 11:16:05 -07001070 testOptionalUnitaryGain(
1071 [this](float volume) { return stream->setVolume(volume, volume); },
1072 "setVolume");
Kevin Rocard624800c2017-03-10 18:47:37 -08001073}
1074
Kevin Rocard72e50e22017-05-05 14:02:55 -07001075static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize,
1076 uint32_t framesCount) {
Kevin Rocard624800c2017-03-10 18:47:37 -08001077 Result res;
1078 // Ignore output parameters as the call should fail
Kevin Rocard72e50e22017-05-05 14:02:55 -07001079 ASSERT_OK(stream->prepareForWriting(
1080 frameSize, framesCount,
1081 [&res](auto r, auto&, auto&, auto&, auto&) { res = r; }));
Kevin Rocardfcf186b2017-05-03 11:16:05 -07001082 EXPECT_RESULT(Result::INVALID_ARGUMENTS, res);
Kevin Rocard624800c2017-03-10 18:47:37 -08001083}
1084
Kevin Rocard195205b2017-05-02 18:34:59 -07001085TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
1086 doc::test(
1087 "Preparing a stream for writing with a 0 sized buffer should fail");
1088 testPrepareForWriting(stream.get(), 0, 0);
1089}
1090
Kevin Rocard624800c2017-03-10 18:47:37 -08001091TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001092 doc::test(
1093 "Preparing a stream for writing with a 2^32 sized buffer should fail");
1094 testPrepareForWriting(stream.get(), 1,
1095 std::numeric_limits<uint32_t>::max());
Kevin Rocard624800c2017-03-10 18:47:37 -08001096}
1097
1098TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001099 doc::test(
1100 "Preparing a stream for writing with a overflowing sized buffer should "
1101 "fail");
Kevin Rocard624800c2017-03-10 18:47:37 -08001102 auto uintMax = std::numeric_limits<uint32_t>::max();
1103 testPrepareForWriting(stream.get(), uintMax, uintMax);
1104}
1105
1106struct Capability {
1107 Capability(IStreamOut* stream) {
1108 EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
1109 auto ret = stream->supportsDrain();
Kevin Rocardf26f67a2017-05-02 19:21:58 -07001110 EXPECT_IS_OK(ret);
Kevin Rocard624800c2017-03-10 18:47:37 -08001111 if (ret.isOk()) {
1112 drain = ret;
1113 }
1114 }
1115 bool pause = false;
1116 bool resume = false;
1117 bool drain = false;
1118};
1119
1120TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001121 doc::test(
1122 "Implementation must expose pause, resume and drain capabilities");
Kevin Rocard624800c2017-03-10 18:47:37 -08001123 Capability(stream.get());
1124}
1125
Kevin Rocard304b6c82017-05-03 10:57:06 -07001126template <class Value>
1127static void checkInvalidStateOr0(Result res, Value value) {
1128 switch (res) {
1129 case Result::INVALID_STATE:
1130 break;
1131 case Result::OK:
1132 ASSERT_EQ(0U, value);
1133 break;
1134 default:
1135 FAIL() << "Unexpected result " << toString(res);
1136 }
1137}
1138
Kevin Rocard624800c2017-03-10 18:47:37 -08001139TEST_P(OutputStreamTest, GetRenderPosition) {
Kevin Rocard304b6c82017-05-03 10:57:06 -07001140 doc::test("A new stream render position should be 0 or INVALID_STATE");
Kevin Rocard624800c2017-03-10 18:47:37 -08001141 uint32_t dspFrames;
1142 ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames)));
1143 if (res == Result::NOT_SUPPORTED) {
1144 doc::partialTest("getRenderPosition is not supported");
1145 return;
1146 }
Kevin Rocard304b6c82017-05-03 10:57:06 -07001147 checkInvalidStateOr0(res, dspFrames);
Kevin Rocard624800c2017-03-10 18:47:37 -08001148}
1149
1150TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
Kevin Rocard304b6c82017-05-03 10:57:06 -07001151 doc::test("A new stream next write timestamp should be 0 or INVALID_STATE");
Kevin Rocard624800c2017-03-10 18:47:37 -08001152 uint64_t timestampUs;
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001153 ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs)));
Kevin Rocard624800c2017-03-10 18:47:37 -08001154 if (res == Result::NOT_SUPPORTED) {
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001155 doc::partialTest("getNextWriteTimestamp is not supported");
Kevin Rocard624800c2017-03-10 18:47:37 -08001156 return;
1157 }
Kevin Rocard304b6c82017-05-03 10:57:06 -07001158 checkInvalidStateOr0(res, timestampUs);
Kevin Rocard624800c2017-03-10 18:47:37 -08001159}
1160
1161/** Stub implementation of out stream callback. */
1162class MockOutCallbacks : public IStreamOutCallback {
1163 Return<void> onWriteReady() override { return {}; }
1164 Return<void> onDrainReady() override { return {}; }
1165 Return<void> onError() override { return {}; }
1166};
1167
Kevin Rocard72e50e22017-05-05 14:02:55 -07001168static bool isAsyncModeSupported(IStreamOut* stream) {
Kevin Rocard624800c2017-03-10 18:47:37 -08001169 auto res = stream->setCallback(new MockOutCallbacks);
Kevin Rocard72e50e22017-05-05 14:02:55 -07001170 stream->clearCallback(); // try to restore the no callback state, ignore
1171 // any error
1172 auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
Kevin Rocard624800c2017-03-10 18:47:37 -08001173 EXPECT_RESULT(okOrNotSupported, res);
1174 return res.isOk() ? res == Result::OK : false;
1175}
1176
1177TEST_P(OutputStreamTest, SetCallback) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001178 doc::test(
1179 "If supported, registering callback for async operation should never "
1180 "fail");
Kevin Rocard624800c2017-03-10 18:47:37 -08001181 if (!isAsyncModeSupported(stream.get())) {
1182 doc::partialTest("The stream does not support async operations");
1183 return;
1184 }
1185 ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1186 ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1187}
1188
1189TEST_P(OutputStreamTest, clearCallback) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001190 doc::test(
1191 "If supported, clearing a callback to go back to sync operation should "
1192 "not fail");
Kevin Rocard624800c2017-03-10 18:47:37 -08001193 if (!isAsyncModeSupported(stream.get())) {
1194 doc::partialTest("The stream does not support async operations");
1195 return;
1196 }
1197 // TODO: Clarify if clearing a non existing callback should fail
1198 ASSERT_OK(stream->setCallback(new MockOutCallbacks));
1199 ASSERT_OK(stream->clearCallback());
1200}
1201
1202TEST_P(OutputStreamTest, Resume) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001203 doc::test(
1204 "If supported, a stream should fail to resume if not previously "
1205 "paused");
Kevin Rocard624800c2017-03-10 18:47:37 -08001206 if (!Capability(stream.get()).resume) {
1207 doc::partialTest("The output stream does not support resume");
1208 return;
1209 }
1210 ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1211}
1212
1213TEST_P(OutputStreamTest, Pause) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001214 doc::test(
1215 "If supported, a stream should fail to pause if not previously "
1216 "started");
Kevin Rocard624800c2017-03-10 18:47:37 -08001217 if (!Capability(stream.get()).pause) {
1218 doc::partialTest("The output stream does not support pause");
1219 return;
1220 }
1221 ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
1222}
1223
Kevin Rocard72e50e22017-05-05 14:02:55 -07001224static void testDrain(IStreamOut* stream, AudioDrain type) {
Kevin Rocard624800c2017-03-10 18:47:37 -08001225 if (!Capability(stream).drain) {
Kevin Rocard6f226802017-04-03 10:29:34 -07001226 doc::partialTest("The output stream does not support drain");
Kevin Rocard624800c2017-03-10 18:47:37 -08001227 return;
1228 }
1229 ASSERT_RESULT(Result::OK, stream->drain(type));
1230}
1231
1232TEST_P(OutputStreamTest, DrainAll) {
Kevin Rocard6f226802017-04-03 10:29:34 -07001233 doc::test("If supported, a stream should always succeed to drain");
Kevin Rocard624800c2017-03-10 18:47:37 -08001234 testDrain(stream.get(), AudioDrain::ALL);
1235}
1236
1237TEST_P(OutputStreamTest, DrainEarlyNotify) {
Kevin Rocard6f226802017-04-03 10:29:34 -07001238 doc::test("If supported, a stream should always succeed to drain");
Kevin Rocard624800c2017-03-10 18:47:37 -08001239 testDrain(stream.get(), AudioDrain::EARLY_NOTIFY);
1240}
1241
1242TEST_P(OutputStreamTest, FlushStop) {
Kevin Rocard6f226802017-04-03 10:29:34 -07001243 doc::test("If supported, a stream should always succeed to flush");
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001244 auto ret = stream->flush();
Kevin Rocardf26f67a2017-05-02 19:21:58 -07001245 ASSERT_IS_OK(ret);
Kevin Rocarde9a8fb72017-03-21 11:39:55 -07001246 if (ret == Result::NOT_SUPPORTED) {
1247 doc::partialTest("Flush is not supported");
1248 return;
1249 }
1250 ASSERT_OK(ret);
Kevin Rocard624800c2017-03-10 18:47:37 -08001251}
1252
1253TEST_P(OutputStreamTest, GetPresentationPositionStop) {
Kevin Rocard72e50e22017-05-05 14:02:55 -07001254 doc::test(
1255 "If supported, a stream should always succeed to retrieve the "
1256 "presentation position");
Kevin Rocard624800c2017-03-10 18:47:37 -08001257 uint64_t frames;
1258 TimeSpec mesureTS;
1259 ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS)));
1260 if (res == Result::NOT_SUPPORTED) {
1261 doc::partialTest("getpresentationPosition is not supported");
1262 return;
1263 }
1264 ASSERT_EQ(0U, frames);
1265
Kevin Rocard476e38f2017-05-03 10:52:43 -07001266 if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) {
1267 // As the stream has never written a frame yet,
1268 // the timestamp does not really have a meaning, allow to return 0
1269 return;
1270 }
1271
1272 // Make sure the return measure is not more than 1s old.
Kevin Rocard624800c2017-03-10 18:47:37 -08001273 struct timespec currentTS;
1274 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &currentTS)) << errno;
1275
Kevin Rocard72e50e22017-05-05 14:02:55 -07001276 auto toMicroSec = [](uint64_t sec, auto nsec) {
1277 return sec * 1e+6 + nsec / 1e+3;
1278 };
Kevin Rocard624800c2017-03-10 18:47:37 -08001279 auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec);
1280 auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec);
Kevin Rocard72e50e22017-05-05 14:02:55 -07001281 ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime,
1282 mesureTime);
Kevin Rocard624800c2017-03-10 18:47:37 -08001283}
1284
Kevin Rocard624800c2017-03-10 18:47:37 -08001285//////////////////////////////////////////////////////////////////////////////
Kevin Rocard3c405a72017-03-08 16:46:51 -08001286/////////////////////////////// PrimaryDevice ////////////////////////////////
1287//////////////////////////////////////////////////////////////////////////////
1288
1289TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
1290 doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
Chih-Hung Hsieh7eb57b62017-05-15 12:31:25 -07001291 testUnitaryGain([](float volume) { return device->setVoiceVolume(volume); });
Kevin Rocard3c405a72017-03-08 16:46:51 -08001292}
1293
1294TEST_F(AudioPrimaryHidlTest, setMode) {
Kevin Rocard04364ed2017-05-02 18:16:00 -07001295 doc::test(
1296 "Make sure setMode always succeeds if mode is valid "
1297 "and fails otherwise");
1298 // Test Invalid values
1299 for (AudioMode mode :
1300 {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
1301 SCOPED_TRACE("mode=" + toString(mode));
1302 ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
1303 }
1304 // Test valid values
Kevin Rocard72e50e22017-05-05 14:02:55 -07001305 for (AudioMode mode :
1306 {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
Kevin Rocard72e50e22017-05-05 14:02:55 -07001307 AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
Kevin Rocard3c405a72017-03-08 16:46:51 -08001308 SCOPED_TRACE("mode=" + toString(mode));
1309 ASSERT_OK(device->setMode(mode));
1310 }
Kevin Rocard3c405a72017-03-08 16:46:51 -08001311}
1312
Kevin Rocard3c405a72017-03-08 16:46:51 -08001313TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
1314 doc::test("Query and set the BT SCO NR&EC state");
1315 testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
Kevin Rocard72e50e22017-05-05 14:02:55 -07001316 &IPrimaryDevice::setBtScoNrecEnabled,
1317 &IPrimaryDevice::getBtScoNrecEnabled);
Kevin Rocard3c405a72017-03-08 16:46:51 -08001318}
1319
1320TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
1321 doc::test("Query and set the SCO whideband state");
1322 testOptionalAccessors("BtScoWideband", {true, false, true},
Kevin Rocard72e50e22017-05-05 14:02:55 -07001323 &IPrimaryDevice::setBtScoWidebandEnabled,
1324 &IPrimaryDevice::getBtScoWidebandEnabled);
Kevin Rocard3c405a72017-03-08 16:46:51 -08001325}
1326
1327using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
1328TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
1329 doc::test("Query and set the TTY mode state");
Kevin Rocard72e50e22017-05-05 14:02:55 -07001330 testOptionalAccessors(
1331 "TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
1332 &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
Kevin Rocard3c405a72017-03-08 16:46:51 -08001333}
1334
1335TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
1336 doc::test("Query and set the HAC state");
Kevin Rocard98390a62017-05-03 11:16:05 -07001337 testOptionalAccessors("HAC", {true, false, true},
1338 &IPrimaryDevice::setHacEnabled,
1339 &IPrimaryDevice::getHacEnabled);
Kevin Rocard3c405a72017-03-08 16:46:51 -08001340}
1341
1342//////////////////////////////////////////////////////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -08001343//////////////////// Clean caches on global tear down ////////////////////////
1344//////////////////////////////////////////////////////////////////////////////
1345
1346int main(int argc, char** argv) {
1347 environment = new Environment;
1348 ::testing::AddGlobalTestEnvironment(environment);
1349 ::testing::InitGoogleTest(&argc, argv);
1350 int status = RUN_ALL_TESTS();
Kevin Rocardf0357882017-02-10 16:19:28 -08001351 return status;
1352}