blob: 69f86f6044416ae42f27642ff0ae673a84d7f8c8 [file] [log] [blame]
Kevin Rocardf0357882017-02-10 16:19:28 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "VtsHalAudioV2_0TargetTest"
18
19#include <algorithm>
20#include <cmath>
21#include <cstddef>
22#include <cstdio>
23#include <limits>
24#include <list>
25#include <string>
26#include <type_traits>
27#include <vector>
28
Yuexi Ma161b5642017-03-10 13:44:22 -080029#include <VtsHalHidlTargetTestBase.h>
Kevin Rocardf0357882017-02-10 16:19:28 -080030
31#include <android-base/logging.h>
32
33#include <android/hardware/audio/2.0/IDevice.h>
34#include <android/hardware/audio/2.0/IDevicesFactory.h>
Kevin Rocard3c405a72017-03-08 16:46:51 -080035#include <android/hardware/audio/2.0/IPrimaryDevice.h>
Kevin Rocardf0357882017-02-10 16:19:28 -080036#include <android/hardware/audio/2.0/types.h>
37#include <android/hardware/audio/common/2.0/types.h>
38
39#include "utility/ReturnIn.h"
40#include "utility/AssertOk.h"
41#include "utility/PrettyPrintAudioTypes.h"
42
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;
52using ::android::hardware::audio::V2_0::DeviceAddress;
53using ::android::hardware::audio::V2_0::IDevice;
Kevin Rocard3c405a72017-03-08 16:46:51 -080054using ::android::hardware::audio::V2_0::IPrimaryDevice;
55using TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode;
Kevin Rocardf0357882017-02-10 16:19:28 -080056using ::android::hardware::audio::V2_0::IDevicesFactory;
57using ::android::hardware::audio::V2_0::IStream;
58using ::android::hardware::audio::V2_0::IStreamIn;
59using ::android::hardware::audio::V2_0::IStreamOut;
Kevin Rocard8878b4b2017-03-10 18:47:37 -080060using ::android::hardware::audio::V2_0::MmapBufferInfo;
61using ::android::hardware::audio::V2_0::MmapPosition;
Kevin Rocardf0357882017-02-10 16:19:28 -080062using ::android::hardware::audio::V2_0::ParameterValue;
63using ::android::hardware::audio::V2_0::Result;
64using ::android::hardware::audio::common::V2_0::AudioChannelMask;
65using ::android::hardware::audio::common::V2_0::AudioConfig;
66using ::android::hardware::audio::common::V2_0::AudioDevice;
67using ::android::hardware::audio::common::V2_0::AudioFormat;
68using ::android::hardware::audio::common::V2_0::AudioHandleConsts;
69using ::android::hardware::audio::common::V2_0::AudioInputFlag;
70using ::android::hardware::audio::common::V2_0::AudioIoHandle;
Kevin Rocard3c405a72017-03-08 16:46:51 -080071using ::android::hardware::audio::common::V2_0::AudioMode;
Kevin Rocardf0357882017-02-10 16:19:28 -080072using ::android::hardware::audio::common::V2_0::AudioOffloadInfo;
73using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
74using ::android::hardware::audio::common::V2_0::AudioSource;
75
76using utility::returnIn;
77
78namespace doc {
79/** Document the current test case.
80 * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test will output:
81 * <testcase name="debugDump" status="run" time="6" classname="AudioPrimaryHidlTest"
82 description="Dump the state of the hal." />
83 * see https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information
84 */
85void test(const std::string& testCaseDocumentation) {
86 ::testing::Test::RecordProperty("description", testCaseDocumentation);
87}
88
89/** Document why a test was not fully run. Usually due to an optional feature not implemented. */
90void partialTest(const std::string& reason) {
91 ::testing::Test::RecordProperty("partialyRunTest", reason);
92}
93}
94
95// Register callback for static object destruction
96// Avoid destroying static objects after main return.
97// Post main return destruction leads to incorrect gtest timing measurements as well as harder
98// debuging if anything goes wrong during destruction.
99class Environment : public ::testing::Environment {
100public:
101 using TearDownFunc = std::function<void ()>;
102 void registerTearDown(TearDownFunc&& tearDown) {
103 tearDowns.push_back(std::move(tearDown));
104 }
105
106private:
107 void TearDown() override {
108 // Call the tear downs in reverse order of insertion
109 for (auto& tearDown : tearDowns) {
110 tearDown();
111 }
112 }
113 std::list<TearDownFunc> tearDowns;
114};
115// Instance to register global tearDown
116static Environment* environment;
117
Yuexi Ma161b5642017-03-10 13:44:22 -0800118class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
Kevin Rocardf0357882017-02-10 16:19:28 -0800119protected:
120 // Convenient member to store results
121 Result res;
122};
123
124//////////////////////////////////////////////////////////////////////////////
125////////////////////// getService audio_devices_factory //////////////////////
126//////////////////////////////////////////////////////////////////////////////
127
128// Test all audio devices
129class AudioHidlTest : public HidlTest {
130public:
131 void SetUp() override {
132 ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base
133
134 if (devicesFactory == nullptr) {
135 environment->registerTearDown([]{ devicesFactory.clear(); });
Yuexi Ma161b5642017-03-10 13:44:22 -0800136 devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>();
Kevin Rocardf0357882017-02-10 16:19:28 -0800137 }
138 ASSERT_TRUE(devicesFactory != nullptr);
139 }
140
141protected:
142 // Cache the devicesFactory retrieval to speed up each test by ~0.5s
143 static sp<IDevicesFactory> devicesFactory;
144};
145sp<IDevicesFactory> AudioHidlTest::devicesFactory;
146
147TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
148 doc::test("test the getService (called in SetUp)");
149}
150
151//////////////////////////////////////////////////////////////////////////////
152/////////////////////////////// openDevice primary ///////////////////////////
153//////////////////////////////////////////////////////////////////////////////
154
155// Test the primary device
156class AudioPrimaryHidlTest : public AudioHidlTest {
157public:
158 /** Primary HAL test are NOT thread safe. */
159 void SetUp() override {
160 ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
161
162 if (device == nullptr) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800163 IDevicesFactory::Result result;
Kevin Rocard3c405a72017-03-08 16:46:51 -0800164 sp<IDevice> baseDevice;
Kevin Rocardf0357882017-02-10 16:19:28 -0800165 ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
Kevin Rocard3c405a72017-03-08 16:46:51 -0800166 returnIn(result, baseDevice)));
167 ASSERT_TRUE(baseDevice != nullptr);
168
169 environment->registerTearDown([]{ device.clear(); });
170 device = IPrimaryDevice::castFrom(baseDevice);
171 ASSERT_TRUE(device != nullptr);
Kevin Rocardf0357882017-02-10 16:19:28 -0800172 }
Kevin Rocardf0357882017-02-10 16:19:28 -0800173 }
174
175protected:
176 // Cache the device opening to speed up each test by ~0.5s
Kevin Rocard3c405a72017-03-08 16:46:51 -0800177 static sp<IPrimaryDevice> device;
Kevin Rocardf0357882017-02-10 16:19:28 -0800178};
Kevin Rocard3c405a72017-03-08 16:46:51 -0800179sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
Kevin Rocardf0357882017-02-10 16:19:28 -0800180
181TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
182 doc::test("Test the openDevice (called in SetUp)");
183}
184
185TEST_F(AudioPrimaryHidlTest, Init) {
186 doc::test("Test that the audio primary hal initialized correctly");
187 ASSERT_OK(device->initCheck());
188}
189
190//////////////////////////////////////////////////////////////////////////////
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800191///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800192//////////////////////////////////////////////////////////////////////////////
193
Kevin Rocard3c405a72017-03-08 16:46:51 -0800194template <class Property>
195class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
Kevin Rocardf0357882017-02-10 16:19:28 -0800196protected:
Kevin Rocard3c405a72017-03-08 16:46:51 -0800197
198 /** Test a property getter and setter. */
Kevin Rocardf0357882017-02-10 16:19:28 -0800199 template <class Getter, class Setter>
Kevin Rocard3c405a72017-03-08 16:46:51 -0800200 void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800201 Setter setter, Getter getter,
202 const vector<Property>& invalidValues = {}) {
Kevin Rocard3c405a72017-03-08 16:46:51 -0800203
204 Property initialValue; // Save initial value to restore it at the end of the test
205 ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
206 ASSERT_OK(res);
207
208 for (Property setValue : valuesToTest) {
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800209 SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
210 testing::PrintToString(setValue));
Kevin Rocard3c405a72017-03-08 16:46:51 -0800211 ASSERT_OK((device.get()->*setter)(setValue));
212 Property getValue;
213 // Make sure the getter returns the same value just set
214 ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
Kevin Rocardf0357882017-02-10 16:19:28 -0800215 ASSERT_OK(res);
Kevin Rocard3c405a72017-03-08 16:46:51 -0800216 EXPECT_EQ(setValue, getValue);
Kevin Rocardf0357882017-02-10 16:19:28 -0800217 }
Kevin Rocard3c405a72017-03-08 16:46:51 -0800218
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800219 for (Property invalidValue : invalidValues) {
220 SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
221 testing::PrintToString(invalidValue));
Kevin Rocard20e7af62017-03-10 17:10:43 -0800222 EXPECT_RESULT(Result::INVALID_ARGUMENTS, (device.get()->*setter)(invalidValue));
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800223 }
224
Kevin Rocard3c405a72017-03-08 16:46:51 -0800225 ASSERT_OK((device.get()->*setter)(initialValue)); // restore initial value
226 }
227
228 /** Test the getter and setter of an optional feature. */
229 template <class Getter, class Setter>
230 void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800231 Setter setter, Getter getter,
232 const vector<Property>& invalidValues = {}) {
Kevin Rocard3c405a72017-03-08 16:46:51 -0800233 doc::test("Test the optional " + propertyName + " getters and setter");
234 {
235 SCOPED_TRACE("Test feature support by calling the getter");
236 Property initialValue;
237 ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
238 if (res == Result::NOT_SUPPORTED) {
239 doc::partialTest(propertyName + " getter is not supported");
240 return;
241 }
242 ASSERT_OK(res); // If it is supported it must succeed
243 }
244 // The feature is supported, test it
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800245 testAccessors(propertyName, valuesToTest, setter, getter, invalidValues);
Kevin Rocardf0357882017-02-10 16:19:28 -0800246 }
247};
248
Kevin Rocard3c405a72017-03-08 16:46:51 -0800249using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
250
Kevin Rocardf0357882017-02-10 16:19:28 -0800251TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
252 doc::test("Check that the mic can be muted and unmuted");
Kevin Rocard3c405a72017-03-08 16:46:51 -0800253 testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
Kevin Rocardf0357882017-02-10 16:19:28 -0800254 // TODO: check that the mic is really muted (all sample are 0)
255}
256
257TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
258 doc::test("If master mute is supported, try to mute and unmute the master output");
Kevin Rocard3c405a72017-03-08 16:46:51 -0800259 testOptionalAccessors("master mute", {true, false, true},
260 &IDevice::setMasterMute, &IDevice::getMasterMute);
Kevin Rocardf0357882017-02-10 16:19:28 -0800261 // TODO: check that the master volume is really muted
262}
263
Kevin Rocard92ce35d2017-03-08 17:17:25 -0800264using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
265TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
266 doc::test("Test the master volume if supported");
267 testOptionalAccessors("master volume", {0, 0.5, 1},
268 &IDevice::setMasterVolume, &IDevice::getMasterVolume,
269 {-0.1, 1.1, NAN, INFINITY, -INFINITY,
270 1 + std::numeric_limits<float>::epsilon()});
271 // TODO: check that the master volume is really changed
272}
273
Kevin Rocardf0357882017-02-10 16:19:28 -0800274//////////////////////////////////////////////////////////////////////////////
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800275//////////////////////////////// AudioPatches ////////////////////////////////
276//////////////////////////////////////////////////////////////////////////////
277
278class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
279protected:
280 bool areAudioPatchesSupported() {
281 auto result = device->supportsAudioPatches();
282 EXPECT_TRUE(result.isOk());
283 return result;
284 }
285};
286
287TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
288 doc::test("Test if audio patches are supported");
289 if (!areAudioPatchesSupported()) {
290 doc::partialTest("Audio patches are not supported");
291 return;
292 }
293 // TODO: test audio patches
294}
295
296
297//////////////////////////////////////////////////////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800298//////////////// Required and recommended audio format support ///////////////
299// From: https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
300// From: https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
301/////////// TODO: move to the beginning of the file for easier update ////////
302//////////////////////////////////////////////////////////////////////////////
303
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800304class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
Kevin Rocardf0357882017-02-10 16:19:28 -0800305public:
306 // Cache result ?
307 static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
308 return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
309 {8000, 11025, 16000, 22050, 32000, 44100},
310 {AudioFormat::PCM_16_BIT});
311 }
312
313 static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
314 return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
315 {24000, 48000},
316 {AudioFormat::PCM_16_BIT});
317 }
318
319 static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
320 // TODO: retrieve audio config supported by the platform
321 // as declared in the policy configuration
322 return {};
323 }
324
325 static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
326 return combineAudioConfig({AudioChannelMask::IN_MONO},
327 {8000, 11025, 16000, 44100},
328 {AudioFormat::PCM_16_BIT});
329 }
330 static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
331 return combineAudioConfig({AudioChannelMask::IN_STEREO},
332 {22050, 48000},
333 {AudioFormat::PCM_16_BIT});
334 }
335 static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
336 // TODO: retrieve audio config supported by the platform
337 // as declared in the policy configuration
338 return {};
339 }
340private:
341 static const vector<AudioConfig> combineAudioConfig(
342 vector<AudioChannelMask> channelMasks,
343 vector<uint32_t> sampleRates,
344 vector<AudioFormat> formats) {
345 vector<AudioConfig> configs;
346 for (auto channelMask: channelMasks) {
347 for (auto sampleRate : sampleRates) {
348 for (auto format : formats) {
349 AudioConfig config{};
350 // leave offloadInfo to 0
351 config.channelMask = channelMask;
352 config.sampleRateHz = sampleRate;
353 config.format = format;
354 // FIXME: leave frameCount to 0 ?
355 configs.push_back(config);
356 }
357 }
358 }
359 return configs;
360 }
361};
362
Kevin Rocard9c369142017-03-08 17:17:25 -0800363/** Generate a test name based on an audio config.
364 *
365 * As the only parameter changing are channel mask and sample rate,
366 * only print those ones in the test name.
367 */
368static string generateTestName(const testing::TestParamInfo<AudioConfig>& info) {
369 const AudioConfig& config = info.param;
370 return to_string(info.index) + "__" + to_string(config.sampleRateHz)+ "_" +
371 // "MONO" is more clear than "FRONT_LEFT"
372 ((config.channelMask == AudioChannelMask::OUT_MONO ||
373 config.channelMask == AudioChannelMask::IN_MONO) ?
374 "MONO" : toString(config.channelMask));
375}
376
Kevin Rocardf0357882017-02-10 16:19:28 -0800377//////////////////////////////////////////////////////////////////////////////
378///////////////////////////// getInputBufferSize /////////////////////////////
379//////////////////////////////////////////////////////////////////////////////
380
381// FIXME: execute input test only if platform declares android.hardware.microphone
382// how to get this value ? is it a property ???
383
384class AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest,
385 public ::testing::WithParamInterface<AudioConfig> {
386protected:
387 void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
388 uint64_t bufferSize;
389 ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
390
391 switch (res) {
392 case Result::INVALID_ARGUMENTS:
393 EXPECT_FALSE(supportRequired);
394 break;
395 case Result::OK:
396 // Check that the buffer is of a sane size
397 // For now only that it is > 0
398 EXPECT_GT(bufferSize, uint64_t(0));
399 break;
400 default:
401 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
402 }
403 }
404};
405
406// Test that the required capture config and those declared in the policy are indeed supported
407class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
408TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
409 doc::test("Input buffer size must be retrievable for a format with required support.");
410 inputBufferSizeTest(GetParam(), true);
411}
412INSTANTIATE_TEST_CASE_P(
413 RequiredInputBufferSize, RequiredInputBufferSizeTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800414 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
415 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800416INSTANTIATE_TEST_CASE_P(
417 SupportedInputBufferSize, RequiredInputBufferSizeTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800418 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
419 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800420
421// Test that the recommended capture config are supported or lead to a INVALID_ARGUMENTS return
422class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
423TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
424 doc::test("Input buffer size should be retrievable for a format with recommended support.");
425 inputBufferSizeTest(GetParam(), false);
426}
427INSTANTIATE_TEST_CASE_P(
428 RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800429 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
430 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800431
432//////////////////////////////////////////////////////////////////////////////
433/////////////////////////////// setScreenState ///////////////////////////////
434//////////////////////////////////////////////////////////////////////////////
435
436TEST_F(AudioPrimaryHidlTest, setScreenState) {
437 doc::test("Check that the hal can receive the screen state");
438 for (bool turnedOn : {false, true, true, false, false}) {
439 auto ret = device->setScreenState(turnedOn);
440 ASSERT_TRUE(ret.isOk());
441 Result result = ret;
442 ASSERT_TRUE(result == Result::OK || result == Result::NOT_SUPPORTED) << toString(result);
443 }
444}
445
446//////////////////////////////////////////////////////////////////////////////
447//////////////////////////// {get,set}Parameters /////////////////////////////
448//////////////////////////////////////////////////////////////////////////////
449
450TEST_F(AudioPrimaryHidlTest, getParameters) {
451 doc::test("Check that the hal can set and get parameters");
452 hidl_vec<hidl_string> keys;
453 hidl_vec<ParameterValue> values;
454 ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
455 ASSERT_OK(device->setParameters(values));
456 values.resize(0);
457 ASSERT_OK(device->setParameters(values));
458}
459
460//////////////////////////////////////////////////////////////////////////////
461//////////////////////////////// debugDebug //////////////////////////////////
462//////////////////////////////////////////////////////////////////////////////
463
Kevin Rocardb9031242017-03-13 12:20:54 -0700464template <class DebugDump>
465static void testDebugDump(DebugDump debugDump) {
Kevin Rocardf0357882017-02-10 16:19:28 -0800466 FILE* file = tmpfile();
467 ASSERT_NE(nullptr, file) << errno;
468
469 auto* nativeHandle = native_handle_create(1, 0);
470 ASSERT_NE(nullptr, nativeHandle);
471 nativeHandle->data[0] = fileno(file);
472
473 hidl_handle handle;
474 handle.setTo(nativeHandle, true /*take ownership*/);
475
Kevin Rocardee771e92017-03-08 17:17:25 -0800476 // TODO: debugDump does not return a Result.
Kevin Rocardf0357882017-02-10 16:19:28 -0800477 // This mean that the hal can not report that it not implementing the function.
Kevin Rocardb9031242017-03-13 12:20:54 -0700478 ASSERT_OK(debugDump(handle));
Kevin Rocardee771e92017-03-08 17:17:25 -0800479
480 rewind(file); // can not fail
Kevin Rocardf0357882017-02-10 16:19:28 -0800481
482 // Check that at least one bit was written by the hal
483 char buff;
Kevin Rocardee771e92017-03-08 17:17:25 -0800484 ASSERT_EQ(size_t{1}, fread(&buff, sizeof(buff), 1, file));
Kevin Rocardf0357882017-02-10 16:19:28 -0800485 EXPECT_EQ(0, fclose(file)) << errno;
486}
487
Kevin Rocardb9031242017-03-13 12:20:54 -0700488TEST_F(AudioPrimaryHidlTest, debugDump) {
489 doc::test("Check that the hal can dump its state without error");
490 testDebugDump([this](const auto& handle){ return device->debugDump(handle); });
491}
492
Kevin Rocardf0357882017-02-10 16:19:28 -0800493//////////////////////////////////////////////////////////////////////////////
494////////////////////////// open{Output,Input}Stream //////////////////////////
495//////////////////////////////////////////////////////////////////////////////
496
497template <class Stream>
498class OpenStreamTest : public AudioConfigPrimaryTest,
499 public ::testing::WithParamInterface<AudioConfig> {
500protected:
501 template <class Open>
502 void testOpen(Open openStream, const AudioConfig& config) {
503 // FIXME: Open a stream without an IOHandle
504 // This is not required to be accepted by hal implementations
505 AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
506 AudioConfig suggestedConfig{};
507 ASSERT_OK(openStream(ioHandle, config, returnIn(res, stream, suggestedConfig)));
508
509 // TODO: only allow failure for RecommendedPlaybackAudioConfig
510 switch (res) {
511 case Result::OK:
512 ASSERT_TRUE(stream != nullptr);
513 audioConfig = config;
514 break;
515 case Result::INVALID_ARGUMENTS:
516 ASSERT_TRUE(stream == nullptr);
517 AudioConfig suggestedConfigRetry;
518 // Could not open stream with config, try again with the suggested one
519 ASSERT_OK(openStream(ioHandle, suggestedConfig,
520 returnIn(res, stream, suggestedConfigRetry)));
521 // This time it must succeed
522 ASSERT_OK(res);
523 ASSERT_TRUE(stream == nullptr);
524 audioConfig = suggestedConfig;
525 break;
526 default:
527 FAIL() << "Invalid return status: " << ::testing::PrintToString(res);
528 }
529 open = true;
530 }
531
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800532 Return<Result> closeStream() {
533 open = false;
534 return stream->close();
535 }
Kevin Rocardf0357882017-02-10 16:19:28 -0800536private:
537 void TearDown() override {
538 if (open) {
539 ASSERT_OK(stream->close());
540 }
541 }
542
543protected:
544
545 AudioConfig audioConfig;
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800546 DeviceAddress address = {};
Kevin Rocardf0357882017-02-10 16:19:28 -0800547 sp<Stream> stream;
548 bool open = false;
549};
550
551////////////////////////////// openOutputStream //////////////////////////////
552
553class OutputStreamTest : public OpenStreamTest<IStreamOut> {
554 virtual void SetUp() override {
555 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800556 address.device = AudioDevice::OUT_DEFAULT;
Kevin Rocardf0357882017-02-10 16:19:28 -0800557 const AudioConfig& config = GetParam();
Kevin Rocardf0357882017-02-10 16:19:28 -0800558 AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
559 testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800560 { return device->openOutputStream(handle, address, config, flags, cb); },
Kevin Rocardf0357882017-02-10 16:19:28 -0800561 config);
562 }
563};
564TEST_P(OutputStreamTest, OpenOutputStreamTest) {
565 doc::test("Check that output streams can be open with the required and recommended config");
566 // Open done in SetUp
567}
568INSTANTIATE_TEST_CASE_P(
569 RequiredOutputStreamConfigSupport, OutputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800570 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
571 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800572INSTANTIATE_TEST_CASE_P(
573 SupportedOutputStreamConfig, OutputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800574 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
575 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800576
577INSTANTIATE_TEST_CASE_P(
578 RecommendedOutputStreamConfigSupport, OutputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800579 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
580 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800581
582////////////////////////////// openInputStream //////////////////////////////
583
584class InputStreamTest : public OpenStreamTest<IStreamIn> {
585
586 virtual void SetUp() override {
587 ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800588 address.device = AudioDevice::IN_DEFAULT;
Kevin Rocardf0357882017-02-10 16:19:28 -0800589 const AudioConfig& config = GetParam();
Kevin Rocardf0357882017-02-10 16:19:28 -0800590 AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
591 AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
592 testOpen([&](AudioIoHandle handle, AudioConfig config, auto cb)
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800593 { return device->openInputStream(handle, address, config, flags, source, cb); },
Kevin Rocardf0357882017-02-10 16:19:28 -0800594 config);
595 }
596};
597
598TEST_P(InputStreamTest, OpenInputStreamTest) {
599 doc::test("Check that input streams can be open with the required and recommended config");
600 // Open done in setup
601}
602INSTANTIATE_TEST_CASE_P(
603 RequiredInputStreamConfigSupport, InputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800604 ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
605 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800606INSTANTIATE_TEST_CASE_P(
607 SupportedInputStreamConfig, InputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800608 ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
609 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800610
611INSTANTIATE_TEST_CASE_P(
612 RecommendedInputStreamConfigSupport, InputStreamTest,
Kevin Rocard9c369142017-03-08 17:17:25 -0800613 ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
614 &generateTestName);
Kevin Rocardf0357882017-02-10 16:19:28 -0800615
616//////////////////////////////////////////////////////////////////////////////
617////////////////////////////// IStream getters ///////////////////////////////
618//////////////////////////////////////////////////////////////////////////////
619
620/** Unpack the provided result.
621 * If the result is not OK, register a failure and return an undefined value. */
622template <class R>
623static R extract(Return<R> ret) {
624 if (!ret.isOk()) {
625 ADD_FAILURE();
626 return R{};
627 }
628 return ret;
629}
630
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800631/* Could not find a way to write a test for two parametrized class fixure
632 * thus use this macro do duplicate tests for Input and Output stream */
633#define TEST_IO_STREAM(test_name, documentation, code) \
634 TEST_P(InputStreamTest, test_name) { \
635 doc::test(documentation); \
636 code; \
637 } \
638 TEST_P(OutputStreamTest, test_name) { \
639 doc::test(documentation); \
640 code; \
641 }
642
643TEST_IO_STREAM(GetFrameCount, "Check that the stream frame count == the one it was opened with",
644 ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount())))
645
646TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with",
647 ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate())))
648
649TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it was opened with",
650 ASSERT_EQ(audioConfig.channelMask, extract(stream->getChannelMask())))
651
652TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with",
653 ASSERT_EQ(audioConfig.format, extract(stream->getFormat())))
654
655// TODO: for now only check that the framesize is not incoherent
656TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with",
657 ASSERT_GT(extract(stream->getFrameSize()), 0U))
658
659TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
660 ASSERT_GE(extract(stream->getBufferSize()), \
661 extract(stream->getFrameSize())));
662
Kevin Rocardf0357882017-02-10 16:19:28 -0800663template <class Property, class CapabilityGetter, class Getter, class Setter>
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800664static void testCapabilityGetter(const string& name, IStream* stream, Property currentValue,
Kevin Rocardf0357882017-02-10 16:19:28 -0800665 CapabilityGetter capablityGetter, Getter getter, Setter setter) {
666 hidl_vec<Property> capabilities;
667 ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
668 if (capabilities.size() == 0) {
669 // The default hal should probably return a NOT_SUPPORTED if the hal does not expose
670 // capability retrieval. For now it returns an empty list if not implemented
671 doc::partialTest(name + " is not supported");
672 return;
673 };
674 // TODO: This code has never been tested on a hal that supports getSupportedSampleRates
675 EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
676 capabilities.end())
677 << "current " << name << " is not in the list of the supported ones "
678 << toString(capabilities);
679
680 // Check that all declared supported values are indeed supported
681 for (auto capability : capabilities) {
682 ASSERT_OK((stream->*setter)(capability));
683 ASSERT_EQ(capability, extract((stream->*getter)()));
684 }
685}
686
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800687TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
688 testCapabilityGetter("getSupportedSampleRate", stream.get(), \
689 extract(stream->getSampleRate()), \
690 &IStream::getSupportedSampleRates, \
691 &IStream::getSampleRate, &IStream::setSampleRate))
692
693TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
694 testCapabilityGetter("getSupportedChannelMask", stream.get(), \
695 extract(stream->getChannelMask()), \
696 &IStream::getSupportedChannelMasks, \
697 &IStream::getChannelMask, &IStream::setChannelMask))
698
699TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
700 testCapabilityGetter("getSupportedFormat", stream.get(), \
701 extract(stream->getFormat()), \
702 &IStream::getSupportedFormats, \
703 &IStream::getFormat, &IStream::setFormat))
704
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800705static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
706 auto ret = stream->getDevice();
707 ASSERT_TRUE(ret.isOk());
708 AudioDevice device = ret;
709 ASSERT_EQ(expectedDevice, device);
710}
711
712TEST_IO_STREAM(GetDevice, "Check that the stream device == the one it was opened with",
713 areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
714 testGetDevice(stream.get(), address.device))
715
716static void testSetDevice(IStream* stream, const DeviceAddress& address) {
717 DeviceAddress otherAddress = address;
718 otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ?
719 AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC;
720 EXPECT_OK(stream->setDevice(otherAddress));
721
722 ASSERT_OK(stream->setDevice(address)); // Go back to the original value
723}
724
725TEST_IO_STREAM(SetDevice, "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
726 areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") : \
727 testSetDevice(stream.get(), address))
728
Kevin Rocardf0357882017-02-10 16:19:28 -0800729static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
730 uint32_t sampleRateHz;
731 AudioChannelMask mask;
732 AudioFormat format;
733
734 stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
735
736 // FIXME: the qcom hal it does not currently negotiate the sampleRate & channel mask
Kevin Rocardd1e98ae2017-03-08 17:17:25 -0800737 EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz);
738 EXPECT_EQ(expectedConfig.channelMask, mask);
Kevin Rocardf0357882017-02-10 16:19:28 -0800739 EXPECT_EQ(expectedConfig.format, format);
740}
741
Kevin Rocarda7df7fc2017-03-10 18:37:46 -0800742TEST_IO_STREAM(GetAudioProperties,
743 "Check that the stream audio properties == the ones it was opened with",
744 testGetAudioProperties(stream.get(), audioConfig))
Kevin Rocardf0357882017-02-10 16:19:28 -0800745
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800746static void testConnectedState(IStream* stream) {
747 DeviceAddress address = {};
748 using AD = AudioDevice;
749 for (auto device : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
750 address.device = device;
751
752 ASSERT_OK(stream->setConnectedState(address, true));
753 ASSERT_OK(stream->setConnectedState(address, false));
754 }
755}
756TEST_IO_STREAM(SetConnectedState,
757 "Check that the stream can be notified of device connection and deconnection",
758 testConnectedState(stream.get()))
759
760
761static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
762TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
763 ASSERT_RESULT(invalidArgsOrNotSupported, stream->setHwAvSync(666)))
764
765static void checkGetParameter(IStream* stream, hidl_vec<hidl_string> keys,
766 vector<Result> expectedResults) {
767 hidl_vec<ParameterValue> parameters;
768 Result res;
769 ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
770 ASSERT_RESULT(expectedResults, res);
771 if (res == Result::OK) {
772 ASSERT_EQ(0U, parameters.size());
773 }
774}
775
776/* Get/Set parameter is intended to be an opaque channel between vendors app and their HALs.
777 * Thus can not be meaningfully tested.
778 * TODO: Doc missing. Should asking for an empty set of params raise an error ?
779 */
780TEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set",
781 checkGetParameter(stream.get(), {} /* keys */,
782 {Result::OK, Result::INVALID_ARGUMENTS}))
783
784
785TEST_IO_STREAM(getNonExistingParameter, "Retrieve the values of an non existing parameter",
786 checkGetParameter(stream.get(), {"Non existing key"} /* keys */,
787 {Result::INVALID_ARGUMENTS}))
788
789static vector<Result> okOrNotSupported = {Result::OK, Result::INVALID_ARGUMENTS};
790TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
791 ASSERT_RESULT(okOrNotSupported, stream->setParameters({})))
792
793TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
794 ASSERT_RESULT(Result::INVALID_ARGUMENTS,
795 stream->setParameters({{"non existing key", "0"}})))
796
Kevin Rocardb9031242017-03-13 12:20:54 -0700797TEST_IO_STREAM(DebugDump,
798 "Check that a stream can dump its state without error",
799 testDebugDump([this](const auto& handle){ return stream->debugDump(handle); }))
800
Kevin Rocardf0357882017-02-10 16:19:28 -0800801//////////////////////////////////////////////////////////////////////////////
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800802////////////////////////////// addRemoveEffect ///////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800803//////////////////////////////////////////////////////////////////////////////
804
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800805TEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail",
806 ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666)))
807TEST_IO_STREAM(RemoveNonExistingEffect, "Removing a non existing effect should fail",
808 ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->removeEffect(666)))
Kevin Rocardf0357882017-02-10 16:19:28 -0800809
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800810//TODO: positive tests
811
812//////////////////////////////////////////////////////////////////////////////
813/////////////////////////////// Control ////////////////////////////////
814//////////////////////////////////////////////////////////////////////////////
815
816TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
817 ASSERT_OK(stream->standby())) // can not fail
818
819static vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
820
821TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
822 ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
823
824TEST_IO_STREAM(stopNoMmap, "Stopping a mmaped stream before mapping it should fail",
825 ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
826
827TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping it should fail",
828 ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
829
830TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
831TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
832 ASSERT_OK(closeStream()); \
833 ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
834
835static void testCreateTooBigMmapBuffer(IStream* stream) {
836 MmapBufferInfo info;
837 Result res;
838 // Assume that int max is a value too big to be allocated
839 // This is true currently with a 32bit media server, but might not when it will run in 64 bit
840 auto minSizeFrames = std::numeric_limits<int32_t>::max();
841 ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info)));
842 ASSERT_RESULT(invalidArgsOrNotSupported, res);
Kevin Rocardf0357882017-02-10 16:19:28 -0800843}
844
Kevin Rocard8878b4b2017-03-10 18:47:37 -0800845TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail",
846 testCreateTooBigMmapBuffer(stream.get()))
847
848
849static void testGetMmapPositionOfNonMmapedStream(IStream* stream) {
850 Result res;
851 MmapPosition position;
852 ASSERT_OK(stream->getMmapPosition(returnIn(res, position)));
853 ASSERT_RESULT(invalidArgsOrNotSupported, res);
854}
855
856TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream,
857 "Retrieving the mmap position of a non mmaped stream should fail",
858 testGetMmapPositionOfNonMmapedStream(stream.get()))
859
Kevin Rocardf0357882017-02-10 16:19:28 -0800860//////////////////////////////////////////////////////////////////////////////
Kevin Rocard3c405a72017-03-08 16:46:51 -0800861/////////////////////////////// PrimaryDevice ////////////////////////////////
862//////////////////////////////////////////////////////////////////////////////
863
864TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
865 doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
866 for (float volume : {0.0, 0.01, 0.5, 0.09, 1.0}) {
867 SCOPED_TRACE("volume=" + to_string(volume));
868 ASSERT_OK(device->setVoiceVolume(volume));
869 }
870 for (float volume : (float[]){-INFINITY,-1.0, -0.0,
871 1.0 + std::numeric_limits<float>::epsilon(), 2.0, INFINITY,
872 NAN}) {
873 SCOPED_TRACE("volume=" + to_string(volume));
874 // FIXME: NAN should never be accepted
875 // FIXME: Missing api doc. What should the impl do if the volume is outside [0,1] ?
Kevin Rocard20e7af62017-03-10 17:10:43 -0800876 ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setVoiceVolume(volume));
Kevin Rocard3c405a72017-03-08 16:46:51 -0800877 }
878}
879
880TEST_F(AudioPrimaryHidlTest, setMode) {
881 doc::test("Make sure setMode always succeeds if mode is valid");
882 for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION,
883 AudioMode::RINGTONE, AudioMode::CURRENT,
884 AudioMode::NORMAL /* Make sure to leave the test in normal mode */ }) {
885 SCOPED_TRACE("mode=" + toString(mode));
886 ASSERT_OK(device->setMode(mode));
887 }
888
889 // FIXME: Missing api doc. What should the impl do if the mode is invalid ?
Kevin Rocard20e7af62017-03-10 17:10:43 -0800890 ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode::INVALID));
Kevin Rocard3c405a72017-03-08 16:46:51 -0800891}
892
893
894TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
895 doc::test("Query and set the BT SCO NR&EC state");
896 testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
897 &IPrimaryDevice::setBtScoNrecEnabled,
898 &IPrimaryDevice::getBtScoNrecEnabled);
899}
900
901TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
902 doc::test("Query and set the SCO whideband state");
903 testOptionalAccessors("BtScoWideband", {true, false, true},
904 &IPrimaryDevice::setBtScoWidebandEnabled,
905 &IPrimaryDevice::getBtScoWidebandEnabled);
906}
907
908using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
909TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
910 doc::test("Query and set the TTY mode state");
911 testOptionalAccessors("TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
912 &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
913}
914
915TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
916 doc::test("Query and set the HAC state");
917 testAccessors("HAC", {true, false, true},
918 &IPrimaryDevice::setHacEnabled,
919 &IPrimaryDevice::getHacEnabled);
920}
921
922//////////////////////////////////////////////////////////////////////////////
Kevin Rocardf0357882017-02-10 16:19:28 -0800923//////////////////// Clean caches on global tear down ////////////////////////
924//////////////////////////////////////////////////////////////////////////////
925
926int main(int argc, char** argv) {
927 environment = new Environment;
928 ::testing::AddGlobalTestEnvironment(environment);
929 ::testing::InitGoogleTest(&argc, argv);
930 int status = RUN_ALL_TESTS();
931 LOG(INFO) << "Test result = " << status;
932 return status;
933}