1 /*
2 * Copyright (C) 2018 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 #include "AudioPrimaryHidlHalTest.h"
18
TEST_P(AudioHidlTest,OpenPrimaryDeviceUsingGetDevice)19 TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
20 doc::test("Calling openDevice(\"primary\") should return the primary device.");
21 if (getDeviceName() != DeviceManager::kPrimaryDevice) {
22 GTEST_SKIP() << "No primary device on this factory"; // returns
23 }
24
25 { // Scope for device SPs
26 sp<IDevice> baseDevice =
27 DeviceManager::getInstance().get(getFactoryName(), DeviceManager::kPrimaryDevice);
28 ASSERT_TRUE(baseDevice != nullptr);
29 Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice);
30 EXPECT_TRUE(primaryDevice.isOk());
31 EXPECT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr);
32 }
33 EXPECT_TRUE(
34 DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice));
35 }
36
37 //////////////////////////////////////////////////////////////////////////////
38 /////////////////////////// get(Active)Microphones ///////////////////////////
39 //////////////////////////////////////////////////////////////////////////////
40
TEST_P(AudioHidlDeviceTest,GetMicrophonesTest)41 TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
42 doc::test("Make sure getMicrophones always succeeds");
43 hidl_vec<MicrophoneInfo> microphones;
44 ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
45 if (res == Result::NOT_SUPPORTED) {
46 GTEST_SKIP() << "getMicrophones is not supported"; // returns
47 }
48 ASSERT_OK(res);
49 if (microphones.size() > 0) {
50 // When there is microphone on the phone, try to open an input stream
51 // and query for the active microphones.
52 doc::test(
53 "Make sure getMicrophones always succeeds"
54 "and getActiveMicrophones always succeeds when recording from these microphones.");
55 AudioConfig config{};
56 config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
57 config.sampleRateHz = 8000;
58 config.format = AudioFormat::PCM_16_BIT;
59 auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
60 const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
61 EventFlag* efGroup;
62 for (auto microphone : microphones) {
63 if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
64 continue;
65 }
66 sp<IStreamIn> stream;
67 StreamHelper<IStreamIn> helper(stream);
68 AudioConfig suggestedConfig{};
69 ASSERT_NO_FATAL_FAILURE(helper.open(
70 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
71 return getDevice()->openInputStream(handle, microphone.deviceAddress,
72 config, flags, initMetadata, cb);
73 },
74 config, &res, &suggestedConfig));
75 hidl_vec<MicrophoneInfo> activeMicrophones;
76 Result readRes;
77 typedef MessageQueue<IStreamIn::ReadParameters, kSynchronizedReadWrite> CommandMQ;
78 typedef MessageQueue<uint8_t, kSynchronizedReadWrite> DataMQ;
79 std::unique_ptr<CommandMQ> commandMQ;
80 std::unique_ptr<DataMQ> dataMQ;
81 size_t frameSize = stream->getFrameSize();
82 size_t frameCount = stream->getBufferSize() / frameSize;
83 ASSERT_OK(stream->prepareForReading(
84 frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto&) {
85 readRes = r;
86 if (readRes == Result::OK) {
87 commandMQ.reset(new CommandMQ(c));
88 dataMQ.reset(new DataMQ(d));
89 if (dataMQ->isValid() && dataMQ->getEventFlagWord()) {
90 EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup);
91 }
92 }
93 }));
94 ASSERT_OK(readRes);
95 IStreamIn::ReadParameters params;
96 params.command = IStreamIn::ReadCommand::READ;
97 ASSERT_TRUE(commandMQ != nullptr);
98 ASSERT_TRUE(commandMQ->isValid());
99 ASSERT_TRUE(commandMQ->write(¶ms));
100 efGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
101 uint32_t efState = 0;
102 efGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
103 if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
104 ASSERT_OK(stream->getActiveMicrophones(returnIn(res, activeMicrophones)));
105 ASSERT_OK(res);
106 ASSERT_NE(0U, activeMicrophones.size());
107 }
108 helper.close(true /*clear*/, &res);
109 ASSERT_OK(res);
110 if (efGroup) {
111 EventFlag::deleteEventFlag(&efGroup);
112 }
113 }
114 }
115 }
116
TEST_P(AudioHidlDeviceTest,SetConnectedState)117 TEST_P(AudioHidlDeviceTest, SetConnectedState) {
118 doc::test("Check that the HAL can be notified of device connection and deconnection");
119 using AD = AudioDevice;
120 for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
121 SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType));
122 for (bool state : {true, false}) {
123 SCOPED_TRACE("state=" + ::testing::PrintToString(state));
124 DeviceAddress address = {};
125 address.device = deviceType;
126 auto ret = getDevice()->setConnectedState(address, state);
127 ASSERT_TRUE(ret.isOk());
128 if (ret == Result::NOT_SUPPORTED) {
129 doc::partialTest("setConnectedState is not supported");
130 break; // other deviceType might be supported
131 }
132 ASSERT_OK(ret);
133 }
134 }
135
136 // Because there is no way of knowing if the devices were connected before
137 // calling setConnectedState, there is no way to restore the HAL to its
138 // initial state. To workaround this, destroy the HAL at the end of this test.
139 ASSERT_TRUE(resetDevice());
140 }
141
testGetDevices(IStream * stream,AudioDevice expectedDevice)142 static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
143 hidl_vec<DeviceAddress> devices;
144 Result res;
145 ASSERT_OK(stream->getDevices(returnIn(res, devices)));
146 if (res == Result::NOT_SUPPORTED) {
147 return doc::partialTest("GetDevices is not supported");
148 }
149 // The stream was constructed with one device, thus getDevices must only return one
150 ASSERT_EQ(1U, devices.size());
151 AudioDevice device = devices[0].device;
152 ASSERT_TRUE(device == expectedDevice)
153 << "Expected: " << ::testing::PrintToString(expectedDevice)
154 << "\n Actual: " << ::testing::PrintToString(device);
155 }
156
157 TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opened with",
158 areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
159 : testGetDevices(stream.get(), address.device))
160
testSetDevices(IStream * stream,const DeviceAddress & address)161 static void testSetDevices(IStream* stream, const DeviceAddress& address) {
162 DeviceAddress otherAddress = address;
163 otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER
164 : AudioDevice::IN_BUILTIN_MIC;
165 EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress}));
166
167 ASSERT_RESULT(okOrNotSupported,
168 stream->setDevices({address})); // Go back to the original value
169 }
170
171 TEST_IO_STREAM(SetDevices, "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
172 areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
173 : testSetDevices(stream.get(), address))
174
checkGetHwAVSync(IDevice * device)175 static void checkGetHwAVSync(IDevice* device) {
176 Result res;
177 AudioHwSync sync;
178 ASSERT_OK(device->getHwAvSync(returnIn(res, sync)));
179 if (res == Result::NOT_SUPPORTED) {
180 return doc::partialTest("getHwAvSync is not supported");
181 }
182 ASSERT_OK(res);
183 }
184 TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(getDevice().get()));
185
TEST_P(InputStreamTest,updateSinkMetadata)186 TEST_P(InputStreamTest, updateSinkMetadata) {
187 doc::test("The HAL should not crash on metadata change");
188
189 hidl_enum_range<AudioSource> range;
190 // Test all possible track configuration
191 for (AudioSource source : range) {
192 for (float volume : {0.0, 0.5, 1.0}) {
193 const SinkMetadata metadata = {{{.source = source, .gain = volume}}};
194 ASSERT_OK(stream->updateSinkMetadata(metadata))
195 << "source=" << toString(source) << ", volume=" << volume;
196 }
197 }
198
199 // Do not test concurrent capture as this is not officially supported
200
201 // Set no metadata as if all stream track had stopped
202 ASSERT_OK(stream->updateSinkMetadata({}));
203
204 // Restore initial
205 ASSERT_OK(stream->updateSinkMetadata(initMetadata));
206 }
207
TEST_P(OutputStreamTest,SelectPresentation)208 TEST_P(OutputStreamTest, SelectPresentation) {
209 doc::test("Verify that presentation selection does not crash");
210 ASSERT_RESULT(okOrNotSupported, stream->selectPresentation(0, 0));
211 }
212
TEST_P(OutputStreamTest,updateSourceMetadata)213 TEST_P(OutputStreamTest, updateSourceMetadata) {
214 doc::test("The HAL should not crash on metadata change");
215
216 hidl_enum_range<AudioUsage> usageRange;
217 hidl_enum_range<AudioContentType> contentRange;
218 // Test all possible track configuration
219 for (auto usage : usageRange) {
220 for (auto content : contentRange) {
221 for (float volume : {0.0, 0.5, 1.0}) {
222 const SourceMetadata metadata = {{{usage, content, volume}}};
223 ASSERT_OK(stream->updateSourceMetadata(metadata))
224 << "usage=" << toString(usage) << ", content=" << toString(content)
225 << ", volume=" << volume;
226 }
227 }
228 }
229
230 // Set many track of different configuration
231 ASSERT_OK(stream->updateSourceMetadata(
232 {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 0.1},
233 {AudioUsage::VOICE_COMMUNICATION, AudioContentType::SPEECH, 1.0},
234 {AudioUsage::ALARM, AudioContentType::SONIFICATION, 0.0},
235 {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}}));
236
237 // Set no metadata as if all stream track had stopped
238 ASSERT_OK(stream->updateSourceMetadata({}));
239
240 // Restore initial
241 ASSERT_OK(stream->updateSourceMetadata(initMetadata));
242 }
243
TEST_P(AudioPrimaryHidlTest,setMode)244 TEST_P(AudioPrimaryHidlTest, setMode) {
245 doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
246 // Test Invalid values
247 #if MAJOR_VERSION >= 6
248 int maxMode = int(AudioMode::CALL_SCREEN);
249 #else
250 int maxMode = int(AudioMode::IN_COMMUNICATION);
251 #endif
252
253 for (int mode : {-2, -1, maxMode + 1}) {
254 ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode)))
255 << "mode=" << mode;
256 }
257 // Test valid values
258 for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
259 AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
260 ASSERT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode);
261 }
262 // AudioMode::CALL_SCREEN as support is optional
263 #if MAJOR_VERSION >= 6
264 ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setMode(AudioMode::CALL_SCREEN));
265 #endif
266 }
267
TEST_P(AudioPrimaryHidlTest,setBtHfpSampleRate)268 TEST_P(AudioPrimaryHidlTest, setBtHfpSampleRate) {
269 doc::test(
270 "Make sure setBtHfpSampleRate either succeeds or "
271 "indicates that it is not supported at all, or that the provided value is invalid");
272 for (auto samplingRate : {8000, 16000, 22050, 24000}) {
273 ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setBtHfpSampleRate(samplingRate));
274 }
275 }
276
TEST_P(AudioPrimaryHidlTest,setBtHfpVolume)277 TEST_P(AudioPrimaryHidlTest, setBtHfpVolume) {
278 doc::test(
279 "Make sure setBtHfpVolume is either not supported or "
280 "only succeed if volume is in [0,1]");
281 auto ret = getDevice()->setBtHfpVolume(0.0);
282 ASSERT_TRUE(ret.isOk());
283 if (ret == Result::NOT_SUPPORTED) {
284 doc::partialTest("setBtHfpVolume is not supported");
285 return;
286 }
287 testUnitaryGain([this](float volume) { return getDevice()->setBtHfpVolume(volume); });
288 }
289
TEST_P(AudioPrimaryHidlTest,setBtScoHeadsetDebugName)290 TEST_P(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) {
291 doc::test(
292 "Make sure setBtScoHeadsetDebugName either succeeds or "
293 "indicates that it is not supported");
294 ASSERT_RESULT(okOrNotSupported, getDevice()->setBtScoHeadsetDebugName("test"));
295 }
296
TEST_P(AudioPrimaryHidlTest,updateRotation)297 TEST_P(AudioPrimaryHidlTest, updateRotation) {
298 doc::test("Check that the hal can receive the current rotation");
299 for (Rotation rotation : {Rotation::DEG_0, Rotation::DEG_90, Rotation::DEG_180,
300 Rotation::DEG_270, Rotation::DEG_0}) {
301 ASSERT_RESULT(okOrNotSupported, getDevice()->updateRotation(rotation));
302 }
303 }
304
TEST_P(BoolAccessorPrimaryHidlTest,setGetBtHfpEnabled)305 TEST_P(BoolAccessorPrimaryHidlTest, setGetBtHfpEnabled) {
306 doc::test("Query and set the BT HFP state");
307 testAccessors<OPTIONAL>("BtHfpEnabled", Initial{false, OPTIONAL}, {true},
308 &IPrimaryDevice::setBtHfpEnabled, &IPrimaryDevice::getBtHfpEnabled);
309 }
310