1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // pull in all the <= 5.0 tests
18 #include "5.0/AudioPrimaryHidlHalTest.cpp"
19
getOutputDeviceConfigParameters()20 const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
21 static std::vector<DeviceConfigParameter> parameters = [] {
22 std::vector<DeviceConfigParameter> result;
23 for (const auto& device : getDeviceParameters()) {
24 auto module =
25 getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
26 for (const auto& ioProfile : module->getOutputProfiles()) {
27 for (const auto& profile : ioProfile->getAudioProfiles()) {
28 const auto& channels = profile->getChannels();
29 const auto& sampleRates = profile->getSampleRates();
30 auto configs = ConfigHelper::combineAudioConfig(
31 vector<audio_channel_mask_t>(channels.begin(), channels.end()),
32 vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
33 profile->getFormat());
34 auto flags = ioProfile->getFlags();
35 for (auto& config : configs) {
36 // Some combinations of flags declared in the config file require special
37 // treatment.
38 if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
39 config.offloadInfo.sampleRateHz = config.sampleRateHz;
40 config.offloadInfo.channelMask = config.channelMask;
41 config.offloadInfo.format = config.format;
42 config.offloadInfo.streamType = AudioStreamType::MUSIC;
43 config.offloadInfo.bitRatePerSecond = 320;
44 config.offloadInfo.durationMicroseconds = -1;
45 config.offloadInfo.bitWidth = 16;
46 config.offloadInfo.bufferSize = 256; // arbitrary value
47 config.offloadInfo.usage = AudioUsage::MEDIA;
48 result.emplace_back(device, config,
49 AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
50 AUDIO_OUTPUT_FLAG_DIRECT));
51 } else {
52 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
53 flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
54 }
55 result.emplace_back(device, config, AudioOutputFlag(flags));
56 }
57 }
58 }
59 }
60 }
61 return result;
62 }();
63 return parameters;
64 }
65
getInputDeviceConfigParameters()66 const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
67 static std::vector<DeviceConfigParameter> parameters = [] {
68 std::vector<DeviceConfigParameter> result;
69 for (const auto& device : getDeviceParameters()) {
70 auto module =
71 getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
72 for (const auto& ioProfile : module->getInputProfiles()) {
73 for (const auto& profile : ioProfile->getAudioProfiles()) {
74 const auto& channels = profile->getChannels();
75 const auto& sampleRates = profile->getSampleRates();
76 auto configs = ConfigHelper::combineAudioConfig(
77 vector<audio_channel_mask_t>(channels.begin(), channels.end()),
78 vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
79 profile->getFormat());
80 for (const auto& config : configs) {
81 result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
82 }
83 }
84 }
85 }
86 return result;
87 }();
88 return parameters;
89 }
90
TEST_P(AudioHidlDeviceTest,CloseDeviceWithOpenedOutputStreams)91 TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) {
92 doc::test("Verify that a device can't be closed if there are streams opened");
93 DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
94 AudioConfig config{};
95 auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
96 SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
97 sp<IStreamOut> stream;
98 StreamHelper<IStreamOut> helper(stream);
99 AudioConfig suggestedConfig{};
100 ASSERT_NO_FATAL_FAILURE(helper.open(
101 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
102 return getDevice()->openOutputStream(handle, address, config, flags, initMetadata,
103 cb);
104 },
105 config, &res, &suggestedConfig));
106 ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
107 ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
108 ASSERT_OK(getDevice()->close());
109 ASSERT_TRUE(resetDevice());
110 }
111
TEST_P(AudioHidlDeviceTest,CloseDeviceWithOpenedInputStreams)112 TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) {
113 doc::test("Verify that a device can't be closed if there are streams opened");
114 auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName());
115 if (module->getInputProfiles().empty()) {
116 GTEST_SKIP() << "Device doesn't have input profiles";
117 }
118 DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
119 AudioConfig config{};
120 auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
121 SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
122 sp<IStreamIn> stream;
123 StreamHelper<IStreamIn> helper(stream);
124 AudioConfig suggestedConfig{};
125 ASSERT_NO_FATAL_FAILURE(helper.open(
126 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
127 return getDevice()->openInputStream(handle, address, config, flags, initMetadata,
128 cb);
129 },
130 config, &res, &suggestedConfig));
131 ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
132 ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
133 ASSERT_OK(getDevice()->close());
134 ASSERT_TRUE(resetDevice());
135 }
136
TEST_P(AudioPatchHidlTest,UpdatePatchInvalidHandle)137 TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
138 doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
139 AudioPatchHandle ignored;
140 ASSERT_OK(getDevice()->updateAudioPatch(
141 static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE),
142 hidl_vec<AudioPortConfig>(), hidl_vec<AudioPortConfig>(), returnIn(res, ignored)));
143 ASSERT_RESULT(Result::INVALID_ARGUMENTS, res);
144 }
145
146 using DualMonoModeAccessorHidlTest = AccessorHidlTest<DualMonoMode, OutputStreamTest>;
TEST_P(DualMonoModeAccessorHidlTest,DualMonoModeTest)147 TEST_P(DualMonoModeAccessorHidlTest, DualMonoModeTest) {
148 doc::test("Check that dual mono mode can be set and retrieved");
149 testAccessors<OPTIONAL>(&OutputStreamTest::getStream, "dual mono mode",
150 Initial{DualMonoMode::OFF},
151 {DualMonoMode::LR, DualMonoMode::LL, DualMonoMode::RR},
152 &IStreamOut::setDualMonoMode, &IStreamOut::getDualMonoMode);
153 }
154
155 INSTANTIATE_TEST_CASE_P(DualMonoModeHidl, DualMonoModeAccessorHidlTest,
156 ::testing::ValuesIn(getOutputDeviceConfigParameters()),
157 &DeviceConfigParameterToString);
158
159 using AudioDescriptionMixLevelHidlTest = AccessorHidlTest<float, OutputStreamTest>;
TEST_P(AudioDescriptionMixLevelHidlTest,AudioDescriptionMixLevelTest)160 TEST_P(AudioDescriptionMixLevelHidlTest, AudioDescriptionMixLevelTest) {
161 doc::test("Check that audio description mix level can be set and retrieved");
162 testAccessors<OPTIONAL>(
163 &OutputStreamTest::getStream, "audio description mix level",
164 Initial{-std::numeric_limits<float>::infinity()}, {-48.0f, -1.0f, 0.0f, 1.0f, 48.0f},
165 &IStreamOut::setAudioDescriptionMixLevel, &IStreamOut::getAudioDescriptionMixLevel,
166 {48.5f, 1000.0f, std::numeric_limits<float>::infinity()});
167 }
168
169 INSTANTIATE_TEST_CASE_P(AudioDescriptionMixLevelHidl, AudioDescriptionMixLevelHidlTest,
170 ::testing::ValuesIn(getOutputDeviceConfigParameters()),
171 &DeviceConfigParameterToString);
172
173 using PlaybackRateParametersHidlTest = AccessorHidlTest<PlaybackRate, OutputStreamTest>;
TEST_P(PlaybackRateParametersHidlTest,PlaybackRateParametersTest)174 TEST_P(PlaybackRateParametersHidlTest, PlaybackRateParametersTest) {
175 doc::test("Check that playback rate parameters can be set and retrieved");
176 testAccessors<OPTIONAL>(
177 &OutputStreamTest::getStream, "playback rate parameters",
178 Initial{PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT,
179 TimestretchFallbackMode::FAIL}},
180 {// Speed and pitch values in the range from 0.5f to 2.0f must be supported
181 // (see the definition of IStreamOut::setPlaybackRateParameters).
182 PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
183 PlaybackRate{2.0f, 2.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
184 PlaybackRate{0.5f, 0.5f, TimestretchMode::DEFAULT, TimestretchFallbackMode::MUTE},
185 // Gross speed / pitch values must not be rejected if the fallback mode is "mute"
186 PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
187 TimestretchFallbackMode::MUTE},
188 // Default speed / pitch values must not be rejected in "fail" fallback mode
189 PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL},
190 // Same for "voice" mode
191 PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
192 PlaybackRate{2.0f, 2.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
193 PlaybackRate{0.5f, 0.5f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
194 PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE, TimestretchFallbackMode::MUTE},
195 PlaybackRate{1.0f, 1.0f, TimestretchMode::VOICE, TimestretchFallbackMode::FAIL}},
196 &IStreamOut::setPlaybackRateParameters, &IStreamOut::getPlaybackRateParameters,
197 {PlaybackRate{1000.0f, 1000.0f, TimestretchMode::DEFAULT,
198 TimestretchFallbackMode::FAIL},
199 PlaybackRate{1000.0f, 1000.0f, TimestretchMode::VOICE,
200 TimestretchFallbackMode::FAIL}});
201 }
202
203 INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest,
204 ::testing::ValuesIn(getOutputDeviceConfigParameters()),
205 &DeviceConfigParameterToString);
206
207 /** Stub implementation of IStreamOutEventCallback **/
208 class MockOutEventCallbacks : public IStreamOutEventCallback {
onCodecFormatChanged(const hidl_vec<uint8_t> & audioMetadata __unused)209 Return<void> onCodecFormatChanged(const hidl_vec<uint8_t>& audioMetadata __unused) override {
210 return {};
211 }
212 };
213
TEST_P(OutputStreamTest,SetEventCallback)214 TEST_P(OutputStreamTest, SetEventCallback) {
215 doc::test("If supported, set event callback for output stream should never fail");
216 auto res = stream->setEventCallback(new MockOutEventCallbacks);
217 EXPECT_RESULT(okOrNotSupported, res);
218 if (res == Result::OK) {
219 ASSERT_OK(stream->setEventCallback(nullptr));
220 } else {
221 doc::partialTest("The stream does not support event callback");
222 }
223 }
224