1f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/* 2f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Copyright (C) 2017 The Android Open Source Project 3f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * 4f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Licensed under the Apache License, Version 2.0 (the "License"); 5f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * you may not use this file except in compliance with the License. 6f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * You may obtain a copy of the License at 7f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * 8f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * http://www.apache.org/licenses/LICENSE-2.0 9f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * 10f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * Unless required by applicable law or agreed to in writing, software 11f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * distributed under the License is distributed on an "AS IS" BASIS, 12f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * See the License for the specific language governing permissions and 14f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * limitations under the License. 15f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard */ 16f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 17f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#define LOG_TAG "VtsHalAudioV2_0TargetTest" 18f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 19f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <algorithm> 20f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cmath> 21f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cstddef> 22f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <cstdio> 23f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <limits> 24f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <list> 25f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <string> 26f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <type_traits> 27f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <vector> 28f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 29161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Ma#include <VtsHalHidlTargetTestBase.h> 30f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 31f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android-base/logging.h> 32f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 33f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/IDevice.h> 34f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/IDevicesFactory.h> 353c405a7acf443a5910601763616275f21bb91a41Kevin Rocard#include <android/hardware/audio/2.0/IPrimaryDevice.h> 36f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/2.0/types.h> 37f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include <android/hardware/audio/common/2.0/types.h> 38f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 39f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/AssertOk.h" 40f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard#include "utility/PrettyPrintAudioTypes.h" 4172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard#include "utility/ReturnIn.h" 42f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 43f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::string; 44f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::to_string; 45f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing std::vector; 46f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 47f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::sp; 48f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::Return; 49f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_handle; 50f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_string; 51f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::hidl_vec; 52c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ::android::hardware::MQDescriptorSync; 53624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::AudioDrain; 54f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::DeviceAddress; 55f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevice; 563c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::V2_0::IPrimaryDevice; 573c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyMode = ::android::hardware::audio::V2_0::IPrimaryDevice::TtyMode; 58f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IDevicesFactory; 59f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStream; 60f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamIn; 61624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::TimeSpec; 6272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardusing ReadParameters = 6372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::android::hardware::audio::V2_0::IStreamIn::ReadParameters; 64c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus; 65f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamOut; 66624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardusing ::android::hardware::audio::V2_0::IStreamOutCallback; 678878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardusing ::android::hardware::audio::V2_0::MmapBufferInfo; 688878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardusing ::android::hardware::audio::V2_0::MmapPosition; 69f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::ParameterValue; 70f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::V2_0::Result; 71f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioChannelMask; 72f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioConfig; 73f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioDevice; 74f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioFormat; 75f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioHandleConsts; 76f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioInputFlag; 77f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioIoHandle; 783c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioMode; 79f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOffloadInfo; 80f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioOutputFlag; 81f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing ::android::hardware::audio::common::V2_0::AudioSource; 82c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocardusing ::android::hardware::audio::common::V2_0::ThreadInfo; 83f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 84f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardusing utility::returnIn; 85f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 8696f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocardconst char* getTestName() { 8796f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard return ::testing::UnitTest::GetInstance()->current_test_info()->name(); 8896f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard} 8996f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard 90f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardnamespace doc { 91f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Document the current test case. 9272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * Eg: calling `doc::test("Dump the state of the hal")` in the "debugDump" test 9372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * will output: 9472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * <testcase name="debugDump" status="run" time="6" 9572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * classname="AudioPrimaryHidlTest" 9672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard description="Dump the state of the hal." /> 9772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * see 9872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#logging-additional-information 99f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard */ 100f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid test(const std::string& testCaseDocumentation) { 101f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ::testing::Test::RecordProperty("description", testCaseDocumentation); 102f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 103f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 10472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard/** Document why a test was not fully run. Usually due to an optional feature 10572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * not implemented. */ 106f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardvoid partialTest(const std::string& reason) { 10796f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard LOG(INFO) << "Test " << getTestName() << " partially run: " << reason; 108f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ::testing::Test::RecordProperty("partialyRunTest", reason); 109f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 1105e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard 1115e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard/** Add a note to the test. */ 1125e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocardvoid note(const std::string& note) { 11396f46c4a23e8acce582bba8d6fc6b1d5a61af319Kevin Rocard LOG(INFO) << "Test " << getTestName() << " noted: " << note; 1145e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard ::testing::Test::RecordProperty("note", note); 1155e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard} 116f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 117f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 118f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Register callback for static object destruction 119f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Avoid destroying static objects after main return. 12072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Post main return destruction leads to incorrect gtest timing measurements as 12172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// well as harder 122f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// debuging if anything goes wrong during destruction. 123f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass Environment : public ::testing::Environment { 12472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard public: 12572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard using TearDownFunc = std::function<void()>; 12672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard void registerTearDown(TearDownFunc&& tearDown) { 12772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard tearDowns.push_back(std::move(tearDown)); 128f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 129f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 13072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard private: 131f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard void TearDown() override { 132f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Call the tear downs in reverse order of insertion 133f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard for (auto& tearDown : tearDowns) { 134f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard tearDown(); 135f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 136f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 137f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard std::list<TearDownFunc> tearDowns; 138f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 139f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Instance to register global tearDown 140f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic Environment* environment; 141f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 142161b564b350c6038d9b49edc48ae2a220cc6326cYuexi Maclass HidlTest : public ::testing::VtsHalHidlTargetTestBase { 14372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 144f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Convenient member to store results 145f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard Result res; 146f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 147f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 148f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 149f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////// getService audio_devices_factory ////////////////////// 150f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 151f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 152f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test all audio devices 153f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioHidlTest : public HidlTest { 15472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard public: 155f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard void SetUp() override { 15672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp()); // setup base 157f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 158f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard if (devicesFactory == nullptr) { 15972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard environment->registerTearDown([] { devicesFactory.clear(); }); 16072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService< 16172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard IDevicesFactory>(); 162f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 163f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_TRUE(devicesFactory != nullptr); 164f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 165f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 16672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 167f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Cache the devicesFactory retrieval to speed up each test by ~0.5s 168f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static sp<IDevicesFactory> devicesFactory; 169f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 170f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardsp<IDevicesFactory> AudioHidlTest::devicesFactory; 171f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 172f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioHidlTest, GetAudioDevicesFactoryService) { 173f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("test the getService (called in SetUp)"); 174f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 175f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 1768604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail NaganovTEST_F(AudioHidlTest, OpenDeviceInvalidParameter) { 1778604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov doc::test("test passing an invalid parameter to openDevice"); 1788604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov IDevicesFactory::Result result; 1798604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov sp<IDevice> device; 1808604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device(-1), 1818604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov returnIn(result, device))); 1828604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov ASSERT_EQ(IDevicesFactory::Result::INVALID_ARGUMENTS, result); 1838604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov ASSERT_TRUE(device == nullptr); 1848604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov} 1858604a738a79d9caf8b57773a7bcc2ef99a8a624dMikhail Naganov 186f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 187f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// openDevice primary /////////////////////////// 188f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 189f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 190f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// Test the primary device 191f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass AudioPrimaryHidlTest : public AudioHidlTest { 19272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard public: 193f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard /** Primary HAL test are NOT thread safe. */ 194f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard void SetUp() override { 19572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base 196f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 197f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard if (device == nullptr) { 198f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard IDevicesFactory::Result result; 1993c405a7acf443a5910601763616275f21bb91a41Kevin Rocard sp<IDevice> baseDevice; 20072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK( 20172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY, 20272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard returnIn(result, baseDevice))); 203fba442a60d199441d06bf03375cb7904768403daKevin Rocard ASSERT_OK(result); 2043c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_TRUE(baseDevice != nullptr); 2053c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 20672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard environment->registerTearDown([] { device.clear(); }); 2073c405a7acf443a5910601763616275f21bb91a41Kevin Rocard device = IPrimaryDevice::castFrom(baseDevice); 2083c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_TRUE(device != nullptr); 209f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 210f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 211f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 21272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 213f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Cache the device opening to speed up each test by ~0.5s 2143c405a7acf443a5910601763616275f21bb91a41Kevin Rocard static sp<IPrimaryDevice> device; 215f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 2163c405a7acf443a5910601763616275f21bb91a41Kevin Rocardsp<IPrimaryDevice> AudioPrimaryHidlTest::device; 217f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 218f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) { 219f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("Test the openDevice (called in SetUp)"); 220f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 221f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 222f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, Init) { 223f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("Test that the audio primary hal initialized correctly"); 224f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(device->initCheck()); 225f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 226f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 227f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 22892ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard///////////////////// {set,get}{Master,Mic}{Mute,Volume} ///////////////////// 229f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 230f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 2313c405a7acf443a5910601763616275f21bb91a41Kevin Rocardtemplate <class Property> 2323c405a7acf443a5910601763616275f21bb91a41Kevin Rocardclass AccessorPrimaryHidlTest : public AudioPrimaryHidlTest { 23372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 2343c405a7acf443a5910601763616275f21bb91a41Kevin Rocard /** Test a property getter and setter. */ 235f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard template <class Getter, class Setter> 23672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard void testAccessors(const string& propertyName, 23772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard const vector<Property>& valuesToTest, Setter setter, 23872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard Getter getter, 23992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard const vector<Property>& invalidValues = {}) { 24072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard Property initialValue; // Save initial value to restore it at the end 24172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // of the test 2423c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue))); 2433c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK(res); 2443c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 2453c405a7acf443a5910601763616275f21bb91a41Kevin Rocard for (Property setValue : valuesToTest) { 24692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard SCOPED_TRACE("Test " + propertyName + " getter and setter for " + 24792ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard testing::PrintToString(setValue)); 2483c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK((device.get()->*setter)(setValue)); 2493c405a7acf443a5910601763616275f21bb91a41Kevin Rocard Property getValue; 2503c405a7acf443a5910601763616275f21bb91a41Kevin Rocard // Make sure the getter returns the same value just set 2513c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK((device.get()->*getter)(returnIn(res, getValue))); 252f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(res); 2533c405a7acf443a5910601763616275f21bb91a41Kevin Rocard EXPECT_EQ(setValue, getValue); 2543c405a7acf443a5910601763616275f21bb91a41Kevin Rocard } 2553c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 25692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard for (Property invalidValue : invalidValues) { 25772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard SCOPED_TRACE("Try to set " + propertyName + 25872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard " with the invalid value " + 25992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard testing::PrintToString(invalidValue)); 26072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard EXPECT_RESULT(Result::INVALID_ARGUMENTS, 26172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard (device.get()->*setter)(invalidValue)); 26292ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard } 26392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard 26472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK( 26572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard (device.get()->*setter)(initialValue)); // restore initial value 2663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard } 2673c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 2683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard /** Test the getter and setter of an optional feature. */ 2693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard template <class Getter, class Setter> 27072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard void testOptionalAccessors(const string& propertyName, 27172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard const vector<Property>& valuesToTest, 27292ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard Setter setter, Getter getter, 27392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard const vector<Property>& invalidValues = {}) { 2743c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::test("Test the optional " + propertyName + " getters and setter"); 2753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard { 2763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard SCOPED_TRACE("Test feature support by calling the getter"); 2773c405a7acf443a5910601763616275f21bb91a41Kevin Rocard Property initialValue; 2783c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue))); 2793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard if (res == Result::NOT_SUPPORTED) { 2803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::partialTest(propertyName + " getter is not supported"); 2813c405a7acf443a5910601763616275f21bb91a41Kevin Rocard return; 2823c405a7acf443a5910601763616275f21bb91a41Kevin Rocard } 28372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(res); // If it is supported it must succeed 284f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 2853c405a7acf443a5910601763616275f21bb91a41Kevin Rocard // The feature is supported, test it 28672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testAccessors(propertyName, valuesToTest, setter, getter, 28772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard invalidValues); 288f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 289f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 290f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 2913c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>; 2923c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 293f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) { 294f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("Check that the mic can be muted and unmuted"); 29572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, 29672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IDevice::getMicMute); 297f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // TODO: check that the mic is really muted (all sample are 0) 298f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 299f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 300f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) { 30172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 30272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If master mute is supported, try to mute and unmute the master " 30372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "output"); 3043c405a7acf443a5910601763616275f21bb91a41Kevin Rocard testOptionalAccessors("master mute", {true, false, true}, 3053c405a7acf443a5910601763616275f21bb91a41Kevin Rocard &IDevice::setMasterMute, &IDevice::getMasterMute); 306f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // TODO: check that the master volume is really muted 307f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 308f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 30992ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocardusing FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>; 31092ce35df946b0514e1e73a4f976cccff9e49823bKevin RocardTEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) { 31192ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard doc::test("Test the master volume if supported"); 31272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testOptionalAccessors("master volume", {0, 0.5, 1}, 31392ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard &IDevice::setMasterVolume, &IDevice::getMasterVolume, 31492ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard {-0.1, 1.1, NAN, INFINITY, -INFINITY, 31592ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard 1 + std::numeric_limits<float>::epsilon()}); 31692ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard // TODO: check that the master volume is really changed 31792ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard} 31892ce35df946b0514e1e73a4f976cccff9e49823bKevin Rocard 319f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 3208878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard//////////////////////////////// AudioPatches //////////////////////////////// 3218878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////////////////////////////////////////////////////// 3228878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 3238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardclass AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest { 32472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 3258878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard bool areAudioPatchesSupported() { 3268878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard auto result = device->supportsAudioPatches(); 327f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard EXPECT_IS_OK(result); 3288878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard return result; 3298878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard } 3308878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard}; 3318878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 3328878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_F(AudioPatchPrimaryHidlTest, AudioPatches) { 3338878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard doc::test("Test if audio patches are supported"); 3348878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard if (!areAudioPatchesSupported()) { 3358878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard doc::partialTest("Audio patches are not supported"); 3368878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard return; 3378878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard } 3388878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard // TODO: test audio patches 3398878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 3408878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 3418878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////////////////////////////////////////////////////// 342f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////// Required and recommended audio format support /////////////// 34372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// From: 34472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording 34572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// From: 34672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback 347f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////// TODO: move to the beginning of the file for easier update //////// 348f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 349f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 3508878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardclass AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest { 35172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard public: 352f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Cache result ? 353f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() { 35472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return combineAudioConfig( 35572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, 35672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {8000, 11025, 16000, 22050, 32000, 44100}, 35772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {AudioFormat::PCM_16_BIT}); 358f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 359f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 36072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard static const vector<AudioConfig> 36172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard getRecommendedSupportPlaybackAudioConfig() { 36272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return combineAudioConfig( 36372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, 36472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {24000, 48000}, {AudioFormat::PCM_16_BIT}); 365f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 366f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 367f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> getSupportedPlaybackAudioConfig() { 368f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // TODO: retrieve audio config supported by the platform 369f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // as declared in the policy configuration 370f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return {}; 371f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 372f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 373f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() { 374f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return combineAudioConfig({AudioChannelMask::IN_MONO}, 375f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard {8000, 11025, 16000, 44100}, 376f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard {AudioFormat::PCM_16_BIT}); 377f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 378f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() { 37972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000}, 380f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard {AudioFormat::PCM_16_BIT}); 381f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 382f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> getSupportedCaptureAudioConfig() { 383f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // TODO: retrieve audio config supported by the platform 384f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // as declared in the policy configuration 385f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return {}; 386f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 38772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard 38872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard private: 389f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard static const vector<AudioConfig> combineAudioConfig( 39072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard vector<AudioChannelMask> channelMasks, vector<uint32_t> sampleRates, 39172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard vector<AudioFormat> formats) { 392f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard vector<AudioConfig> configs; 39372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard for (auto channelMask : channelMasks) { 394f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard for (auto sampleRate : sampleRates) { 395f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard for (auto format : formats) { 396f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioConfig config{}; 397f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // leave offloadInfo to 0 398f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard config.channelMask = channelMask; 399f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard config.sampleRateHz = sampleRate; 400f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard config.format = format; 401f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // FIXME: leave frameCount to 0 ? 402f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard configs.push_back(config); 403f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 404f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 405f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 406f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return configs; 407f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 408f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 409f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 4109c369149837baf173401b5033b5ec96214362631Kevin Rocard/** Generate a test name based on an audio config. 4119c369149837baf173401b5033b5ec96214362631Kevin Rocard * 4129c369149837baf173401b5033b5ec96214362631Kevin Rocard * As the only parameter changing are channel mask and sample rate, 4139c369149837baf173401b5033b5ec96214362631Kevin Rocard * only print those ones in the test name. 4149c369149837baf173401b5033b5ec96214362631Kevin Rocard */ 41572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic string generateTestName( 41672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard const testing::TestParamInfo<AudioConfig>& info) { 4179c369149837baf173401b5033b5ec96214362631Kevin Rocard const AudioConfig& config = info.param; 41872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" + 41972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // "MONO" is more clear than "FRONT_LEFT" 42072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ((config.channelMask == AudioChannelMask::OUT_MONO || 42172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard config.channelMask == AudioChannelMask::IN_MONO) 42272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ? "MONO" 42372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard : toString(config.channelMask)); 4249c369149837baf173401b5033b5ec96214362631Kevin Rocard} 4259c369149837baf173401b5033b5ec96214362631Kevin Rocard 426f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 427f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard///////////////////////////// getInputBufferSize ///////////////////////////// 428f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 429f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 43072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// FIXME: execute input test only if platform declares 43172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// android.hardware.microphone 432f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard// how to get this value ? is it a property ??? 433f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 43472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardclass AudioCaptureConfigPrimaryTest 43572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard : public AudioConfigPrimaryTest, 43672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard public ::testing::WithParamInterface<AudioConfig> { 43772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 43872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard void inputBufferSizeTest(const AudioConfig& audioConfig, 43972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard bool supportRequired) { 440f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard uint64_t bufferSize; 44172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK( 44272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard device->getInputBufferSize(audioConfig, returnIn(res, bufferSize))); 443f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 444f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard switch (res) { 445f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard case Result::INVALID_ARGUMENTS: 446f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard EXPECT_FALSE(supportRequired); 447f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard break; 448f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard case Result::OK: 449f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Check that the buffer is of a sane size 450f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // For now only that it is > 0 451f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard EXPECT_GT(bufferSize, uint64_t(0)); 452f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard break; 453f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard default: 45472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard FAIL() << "Invalid return status: " 45572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard << ::testing::PrintToString(res); 456f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 457f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 458f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 459f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 46072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Test that the required capture config and those declared in the policy are 46172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// indeed supported 462f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {}; 463f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) { 46472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 46572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Input buffer size must be retrievable for a format with required " 46672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "support."); 467f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard inputBufferSizeTest(GetParam(), true); 468f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 469f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 47072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RequiredInputBufferSize, RequiredInputBufferSizeTest, 47172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 47272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()), 47372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 474f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 47572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard SupportedInputBufferSize, RequiredInputBufferSizeTest, 47672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 47772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()), 47872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 479f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 48072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// Test that the recommended capture config are supported or lead to a 48172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// INVALID_ARGUMENTS return 482f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {}; 483f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) { 48472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 48572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Input buffer size should be retrievable for a format with recommended " 48672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "support."); 487f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard inputBufferSizeTest(GetParam(), false); 488f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 489f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 49072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest, 49172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 49272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()), 49372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 494f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 495f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 496f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/////////////////////////////// setScreenState /////////////////////////////// 497f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 498f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 499f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, setScreenState) { 500f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("Check that the hal can receive the screen state"); 501f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard for (bool turnedOn : {false, true, true, false, false}) { 502f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard auto ret = device->setScreenState(turnedOn); 503f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(ret); 504f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard Result result = ret; 505f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED}; 506f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_RESULT(okOrNotSupported, result); 507f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 508f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 509f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 510f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 511f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////// {get,set}Parameters ///////////////////////////// 512f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 513f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 514f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_F(AudioPrimaryHidlTest, getParameters) { 515f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::test("Check that the hal can set and get parameters"); 516f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard hidl_vec<hidl_string> keys; 517f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard hidl_vec<ParameterValue> values; 518f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(device->getParameters(keys, returnIn(res, values))); 519f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(device->setParameters(values)); 520f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard values.resize(0); 521f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(device->setParameters(values)); 522f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 523f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 524f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 525f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////////////////// debugDebug ////////////////////////////////// 526f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 527f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 528b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocardtemplate <class DebugDump> 529b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocardstatic void testDebugDump(DebugDump debugDump) { 5305e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard // Dump in a temporary file 5315e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard // Note that SELinux must be deactivate for this test to work 532f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard FILE* file = tmpfile(); 533f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_NE(nullptr, file) << errno; 534f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 5355e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard // Wrap the temporary file file descriptor in a native handle 536f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard auto* nativeHandle = native_handle_create(1, 0); 537f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_NE(nullptr, nativeHandle); 538f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard nativeHandle->data[0] = fileno(file); 539f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 5405e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard // Wrap this native handle in a hidl handle 541f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard hidl_handle handle; 542f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard handle.setTo(nativeHandle, true /*take ownership*/); 543f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 5445e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard ASSERT_OK(debugDump(handle)); 5455e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard 5465e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard // Check that at least one bit was written by the hal 547ee771e9cfac6d0ec1d930ef9e71b1c7bd9b91fa9Kevin Rocard // TODO: debugDump does not return a Result. 54872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // This mean that the hal can not report that it not implementing the 54972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // function. 55072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard rewind(file); // can not fail 551f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard char buff; 5525e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard if (fread(&buff, sizeof(buff), 1, file) != 1) { 5535e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard doc::note("debugDump does not seem implemented"); 5545e5783daef84deecd53bfb1e94a0177e667b71dbKevin Rocard } 555f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard EXPECT_EQ(0, fclose(file)) << errno; 556f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 557f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 5585e5783daef84deecd53bfb1e94a0177e667b71dbKevin RocardTEST_F(AudioPrimaryHidlTest, DebugDump) { 559b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard doc::test("Check that the hal can dump its state without error"); 56072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testDebugDump( 56172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [this](const auto& handle) { return device->debugDump(handle); }); 562b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard} 563b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard 5645e5783daef84deecd53bfb1e94a0177e667b71dbKevin RocardTEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) { 5653e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov doc::test("Check that the hal dump doesn't crash on invalid arguments"); 5663e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov ASSERT_OK(device->debugDump(hidl_handle())); 5673e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov} 5683e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov 569f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 570f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////// open{Output,Input}Stream ////////////////////////// 571f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 572f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 573f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Stream> 574f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OpenStreamTest : public AudioConfigPrimaryTest, 575f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard public ::testing::WithParamInterface<AudioConfig> { 57672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 577f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard template <class Open> 578f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard void testOpen(Open openStream, const AudioConfig& config) { 579f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // FIXME: Open a stream without an IOHandle 580f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // This is not required to be accepted by hal implementations 58172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioIoHandle ioHandle = 58272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE; 583f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioConfig suggestedConfig{}; 58472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(openStream(ioHandle, config, 58572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard returnIn(res, stream, suggestedConfig))); 586f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 587f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // TODO: only allow failure for RecommendedPlaybackAudioConfig 588f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard switch (res) { 589f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard case Result::OK: 590f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_TRUE(stream != nullptr); 591f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard audioConfig = config; 592f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard break; 593f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard case Result::INVALID_ARGUMENTS: 594f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_TRUE(stream == nullptr); 595f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioConfig suggestedConfigRetry; 59672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // Could not open stream with config, try again with the 59772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // suggested one 59872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK( 59972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard openStream(ioHandle, suggestedConfig, 60072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard returnIn(res, stream, suggestedConfigRetry))); 601f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // This time it must succeed 602f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(res); 6034aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard ASSERT_TRUE(stream != nullptr); 604f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard audioConfig = suggestedConfig; 605f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard break; 606f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard default: 60772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard FAIL() << "Invalid return status: " 60872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard << ::testing::PrintToString(res); 609f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 610f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard open = true; 611f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 612f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 6138878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard Return<Result> closeStream() { 6148878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard open = false; 6158878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard return stream->close(); 6168878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard } 61772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard 61872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard private: 619f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard void TearDown() override { 620f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard if (open) { 621f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK(stream->close()); 622f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 623f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 624f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 62572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard protected: 626f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioConfig audioConfig; 6278878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard DeviceAddress address = {}; 628f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard sp<Stream> stream; 629f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard bool open = false; 630f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 631f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 632f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openOutputStream ////////////////////////////// 633f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 634f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass OutputStreamTest : public OpenStreamTest<IStreamOut> { 635f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard virtual void SetUp() override { 63672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base 6378878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard address.device = AudioDevice::OUT_DEFAULT; 638f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard const AudioConfig& config = GetParam(); 63972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioOutputFlag flags = 64072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioOutputFlag::NONE; // TODO: test all flag combination 64172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testOpen( 64272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [&](AudioIoHandle handle, AudioConfig config, auto cb) { 64372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return device->openOutputStream(handle, address, config, flags, 64472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard cb); 64572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard }, 64672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard config); 647f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 648f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 649f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(OutputStreamTest, OpenOutputStreamTest) { 65072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 65172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that output streams can be open with the required and " 65272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "recommended config"); 653f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Open done in SetUp 654f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 655f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 65672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RequiredOutputStreamConfigSupport, OutputStreamTest, 65772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 65872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()), 65972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 660f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 66172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard SupportedOutputStreamConfig, OutputStreamTest, 66272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 66372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()), 66472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 665f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 666f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 66772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RecommendedOutputStreamConfigSupport, OutputStreamTest, 66872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 66972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()), 67072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 671f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 672f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// openInputStream ////////////////////////////// 673f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 674f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardclass InputStreamTest : public OpenStreamTest<IStreamIn> { 675f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard virtual void SetUp() override { 67672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base 6778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard address.device = AudioDevice::IN_DEFAULT; 678f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard const AudioConfig& config = GetParam(); 67972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioInputFlag flags = 68072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioInputFlag::NONE; // TODO: test all flag combination 68172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioSource source = 68272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioSource::DEFAULT; // TODO: test all flag combination 68372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testOpen( 68472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [&](AudioIoHandle handle, AudioConfig config, auto cb) { 68572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return device->openInputStream(handle, address, config, flags, 68672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard source, cb); 68772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard }, 68872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard config); 689f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 690f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard}; 691f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 692f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardTEST_P(InputStreamTest, OpenInputStreamTest) { 69372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 69472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that input streams can be open with the required and " 69572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "recommended config"); 696f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Open done in setup 697f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 698f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 69972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RequiredInputStreamConfigSupport, InputStreamTest, 70072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 70172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()), 70272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 703f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 70472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard SupportedInputStreamConfig, InputStreamTest, 70572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 70672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()), 70772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 708f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 709f0357884b5048c097cc7acda694e62f5aa68b631Kevin RocardINSTANTIATE_TEST_CASE_P( 71072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard RecommendedInputStreamConfigSupport, InputStreamTest, 71172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ::testing::ValuesIn( 71272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()), 71372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &generateTestName); 714f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 715f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 716f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////// IStream getters /////////////////////////////// 717f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 718f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 719f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard/** Unpack the provided result. 720f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard * If the result is not OK, register a failure and return an undefined value. */ 721f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class R> 722f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardstatic R extract(Return<R> ret) { 723f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard if (!ret.isOk()) { 724f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard EXPECT_IS_OK(ret); 725f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return R{}; 726f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 727f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return ret; 728f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 729f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 730a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard/* Could not find a way to write a test for two parametrized class fixure 731a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard * thus use this macro do duplicate tests for Input and Output stream */ 732a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard#define TEST_IO_STREAM(test_name, documentation, code) \ 73372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard TEST_P(InputStreamTest, test_name) { \ 73472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test(documentation); \ 73572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard code; \ 73672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard } \ 73772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard TEST_P(OutputStreamTest, test_name) { \ 73872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test(documentation); \ 73972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard code; \ 740a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard } 741a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 74272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 74372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard GetFrameCount, 74472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream frame count == the one it was opened with", 74572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_EQ(audioConfig.frameCount, extract(stream->getFrameCount()))) 746a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 74772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 74872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard GetSampleRate, 74972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream sample rate == the one it was opened with", 750fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard stream->getSampleRate()) 751a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 75272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 75372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard GetChannelMask, 75472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream channel mask == the one it was opened with", 755fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard stream->getChannelMask()) 756a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 75772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetFormat, 75872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream format == the one it was opened with", 759a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard ASSERT_EQ(audioConfig.format, extract(stream->getFormat()))) 760a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 761a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard// TODO: for now only check that the framesize is not incoherent 76272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetFrameSize, 76372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream frame size == the one it was opened with", 764a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard ASSERT_GT(extract(stream->getFrameSize()), 0U)) 765a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 76672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetBufferSize, 76772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream buffer size== the one it was opened with", 76872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_GE(extract(stream->getBufferSize()), 76972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard extract(stream->getFrameSize()))); 770a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 771f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardtemplate <class Property, class CapabilityGetter, class Getter, class Setter> 77272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testCapabilityGetter(const string& name, IStream* stream, 77372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard Property currentValue, 77472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard CapabilityGetter capablityGetter, 77572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard Getter getter, Setter setter) { 776f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard hidl_vec<Property> capabilities; 777f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities))); 778f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard if (capabilities.size() == 0) { 77972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // The default hal should probably return a NOT_SUPPORTED if the hal 78072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // does not expose 78172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // capability retrieval. For now it returns an empty list if not 78272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // implemented 783f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard doc::partialTest(name + " is not supported"); 784f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return; 785f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard }; 78672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // TODO: This code has never been tested on a hal that supports 78772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // getSupportedSampleRates 788f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue), 78972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard capabilities.end()) 790f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard << "current " << name << " is not in the list of the supported ones " 791f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard << toString(capabilities); 792f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 793f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard // Check that all declared supported values are indeed supported 794f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard for (auto capability : capabilities) { 795f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_OK((stream->*setter)(capability)); 796f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ASSERT_EQ(capability, extract((stream->*getter)())); 797f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard } 798f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 799f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 80072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedSampleRate, 80172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream sample rate is declared as supported", 80272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testCapabilityGetter("getSupportedSampleRate", stream.get(), 80372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard extract(stream->getSampleRate()), 80472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::getSupportedSampleRates, 80572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::getSampleRate, 80672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::setSampleRate)) 80772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard 80872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedChannelMask, 80972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream channel mask is declared as supported", 81072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testCapabilityGetter("getSupportedChannelMask", stream.get(), 81172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard extract(stream->getChannelMask()), 81272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::getSupportedChannelMasks, 81372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::getChannelMask, 81472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::setChannelMask)) 81572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard 81672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(SupportedFormat, 81772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream format is declared as supported", 81872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testCapabilityGetter("getSupportedFormat", stream.get(), 81972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard extract(stream->getFormat()), 82072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IStream::getSupportedFormats, 821a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard &IStream::getFormat, &IStream::setFormat)) 822a7df7fc097d09deff178ffc591f1bbdac041f561Kevin Rocard 8238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testGetDevice(IStream* stream, AudioDevice expectedDevice) { 8248f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard // Unfortunately the interface does not allow the implementation to return 8258f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard // NOT_SUPPORTED 8268f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard // Thus allow NONE as signaling that the call is not supported. 8278878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard auto ret = stream->getDevice(); 828f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(ret); 8298878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard AudioDevice device = ret; 8308f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard ASSERT_TRUE(device == expectedDevice || device == AudioDevice::NONE) 8318f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard << "Expected: " << ::testing::PrintToString(expectedDevice) 8328f8730c7629fe87d8a2123359da2e1a20f926d0eKevin Rocard << "\n Actual: " << ::testing::PrintToString(device); 8338878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 8348878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 83572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(GetDevice, 83672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream device == the one it was opened with", 83772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard areAudioPatchesSupported() 83872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ? doc::partialTest("Audio patches are supported") 83972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard : testGetDevice(stream.get(), address.device)) 8408878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 8418878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testSetDevice(IStream* stream, const DeviceAddress& address) { 8428878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard DeviceAddress otherAddress = address; 84372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 84472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ? AudioDevice::OUT_SPEAKER 84572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard : AudioDevice::IN_BUILTIN_MIC; 8468878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard EXPECT_OK(stream->setDevice(otherAddress)); 8478878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 84872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(stream->setDevice(address)); // Go back to the original value 8498878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 8508878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 85172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 85272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard SetDevice, 85372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC", 85472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") 85572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard : testSetDevice(stream.get(), address)) 8568878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 857fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocardstatic void testGetAudioProperties(IStream* stream) { 858f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard uint32_t sampleRateHz; 859f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioChannelMask mask; 860f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard AudioFormat format; 861f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard stream->getAudioProperties(returnIn(sampleRateHz, mask, format)); 862f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 863f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 86472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 86572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard GetAudioProperties, 86672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream audio properties == the ones it was opened with", 867fd297c6f8e722ac834706844fec058ff7b1335c0Kevin Rocard testGetAudioProperties(stream.get())) 868f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 8698878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testConnectedState(IStream* stream) { 8708878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard DeviceAddress address = {}; 8718878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard using AD = AudioDevice; 87272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard for (auto device : 87372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) { 8748878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard address.device = device; 8758878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 8768878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_OK(stream->setConnectedState(address, true)); 8778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_OK(stream->setConnectedState(address, false)); 8788878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard } 8798878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 8808878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(SetConnectedState, 88172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Check that the stream can be notified of device connection and " 88272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "deconnection", 8838878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard testConnectedState(stream.get())) 8848878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 885f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocardstatic auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS, 886f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard Result::NOT_SUPPORTED, Result::OK}; 8878878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value", 888f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard ASSERT_RESULT(invalidArgsOrNotSupportedOrOK, 88972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard stream->setHwAvSync(666))) 8908878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 891e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin RocardTEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", 892f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(device->getHwAvSync())); 893e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard 894fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocardstatic void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys, 895fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard vector<Result> expectedResults) { 8968878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard hidl_vec<ParameterValue> parameters; 8978878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard Result res; 8988878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters))); 8998878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(expectedResults, res); 9008878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard if (res == Result::OK) { 9014aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard for (auto& parameter : parameters) { 9024aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard ASSERT_EQ(0U, parameter.value.size()) << toString(parameter); 9034aefd1c1ff3f92fd02fdfb76d7feda93cdea2909Kevin Rocard } 9048878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard } 9058878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 9068878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 90772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard/* Get/Set parameter is intended to be an opaque channel between vendors app and 90872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard * their HALs. 9098878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard * Thus can not be meaningfully tested. 9108878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard */ 9118878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(getEmptySetParameter, "Retrieve the values of an empty set", 912fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard checkGetNoParameter(stream.get(), {} /* keys */, {Result::OK})) 9138878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 91472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(getNonExistingParameter, 91572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Retrieve the values of an non existing parameter", 916fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard checkGetNoParameter(stream.get(), 917fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard {"Non existing key"} /* keys */, 918fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard {Result::NOT_SUPPORTED})) 9198878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 92072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(setEmptySetParameter, 92172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Set the values of an empty set of parameters", 922f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard ASSERT_RESULT(Result::OK, stream->setParameters({}))) 9238878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 92472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 92572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard setNonExistingParameter, "Set the values of an non existing parameter", 926f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard // Unfortunately, the set_parameter legacy interface did not return any 927f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard // error code when a key is not supported. 928f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard // To allow implementation to just wrapped the legacy one, consider OK as a 929f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard // valid result for setting a non existing parameter. 930f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard ASSERT_RESULT(invalidArgsOrNotSupportedOrOK, 93172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard stream->setParameters({{"non existing key", "0"}}))) 9328878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 933b903124b365a095b56cce6ac4345fc1166d937c7Kevin RocardTEST_IO_STREAM(DebugDump, 934b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard "Check that a stream can dump its state without error", 93572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testDebugDump([this](const auto& handle) { 93672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return stream->debugDump(handle); 93772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard })) 938b903124b365a095b56cce6ac4345fc1166d937c7Kevin Rocard 9393e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail NaganovTEST_IO_STREAM(DebugDumpInvalidArguments, 9403e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov "Check that the stream dump doesn't crash on invalid arguments", 9413e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov ASSERT_OK(stream->debugDump(hidl_handle()))) 9423e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov 943f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 9448878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////// addRemoveEffect /////////////////////////////// 945f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 946f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 9478878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(AddNonExistingEffect, "Adding a non existing effect should fail", 9488878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->addEffect(666))) 94972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(RemoveNonExistingEffect, 95072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Removing a non existing effect should fail", 95172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_RESULT(Result::INVALID_ARGUMENTS, 95272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard stream->removeEffect(666))) 953f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 95472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard// TODO: positive tests 9558878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 9568878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////////////////////////////////////////////////////// 9578878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard/////////////////////////////// Control //////////////////////////////// 9588878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard////////////////////////////////////////////////////////////////////////////// 9598878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 9608878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(standby, "Make sure the stream can be put in stanby", 96172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(stream->standby())) // can not fail 9628878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 96372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic vector<Result> invalidStateOrNotSupported = {Result::INVALID_STATE, 96472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard Result::NOT_SUPPORTED}; 9658878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 96672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(startNoMmap, 96772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Starting a mmaped stream before mapping it should fail", 9688878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(invalidStateOrNotSupported, stream->start())) 9698878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 97072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(stopNoMmap, 97172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Stopping a mmaped stream before mapping it should fail", 9728878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(invalidStateOrNotSupported, stream->stop())) 9738878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 97472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(getMmapPositionNoMmap, 97572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Get a stream Mmap position before mapping it should fail", 9768878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(invalidStateOrNotSupported, stream->stop())) 9778878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 97872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM(close, "Make sure a stream can be closed", 97972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(closeStream())) 9808878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", 98172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(closeStream()); 9828878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(Result::INVALID_STATE, closeStream())) 9838878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 984f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocardstatic auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, 985f8500dcb5a22b3f21dbcdadf04cf3d667d499b51Kevin Rocard Result::NOT_SUPPORTED}; 9868878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testCreateTooBigMmapBuffer(IStream* stream) { 9878878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard MmapBufferInfo info; 9888878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard Result res; 9898878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard // Assume that int max is a value too big to be allocated 99072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // This is true currently with a 32bit media server, but might not when it 99172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // will run in 64 bit 9928878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard auto minSizeFrames = std::numeric_limits<int32_t>::max(); 9938878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_OK(stream->createMmapBuffer(minSizeFrames, returnIn(res, info))); 9948878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(invalidArgsOrNotSupported, res); 9958878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard} 9968878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 9978878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin RocardTEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail", 9988878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard testCreateTooBigMmapBuffer(stream.get())) 9998878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 10008878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocardstatic void testGetMmapPositionOfNonMmapedStream(IStream* stream) { 10018878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard Result res; 10028878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard MmapPosition position; 10038878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_OK(stream->getMmapPosition(returnIn(res, position))); 10048878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard ASSERT_RESULT(invalidArgsOrNotSupported, res); 1005f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 1006f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 100772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardTEST_IO_STREAM( 100872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard GetMmapPositionOfNonMmapedStream, 100972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Retrieving the mmap position of a non mmaped stream should fail", 101072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testGetMmapPositionOfNonMmapedStream(stream.get())) 10118878b4ba1f7c1f1e9fcfdf907bf0cad6b93f6a02Kevin Rocard 1012f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 1013c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard///////////////////////////////// StreamIn /////////////////////////////////// 10143c405a7acf443a5910601763616275f21bb91a41Kevin Rocard////////////////////////////////////////////////////////////////////////////// 10153c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 1016c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, GetAudioSource) { 101772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 101872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Retrieving the audio source of an input stream should always succeed"); 1019c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard AudioSource source; 1020c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard ASSERT_OK(stream->getAudioSource(returnIn(res, source))); 102198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard if (res == Result::NOT_SUPPORTED) { 102298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard doc::partialTest("getAudioSource is not supported"); 102398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard return; 102498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard } 1025c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard ASSERT_OK(res); 1026c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard ASSERT_EQ(AudioSource::DEFAULT, source); 1027c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1028c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 102972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testUnitaryGain(std::function<Return<Result>(float)> setGain) { 1030c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard for (float value : 1031c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard (float[]){-INFINITY, -1.0, 1.0 + std::numeric_limits<float>::epsilon(), 1032c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard 2.0, INFINITY, NAN}) { 1033a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard EXPECT_RESULT(Result::INVALID_ARGUMENTS, setGain(value)) << "value=" 1034a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard << value; 10353c405a7acf443a5910601763616275f21bb91a41Kevin Rocard } 1036c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard // Do not consider -0.0 as an invalid value as it is == with 0.0 1037c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard for (float value : {-0.0, 0.0, 0.01, 0.5, 0.09, 1.0 /* Restore volume*/}) { 1038a1d6ea4ba76c96cd613ee81eb204bc3041a219f7Kevin Rocard EXPECT_OK(setGain(value)) << "value=" << value; 1039c4f1b2f86a0dd9337577192372219e868a6c59f3Kevin Rocard } 10403c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 10413c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 104298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocardstatic void testOptionalUnitaryGain( 104398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard std::function<Return<Result>(float)> setGain, string debugName) { 104498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard auto result = setGain(1); 1045f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(result); 104698390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard if (result == Result::NOT_SUPPORTED) { 104798390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard doc::partialTest(debugName + " is not supported"); 104898390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard return; 104998390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard } 105098390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard testUnitaryGain(setGain); 105198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard} 105298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard 1053c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, SetGain) { 1054c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard doc::test("The gain of an input stream should only be set between [0,1]"); 105598390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard testOptionalUnitaryGain( 105698390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard [this](float volume) { return stream->setGain(volume); }, 105798390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard "InputStream::setGain"); 1058c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1059c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 106072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, 106172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard uint32_t framesCount) { 1062c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard Result res; 1063c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard // Ignore output parameters as the call should fail 106472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(stream->prepareForReading( 106572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard frameSize, framesCount, 106672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); 1067fcf186bd5949f3bbb4274f8f7bf4ab9e4497d541Kevin Rocard EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); 1068c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1069c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 1070195205b323b7d93cf4d477445469759b27371f45Kevin RocardTEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) { 1071195205b323b7d93cf4d477445469759b27371f45Kevin Rocard doc::test( 1072195205b323b7d93cf4d477445469759b27371f45Kevin Rocard "Preparing a stream for reading with a 0 sized buffer should fail"); 1073195205b323b7d93cf4d477445469759b27371f45Kevin Rocard testPrepareForReading(stream.get(), 0, 0); 1074195205b323b7d93cf4d477445469759b27371f45Kevin Rocard} 1075195205b323b7d93cf4d477445469759b27371f45Kevin Rocard 1076c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) { 107772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 107872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Preparing a stream for reading with a 2^32 sized buffer should fail"); 107972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testPrepareForReading(stream.get(), 1, 108072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard std::numeric_limits<uint32_t>::max()); 1081c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1082c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 1083c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, PrepareForReadingCheckOverflow) { 108472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 108572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Preparing a stream for reading with a overflowing sized buffer should " 108672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "fail"); 1087c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard auto uintMax = std::numeric_limits<uint32_t>::max(); 1088c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard testPrepareForReading(stream.get(), uintMax, uintMax); 1089c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1090c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 1091e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin RocardTEST_P(InputStreamTest, GetInputFramesLost) { 109272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 109372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "The number of frames lost on a never started stream should be 0"); 1094e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard auto ret = stream->getInputFramesLost(); 1095f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(ret); 1096e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard uint32_t framesLost{ret}; 1097e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard ASSERT_EQ(0U, framesLost); 1098e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard} 1099e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard 1100c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_P(InputStreamTest, getCapturePosition) { 110172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 110272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "The capture position of a non prepared stream should not be " 110372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "retrievable"); 1104c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard uint64_t frames; 1105c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard uint64_t time; 1106c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time))); 1107c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard ASSERT_RESULT(invalidStateOrNotSupported, res); 1108c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1109c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 1110c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard////////////////////////////////////////////////////////////////////////////// 1111624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard///////////////////////////////// StreamIn /////////////////////////////////// 1112624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard////////////////////////////////////////////////////////////////////////////// 1113624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1114624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, getLatency) { 1115624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::test("Make sure latency is over 0"); 1116624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto result = stream->getLatency(); 1117f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(result); 1118624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_GT(result, 0U); 1119624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1120624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1121624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, setVolume) { 1122624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::test("Try to set the output volume"); 112398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard testOptionalUnitaryGain( 112498390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard [this](float volume) { return stream->setVolume(volume, volume); }, 112598390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard "setVolume"); 1126624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1127624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 112872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, 112972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard uint32_t framesCount) { 1130624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Result res; 1131624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard // Ignore output parameters as the call should fail 113272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_OK(stream->prepareForWriting( 113372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard frameSize, framesCount, 113472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); 1135fcf186bd5949f3bbb4274f8f7bf4ab9e4497d541Kevin Rocard EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); 1136624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1137624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1138195205b323b7d93cf4d477445469759b27371f45Kevin RocardTEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) { 1139195205b323b7d93cf4d477445469759b27371f45Kevin Rocard doc::test( 1140195205b323b7d93cf4d477445469759b27371f45Kevin Rocard "Preparing a stream for writing with a 0 sized buffer should fail"); 1141195205b323b7d93cf4d477445469759b27371f45Kevin Rocard testPrepareForWriting(stream.get(), 0, 0); 1142195205b323b7d93cf4d477445469759b27371f45Kevin Rocard} 1143195205b323b7d93cf4d477445469759b27371f45Kevin Rocard 1144624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) { 114572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 114672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Preparing a stream for writing with a 2^32 sized buffer should fail"); 114772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testPrepareForWriting(stream.get(), 1, 114872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard std::numeric_limits<uint32_t>::max()); 1149624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1150624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1151624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) { 115272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 115372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Preparing a stream for writing with a overflowing sized buffer should " 115472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "fail"); 1155624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto uintMax = std::numeric_limits<uint32_t>::max(); 1156624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard testPrepareForWriting(stream.get(), uintMax, uintMax); 1157624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1158624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1159624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardstruct Capability { 1160624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Capability(IStreamOut* stream) { 1161624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume))); 1162624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto ret = stream->supportsDrain(); 1163f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard EXPECT_IS_OK(ret); 1164624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (ret.isOk()) { 1165624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard drain = ret; 1166624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1167624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1168624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard bool pause = false; 1169624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard bool resume = false; 1170624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard bool drain = false; 1171624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}; 1172624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1173624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) { 117472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 117572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "Implementation must expose pause, resume and drain capabilities"); 1176624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Capability(stream.get()); 1177624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1178624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1179304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocardtemplate <class Value> 1180304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocardstatic void checkInvalidStateOr0(Result res, Value value) { 1181304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard switch (res) { 1182304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard case Result::INVALID_STATE: 1183304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard break; 1184304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard case Result::OK: 1185304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard ASSERT_EQ(0U, value); 1186304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard break; 1187304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard default: 1188304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard FAIL() << "Unexpected result " << toString(res); 1189304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard } 1190304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard} 1191304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard 1192624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetRenderPosition) { 1193304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard doc::test("A new stream render position should be 0 or INVALID_STATE"); 1194624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard uint32_t dspFrames; 1195624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames))); 1196624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (res == Result::NOT_SUPPORTED) { 1197624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("getRenderPosition is not supported"); 1198624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1199624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1200304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard checkInvalidStateOr0(res, dspFrames); 1201624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1202624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1203624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetNextWriteTimestamp) { 1204304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard doc::test("A new stream next write timestamp should be 0 or INVALID_STATE"); 1205624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard uint64_t timestampUs; 1206e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs))); 1207624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (res == Result::NOT_SUPPORTED) { 1208e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard doc::partialTest("getNextWriteTimestamp is not supported"); 1209624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1210624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1211304b6c810eb0209d5c548d63252670ce2396b020Kevin Rocard checkInvalidStateOr0(res, timestampUs); 1212624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1213624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1214624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard/** Stub implementation of out stream callback. */ 1215624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocardclass MockOutCallbacks : public IStreamOutCallback { 1216624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Return<void> onWriteReady() override { return {}; } 1217624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Return<void> onDrainReady() override { return {}; } 1218624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard Return<void> onError() override { return {}; } 1219624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard}; 1220624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 122172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic bool isAsyncModeSupported(IStreamOut* stream) { 1222624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto res = stream->setCallback(new MockOutCallbacks); 122372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard stream->clearCallback(); // try to restore the no callback state, ignore 122472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard // any error 122572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED}; 1226624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard EXPECT_RESULT(okOrNotSupported, res); 1227624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return res.isOk() ? res == Result::OK : false; 1228624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1229624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1230624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, SetCallback) { 123172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 123272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If supported, registering callback for async operation should never " 123372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "fail"); 1234624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (!isAsyncModeSupported(stream.get())) { 1235624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("The stream does not support async operations"); 1236624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1237624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1238624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->setCallback(new MockOutCallbacks)); 1239624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->setCallback(new MockOutCallbacks)); 1240624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1241624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1242624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, clearCallback) { 124372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 124472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If supported, clearing a callback to go back to sync operation should " 124572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "not fail"); 1246624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (!isAsyncModeSupported(stream.get())) { 1247624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("The stream does not support async operations"); 1248624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1249624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1250624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard // TODO: Clarify if clearing a non existing callback should fail 1251624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->setCallback(new MockOutCallbacks)); 1252624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->clearCallback()); 1253624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1254624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1255624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, Resume) { 125672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 125772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If supported, a stream should fail to resume if not previously " 125872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "paused"); 1259624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (!Capability(stream.get()).resume) { 1260624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("The output stream does not support resume"); 1261624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1262624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1263624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_RESULT(Result::INVALID_STATE, stream->resume()); 1264624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1265624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1266624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, Pause) { 126772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 126872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If supported, a stream should fail to pause if not previously " 126972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "started"); 1270624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (!Capability(stream.get()).pause) { 1271624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("The output stream does not support pause"); 1272624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1273624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1274624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_RESULT(Result::INVALID_STATE, stream->resume()); 1275624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1276624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 127772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocardstatic void testDrain(IStreamOut* stream, AudioDrain type) { 1278624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (!Capability(stream).drain) { 12796f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard doc::partialTest("The output stream does not support drain"); 1280624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1281624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1282624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_RESULT(Result::OK, stream->drain(type)); 1283624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1284624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1285624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, DrainAll) { 12866f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard doc::test("If supported, a stream should always succeed to drain"); 1287624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard testDrain(stream.get(), AudioDrain::ALL); 1288624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1289624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1290624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, DrainEarlyNotify) { 12916f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard doc::test("If supported, a stream should always succeed to drain"); 1292624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard testDrain(stream.get(), AudioDrain::EARLY_NOTIFY); 1293624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1294624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1295624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, FlushStop) { 12966f22680db6bfe392a2f9f6b934ea8a54abea0ad7Kevin Rocard doc::test("If supported, a stream should always succeed to flush"); 1297e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard auto ret = stream->flush(); 1298f26f67a16b1c29993309380e3b33178bf35c4507Kevin Rocard ASSERT_IS_OK(ret); 1299e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard if (ret == Result::NOT_SUPPORTED) { 1300e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard doc::partialTest("Flush is not supported"); 1301e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard return; 1302e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard } 1303e9a8fb737192cafcb7d1d6cd34446825be9e1590Kevin Rocard ASSERT_OK(ret); 1304624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1305624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1306624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin RocardTEST_P(OutputStreamTest, GetPresentationPositionStop) { 130772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard doc::test( 130872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "If supported, a stream should always succeed to retrieve the " 130972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "presentation position"); 1310624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard uint64_t frames; 1311624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard TimeSpec mesureTS; 1312624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS))); 1313624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard if (res == Result::NOT_SUPPORTED) { 1314624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard doc::partialTest("getpresentationPosition is not supported"); 1315624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard return; 1316624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard } 1317624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_EQ(0U, frames); 1318624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1319476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard if (mesureTS.tvNSec == 0 && mesureTS.tvSec == 0) { 1320476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard // As the stream has never written a frame yet, 1321476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard // the timestamp does not really have a meaning, allow to return 0 1322476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard return; 1323476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard } 1324476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard 1325476e38fd3146989efbac1e02e0e918d1deed9fffKevin Rocard // Make sure the return measure is not more than 1s old. 1326624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard struct timespec currentTS; 1327624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, ¤tTS)) << errno; 1328624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 132972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard auto toMicroSec = [](uint64_t sec, auto nsec) { 133072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard return sec * 1e+6 + nsec / 1e+3; 133172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard }; 1332624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto currentTime = toMicroSec(currentTS.tv_sec, currentTS.tv_nsec); 1333624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard auto mesureTime = toMicroSec(mesureTS.tvSec, mesureTS.tvNSec); 133472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ASSERT_PRED2([](auto c, auto m) { return c - m < 1e+6; }, currentTime, 133572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard mesureTime); 1336624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard} 1337624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard 1338624800c0737674f8d01564ab68eb5dcea0ff0a38Kevin Rocard////////////////////////////////////////////////////////////////////////////// 1339c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard/////////////////////////////// PrimaryDevice //////////////////////////////// 1340c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard////////////////////////////////////////////////////////////////////////////// 1341c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 1342c9963526d9660c85b5f567d3b24884028234ac7eKevin RocardTEST_F(AudioPrimaryHidlTest, setVoiceVolume) { 1343c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]"); 134472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testUnitaryGain( 134572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard [this](float volume) { return device->setVoiceVolume(volume); }); 1346c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard} 1347c9963526d9660c85b5f567d3b24884028234ac7eKevin Rocard 13483c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(AudioPrimaryHidlTest, setMode) { 134904364edefcc39a5f620156a35209b760eb66a916Kevin Rocard doc::test( 135004364edefcc39a5f620156a35209b760eb66a916Kevin Rocard "Make sure setMode always succeeds if mode is valid " 135104364edefcc39a5f620156a35209b760eb66a916Kevin Rocard "and fails otherwise"); 135204364edefcc39a5f620156a35209b760eb66a916Kevin Rocard // Test Invalid values 135304364edefcc39a5f620156a35209b760eb66a916Kevin Rocard for (AudioMode mode : 135404364edefcc39a5f620156a35209b760eb66a916Kevin Rocard {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) { 135504364edefcc39a5f620156a35209b760eb66a916Kevin Rocard SCOPED_TRACE("mode=" + toString(mode)); 135604364edefcc39a5f620156a35209b760eb66a916Kevin Rocard ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode)); 135704364edefcc39a5f620156a35209b760eb66a916Kevin Rocard } 135804364edefcc39a5f620156a35209b760eb66a916Kevin Rocard // Test valid values 135972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard for (AudioMode mode : 136072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE, 136172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) { 13623c405a7acf443a5910601763616275f21bb91a41Kevin Rocard SCOPED_TRACE("mode=" + toString(mode)); 13633c405a7acf443a5910601763616275f21bb91a41Kevin Rocard ASSERT_OK(device->setMode(mode)); 13643c405a7acf443a5910601763616275f21bb91a41Kevin Rocard } 13653c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 13663c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 13673c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) { 13683c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::test("Query and set the BT SCO NR&EC state"); 13693c405a7acf443a5910601763616275f21bb91a41Kevin Rocard testOptionalAccessors("BtScoNrecEnabled", {true, false, true}, 137072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IPrimaryDevice::setBtScoNrecEnabled, 137172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IPrimaryDevice::getBtScoNrecEnabled); 13723c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 13733c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 13743c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) { 13753c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::test("Query and set the SCO whideband state"); 13763c405a7acf443a5910601763616275f21bb91a41Kevin Rocard testOptionalAccessors("BtScoWideband", {true, false, true}, 137772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IPrimaryDevice::setBtScoWidebandEnabled, 137872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IPrimaryDevice::getBtScoWidebandEnabled); 13793c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 13803c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 13813c405a7acf443a5910601763616275f21bb91a41Kevin Rocardusing TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>; 13823c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) { 13833c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::test("Query and set the TTY mode state"); 138472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard testOptionalAccessors( 138572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL}, 138672e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode); 13873c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 13883c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 13893c405a7acf443a5910601763616275f21bb91a41Kevin RocardTEST_F(BoolAccessorPrimaryHidlTest, setGetHac) { 13903c405a7acf443a5910601763616275f21bb91a41Kevin Rocard doc::test("Query and set the HAC state"); 139198390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard testOptionalAccessors("HAC", {true, false, true}, 139298390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard &IPrimaryDevice::setHacEnabled, 139398390a6c2cff5b5c75b7236b40a6b72b5b116f17Kevin Rocard &IPrimaryDevice::getHacEnabled); 13943c405a7acf443a5910601763616275f21bb91a41Kevin Rocard} 13953c405a7acf443a5910601763616275f21bb91a41Kevin Rocard 13963c405a7acf443a5910601763616275f21bb91a41Kevin Rocard////////////////////////////////////////////////////////////////////////////// 1397f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard//////////////////// Clean caches on global tear down //////////////////////// 1398f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard////////////////////////////////////////////////////////////////////////////// 1399f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard 1400f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocardint main(int argc, char** argv) { 1401f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard environment = new Environment; 1402f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ::testing::AddGlobalTestEnvironment(environment); 1403f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard ::testing::InitGoogleTest(&argc, argv); 1404f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard int status = RUN_ALL_TESTS(); 1405f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard LOG(INFO) << "Test result = " << status; 1406f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard return status; 1407f0357884b5048c097cc7acda694e62f5aa68b631Kevin Rocard} 1408