• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params));
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