| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // pull in all the <= 5.0 tests |
| #include "5.0/AudioPrimaryHidlHalTest.cpp" |
| |
| #if MAJOR_VERSION <= 6 |
| static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters( |
| bool oneProfilePerDevice) { |
| std::vector<DeviceConfigParameter> result; |
| for (const auto& device : getDeviceParameters()) { |
| auto module = |
| getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device)); |
| for (const auto& ioProfile : module->getOutputProfiles()) { |
| for (const auto& profile : ioProfile->getAudioProfiles()) { |
| const auto& channels = profile->getChannels(); |
| const auto& sampleRates = profile->getSampleRates(); |
| auto configs = ConfigHelper::combineAudioConfig( |
| std::vector<audio_channel_mask_t>(channels.begin(), channels.end()), |
| std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()), |
| profile->getFormat()); |
| auto flags = ioProfile->getFlags(); |
| for (auto& config : configs) { |
| // Some combinations of flags declared in the config file require special |
| // treatment. |
| if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { |
| config.offloadInfo.sampleRateHz = config.sampleRateHz; |
| config.offloadInfo.channelMask = config.channelMask; |
| config.offloadInfo.format = config.format; |
| config.offloadInfo.streamType = AudioStreamType::MUSIC; |
| config.offloadInfo.bitRatePerSecond = 320; |
| config.offloadInfo.durationMicroseconds = -1; |
| config.offloadInfo.bitWidth = 16; |
| config.offloadInfo.bufferSize = 256; // arbitrary value |
| config.offloadInfo.usage = AudioUsage::MEDIA; |
| result.emplace_back(device, config, |
| AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD | |
| AudioOutputFlag::DIRECT)); |
| } else { |
| if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag |
| flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY; |
| } |
| result.emplace_back(device, config, AudioOutputFlag(flags)); |
| } |
| if (oneProfilePerDevice) break; |
| } |
| if (oneProfilePerDevice) break; |
| } |
| if (oneProfilePerDevice) break; |
| } |
| } |
| return result; |
| } |
| |
| const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() { |
| static std::vector<DeviceConfigParameter> parameters = |
| generateOutputDeviceConfigParameters(false); |
| return parameters; |
| } |
| |
| const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() { |
| static std::vector<DeviceConfigParameter> parameters = |
| generateOutputDeviceConfigParameters(true); |
| return parameters; |
| } |
| |
| static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters( |
| bool oneProfilePerDevice) { |
| std::vector<DeviceConfigParameter> result; |
| for (const auto& device : getDeviceParameters()) { |
| auto module = |
| getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device)); |
| for (const auto& ioProfile : module->getInputProfiles()) { |
| for (const auto& profile : ioProfile->getAudioProfiles()) { |
| const auto& channels = profile->getChannels(); |
| const auto& sampleRates = profile->getSampleRates(); |
| auto configs = ConfigHelper::combineAudioConfig( |
| std::vector<audio_channel_mask_t>(channels.begin(), channels.end()), |
| std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()), |
| profile->getFormat()); |
| for (const auto& config : configs) { |
| result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags())); |
| if (oneProfilePerDevice) break; |
| } |
| if (oneProfilePerDevice) break; |
| } |
| if (oneProfilePerDevice) break; |
| } |
| } |
| return result; |
| } |
| |
| const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() { |
| static std::vector<DeviceConfigParameter> parameters = |
| generateInputDeviceConfigParameters(false); |
| return parameters; |
| } |
| |
| const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() { |
| static std::vector<DeviceConfigParameter> parameters = |
| generateInputDeviceConfigParameters(true); |
| return parameters; |
| } |
| #endif // MAJOR_VERSION <= 6 |
| |
| class SingleConfigOutputStreamTest : public OutputStreamTest {}; |
| TEST_P(SingleConfigOutputStreamTest, CloseDeviceWithOpenedOutputStreams) { |
| doc::test("Verify that a device can't be closed if there are output streams opened"); |
| // Opening of the stream is done in SetUp. |
| ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close()); |
| ASSERT_OK(closeStream(true /*clear*/)); |
| ASSERT_OK(getDevice()->close()); |
| ASSERT_TRUE(resetDevice()); |
| } |
| INSTANTIATE_TEST_CASE_P(SingleConfigOutputStream, SingleConfigOutputStreamTest, |
| ::testing::ValuesIn(getOutputDeviceSingleConfigParameters()), |
| &DeviceConfigParameterToString); |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigOutputStream); |
| |
| class SingleConfigInputStreamTest : public InputStreamTest {}; |
| TEST_P(SingleConfigInputStreamTest, CloseDeviceWithOpenedInputStreams) { |
| doc::test("Verify that a device can't be closed if there are input streams opened"); |
| // Opening of the stream is done in SetUp. |
| ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close()); |
| ASSERT_OK(closeStream(true /*clear*/)); |
| ASSERT_OK(getDevice()->close()); |
| ASSERT_TRUE(resetDevice()); |
| } |
| INSTANTIATE_TEST_CASE_P(SingleConfigInputStream, SingleConfigInputStreamTest, |
| ::testing::ValuesIn(getInputDeviceSingleConfigParameters()), |
| &DeviceConfigParameterToString); |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigInputStream); |
| |
| TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) { |
| doc::test("Verify that passing an invalid handle to updateAudioPatch is checked"); |
| AudioPatchHandle ignored; |
| ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec<AudioPortConfig>(), |
| hidl_vec<AudioPortConfig>(), returnIn(res, ignored))); |
| ASSERT_RESULT(Result::INVALID_ARGUMENTS, res); |
| } |
| |
| using DualMonoModeAccessorHidlTest = AccessorHidlTest<DualMonoMode, OutputStreamTest>; |
| TEST_P(DualMonoModeAccessorHidlTest, DualMonoModeTest) { |
| doc::test("Check that dual mono mode can be set and retrieved"); |
| testAccessors<OPTIONAL>(&OutputStreamTest::getStream, "dual mono mode", |
| Initial{DualMonoMode::OFF}, |
| {DualMonoMode::LR, DualMonoMode::LL, DualMonoMode::RR}, |
| &IStreamOut::setDualMonoMode, &IStreamOut::getDualMonoMode); |
| } |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DualMonoModeAccessorHidlTest); |
| INSTANTIATE_TEST_CASE_P(DualMonoModeHidl, DualMonoModeAccessorHidlTest, |
| ::testing::ValuesIn(getOutputDeviceConfigParameters()), |
| &DeviceConfigParameterToString); |
| |
| using AudioDescriptionMixLevelHidlTest = AccessorHidlTest<float, OutputStreamTest>; |
| TEST_P(AudioDescriptionMixLevelHidlTest, AudioDescriptionMixLevelTest) { |
| doc::test("Check that audio description mix level can be set and retrieved"); |
| testAccessors<OPTIONAL>( |
| &OutputStreamTest::getStream, "audio description mix level", |
| Initial{-std::numeric_limits<float>::infinity()}, {-48.0f, -1.0f, 0.0f, 1.0f, 48.0f}, |
| &IStreamOut::setAudioDescriptionMixLevel, &IStreamOut::getAudioDescriptionMixLevel, |
| {48.5f, 1000.0f, std::numeric_limits<float>::infinity()}); |
| } |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioDescriptionMixLevelHidlTest); |
| INSTANTIATE_TEST_CASE_P(AudioDescriptionMixLevelHidl, AudioDescriptionMixLevelHidlTest, |
| ::testing::ValuesIn(getOutputDeviceConfigParameters()), |
| &DeviceConfigParameterToString); |
| |
| using PlaybackRateParametersHidlTest = AccessorHidlTest<PlaybackRate, OutputStreamTest>; |
| TEST_P(PlaybackRateParametersHidlTest, PlaybackRateParametersTest) { |
| doc::test("Check that playback rate parameters can be set and retrieved"); |
| testAccessors<OPTIONAL>( |
| &OutputStreamTest::getStream, "playback rate parameters", |
| Initial{PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, |
| TimestretchFallbackMode::FAIL}}, |
| {// Speed and pitch values in the range from 0.5f to 2.0f must be supported |
| // (see the definition of IStreamOut::setPlaybackRateParameters). |
| PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{2.0f, 2.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{0.5f, 0.5f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE}, |
| // Gross speed / pitch values must not be rejected if the fallback mode is "mute" |
| PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT, |
| TimestretchFallbackMode::MUTE}, |
| // Default speed / pitch values must not be rejected in "fail" fallback mode |
| PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL}, |
| // Same for "voice" mode |
| PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{2.0f, 2.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{0.5f, 0.5f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE}, |
| PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::FAIL}}, |
| &IStreamOut::setPlaybackRateParameters, &IStreamOut::getPlaybackRateParameters, |
| {PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT, |
| TimestretchFallbackMode::FAIL}, |
| PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, |
| TimestretchFallbackMode::FAIL}}); |
| } |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PlaybackRateParametersHidlTest); |
| INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest, |
| ::testing::ValuesIn(getOutputDeviceConfigParameters()), |
| &DeviceConfigParameterToString); |
| |
| /** Stub implementation of IStreamOutEventCallback **/ |
| class MockOutEventCallbacks : public IStreamOutEventCallback { |
| Return<void> onCodecFormatChanged(const hidl_vec<uint8_t>& audioMetadata __unused) override { |
| return {}; |
| } |
| }; |
| |
| TEST_P(OutputStreamTest, SetEventCallback) { |
| doc::test("If supported, set event callback for output stream should never fail"); |
| auto res = stream->setEventCallback(new MockOutEventCallbacks); |
| EXPECT_RESULT(okOrNotSupported, res); |
| if (res == Result::OK) { |
| ASSERT_OK(stream->setEventCallback(nullptr)); |
| } else { |
| doc::partialTest("The stream does not support event callback"); |
| } |
| } |