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