1 /*
2 * Copyright 2025 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 #define LOG_TAG "EffectHalAidlTest"
18
19 #include "EffectHalAidl.h"
20
21 #include <aidl/android/hardware/audio/effect/BnEffect.h>
22 #include <aidl/android/hardware/audio/effect/BnFactory.h>
23
24 #include <aidl/android/hardware/audio/effect/Parameter.h>
25 #include <android/binder_status.h>
26 #include <media/AudioDeviceTypeAddr.h>
27 #include <utils/Log.h>
28
29 #include <gmock/gmock.h>
30 #include <gtest/gtest.h>
31 #include <utility>
32 #include <vector>
33
34 namespace {
35
36 using ::aidl::android::hardware::audio::effect::CommandId;
37 using ::aidl::android::hardware::audio::effect::Descriptor;
38 using ::aidl::android::hardware::audio::effect::IEffect;
39 using ::aidl::android::hardware::audio::effect::Parameter;
40 using ::aidl::android::hardware::audio::effect::Processing;
41 using ::aidl::android::hardware::audio::effect::State;
42 using ::aidl::android::media::audio::common::AudioDeviceDescription;
43 using ::aidl::android::media::audio::common::AudioDeviceType;
44 using ::aidl::android::media::audio::common::AudioUuid;
45 using android::AudioDeviceTypeAddr;
46 using android::AudioDeviceTypeAddrVector;
47 using android::OK;
48 using android::sp;
49 using android::effect::EffectHalAidl;
50
51 using ::testing::_;
52 using ::testing::Return;
53
54 class IFactoryMock : public ::aidl::android::hardware::audio::effect::BnFactory {
55 public:
56 IFactoryMock() = default;
57
queryEffects(const std::optional<AudioUuid> &,const std::optional<AudioUuid> &,const std::optional<AudioUuid> &,std::vector<Descriptor> *)58 ndk::ScopedAStatus queryEffects(const std::optional<AudioUuid>&,
59 const std::optional<AudioUuid>&,
60 const std::optional<AudioUuid>&,
61 std::vector<Descriptor>*) override {
62 return ndk::ScopedAStatus::ok();
63 }
64
queryProcessing(const std::optional<Processing::Type> &,std::vector<Processing> *)65 ndk::ScopedAStatus queryProcessing(const std::optional<Processing::Type>&,
66 std::vector<Processing>*) override {
67 return ndk::ScopedAStatus::ok();
68 }
69
createEffect(const AudioUuid &,std::shared_ptr<IEffect> *)70 ndk::ScopedAStatus createEffect(const AudioUuid&, std::shared_ptr<IEffect>*) override {
71 return ndk::ScopedAStatus::ok();
72 }
73
destroyEffect(const std::shared_ptr<IEffect> &)74 ndk::ScopedAStatus destroyEffect(const std::shared_ptr<IEffect>&) override {
75 return ndk::ScopedAStatus::ok();
76 }
77 };
78
79 class IEffectMock : public ::aidl::android::hardware::audio::effect::BnEffect {
80 public:
81 IEffectMock() = default;
82
83 MOCK_METHOD(ndk::ScopedAStatus, open,
84 (const Parameter::Common& common, const std::optional<Parameter::Specific>& spec,
85 IEffect::OpenEffectReturn* ret),
86 (override));
87 MOCK_METHOD(ndk::ScopedAStatus, close, (), (override));
88 MOCK_METHOD(ndk::ScopedAStatus, getDescriptor, (Descriptor * desc), (override));
89 MOCK_METHOD(ndk::ScopedAStatus, command, (CommandId commandId), (override));
90 MOCK_METHOD(ndk::ScopedAStatus, getState, (State * state), (override));
91 MOCK_METHOD(ndk::ScopedAStatus, getParameter, (const Parameter::Id& id, Parameter* param),
92 (override));
93 MOCK_METHOD(ndk::ScopedAStatus, reopen, (IEffect::OpenEffectReturn * ret), (override));
94
setParameter(const Parameter & param)95 ndk::ScopedAStatus setParameter(const Parameter& param) {
96 if (param == mExpectParam)
97 return ndk::ScopedAStatus::ok();
98 else {
99 ALOGW("%s mismatch, %s vs %s", __func__, param.toString().c_str(),
100 mExpectParam.toString().c_str());
101 return ndk::ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
102 }
103 }
104
setExpectParameter(const Parameter & param)105 void setExpectParameter(const Parameter& param) { mExpectParam = param; }
106
107 private:
108 Parameter mExpectParam;
109 };
110
111 // Predefined vector of {audio_devices_t, AudioDeviceDescription} pair
112 static const std::vector<std::pair<audio_devices_t, AudioDeviceDescription>>& kAudioDevicePairs = {
113 {AUDIO_DEVICE_NONE, AudioDeviceDescription{.type = AudioDeviceType::NONE}},
114 {AUDIO_DEVICE_OUT_EARPIECE,
115 AudioDeviceDescription{.type = AudioDeviceType::OUT_SPEAKER_EARPIECE}},
116 {AUDIO_DEVICE_OUT_SPEAKER, AudioDeviceDescription{.type = AudioDeviceType::OUT_SPEAKER}},
117 {AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
118 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADPHONE,
119 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
120 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO,
121 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
122 .connection = AudioDeviceDescription::CONNECTION_BT_SCO}},
123 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
124 AudioDeviceDescription{.type = AudioDeviceType::OUT_CARKIT,
125 .connection = AudioDeviceDescription::CONNECTION_BT_SCO}},
126 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
127 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADPHONE,
128 .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}},
129 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,
130 AudioDeviceDescription{.type = AudioDeviceType::OUT_SPEAKER,
131 .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}},
132 {AUDIO_DEVICE_OUT_TELEPHONY_TX,
133 AudioDeviceDescription{.type = AudioDeviceType::OUT_TELEPHONY_TX}},
134 {AUDIO_DEVICE_OUT_AUX_LINE, AudioDeviceDescription{.type = AudioDeviceType::OUT_LINE_AUX}},
135 {AUDIO_DEVICE_OUT_SPEAKER_SAFE,
136 AudioDeviceDescription{.type = AudioDeviceType::OUT_SPEAKER_SAFE}},
137 {AUDIO_DEVICE_OUT_HEARING_AID,
138 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEARING_AID,
139 .connection = AudioDeviceDescription::CONNECTION_WIRELESS}},
140 {AUDIO_DEVICE_OUT_ECHO_CANCELLER,
141 AudioDeviceDescription{.type = AudioDeviceType::OUT_ECHO_CANCELLER}},
142 {AUDIO_DEVICE_OUT_BLE_SPEAKER,
143 AudioDeviceDescription{.type = AudioDeviceType::OUT_SPEAKER,
144 .connection = AudioDeviceDescription::CONNECTION_BT_LE}},
145 {AUDIO_DEVICE_OUT_BLE_BROADCAST,
146 AudioDeviceDescription{.type = AudioDeviceType::OUT_BROADCAST,
147 .connection = AudioDeviceDescription::CONNECTION_BT_LE}},
148 {AUDIO_DEVICE_OUT_MULTICHANNEL_GROUP,
149 AudioDeviceDescription{.type = AudioDeviceType::OUT_MULTICHANNEL_GROUP,
150 .connection = AudioDeviceDescription::CONNECTION_VIRTUAL}},
151
152 {AUDIO_DEVICE_OUT_DEFAULT, AudioDeviceDescription{.type = AudioDeviceType::OUT_DEFAULT}},
153 {AUDIO_DEVICE_OUT_WIRED_HEADSET,
154 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADSET,
155 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
156 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
157 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADSET,
158 .connection = AudioDeviceDescription::CONNECTION_BT_SCO}},
159 {AUDIO_DEVICE_OUT_HDMI,
160 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
161 .connection = AudioDeviceDescription::CONNECTION_HDMI}},
162 {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET,
163 AudioDeviceDescription{.type = AudioDeviceType::OUT_DOCK,
164 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
165 {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
166 AudioDeviceDescription{.type = AudioDeviceType::OUT_DOCK,
167 .connection = AudioDeviceDescription::CONNECTION_USB}},
168 {AUDIO_DEVICE_OUT_USB_ACCESSORY,
169 AudioDeviceDescription{.type = AudioDeviceType::OUT_ACCESSORY,
170 .connection = AudioDeviceDescription::CONNECTION_USB}},
171 {AUDIO_DEVICE_OUT_USB_DEVICE,
172 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
173 .connection = AudioDeviceDescription::CONNECTION_USB}},
174 {AUDIO_DEVICE_OUT_FM, AudioDeviceDescription{.type = AudioDeviceType::OUT_FM}},
175 {AUDIO_DEVICE_OUT_LINE,
176 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
177 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
178 {AUDIO_DEVICE_OUT_SPDIF,
179 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
180 .connection = AudioDeviceDescription::CONNECTION_SPDIF}},
181 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
182 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
183 .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}},
184 {AUDIO_DEVICE_OUT_IP,
185 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
186 .connection = AudioDeviceDescription::CONNECTION_IP_V4}},
187 {AUDIO_DEVICE_OUT_BUS, AudioDeviceDescription{.type = AudioDeviceType::OUT_BUS}},
188 {AUDIO_DEVICE_OUT_PROXY,
189 AudioDeviceDescription{.type = AudioDeviceType::OUT_AFE_PROXY,
190 .connection = AudioDeviceDescription::CONNECTION_VIRTUAL}},
191 {AUDIO_DEVICE_OUT_USB_HEADSET,
192 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADSET,
193 .connection = AudioDeviceDescription::CONNECTION_USB}},
194 {AUDIO_DEVICE_OUT_HDMI_ARC,
195 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
196 .connection = AudioDeviceDescription::CONNECTION_HDMI_ARC}},
197 {AUDIO_DEVICE_OUT_HDMI_EARC,
198 AudioDeviceDescription{.type = AudioDeviceType::OUT_DEVICE,
199 .connection = AudioDeviceDescription::CONNECTION_HDMI_EARC}},
200 {AUDIO_DEVICE_OUT_BLE_HEADSET,
201 AudioDeviceDescription{.type = AudioDeviceType::OUT_HEADSET,
202 .connection = AudioDeviceDescription::CONNECTION_BT_LE}},
203 {AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
204 AudioDeviceDescription{.type = AudioDeviceType::OUT_SUBMIX,
205 .connection = AudioDeviceDescription::CONNECTION_VIRTUAL}},
206 {AUDIO_DEVICE_IN_BUILTIN_MIC,
207 AudioDeviceDescription{.type = AudioDeviceType::IN_MICROPHONE}},
208 {AUDIO_DEVICE_IN_BACK_MIC,
209 AudioDeviceDescription{.type = AudioDeviceType::IN_MICROPHONE_BACK}},
210 {AUDIO_DEVICE_IN_TELEPHONY_RX,
211 AudioDeviceDescription{.type = AudioDeviceType::IN_TELEPHONY_RX}},
212 {AUDIO_DEVICE_IN_TV_TUNER, AudioDeviceDescription{.type = AudioDeviceType::IN_TV_TUNER}},
213 {AUDIO_DEVICE_IN_LOOPBACK, AudioDeviceDescription{.type = AudioDeviceType::IN_LOOPBACK}},
214 {AUDIO_DEVICE_IN_BLUETOOTH_BLE,
215 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
216 .connection = AudioDeviceDescription::CONNECTION_BT_LE}},
217 {AUDIO_DEVICE_IN_ECHO_REFERENCE,
218 AudioDeviceDescription{.type = AudioDeviceType::IN_ECHO_REFERENCE}},
219 {AUDIO_DEVICE_IN_DEFAULT, AudioDeviceDescription{.type = AudioDeviceType::IN_DEFAULT}},
220 {AUDIO_DEVICE_IN_WIRED_HEADSET,
221 AudioDeviceDescription{.type = AudioDeviceType::IN_HEADSET,
222 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
223 {AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
224 AudioDeviceDescription{.type = AudioDeviceType::IN_HEADSET,
225 .connection = AudioDeviceDescription::CONNECTION_BT_SCO}},
226 {AUDIO_DEVICE_IN_HDMI,
227 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
228 .connection = AudioDeviceDescription::CONNECTION_HDMI}},
229 {AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET,
230 AudioDeviceDescription{.type = AudioDeviceType::IN_DOCK,
231 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
232 {AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET,
233 AudioDeviceDescription{.type = AudioDeviceType::IN_DOCK,
234 .connection = AudioDeviceDescription::CONNECTION_USB}},
235 {AUDIO_DEVICE_IN_USB_ACCESSORY,
236 AudioDeviceDescription{.type = AudioDeviceType::IN_ACCESSORY,
237 .connection = AudioDeviceDescription::CONNECTION_USB}},
238 {AUDIO_DEVICE_IN_USB_DEVICE,
239 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
240 .connection = AudioDeviceDescription::CONNECTION_USB}},
241 {AUDIO_DEVICE_IN_FM_TUNER, AudioDeviceDescription{.type = AudioDeviceType::IN_FM_TUNER}},
242 {AUDIO_DEVICE_IN_LINE,
243 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
244 .connection = AudioDeviceDescription::CONNECTION_ANALOG}},
245 {AUDIO_DEVICE_IN_SPDIF,
246 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
247 .connection = AudioDeviceDescription::CONNECTION_SPDIF}},
248 {AUDIO_DEVICE_IN_BLUETOOTH_A2DP,
249 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
250 .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}},
251 {AUDIO_DEVICE_IN_IP,
252 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
253 .connection = AudioDeviceDescription::CONNECTION_IP_V4}},
254 {AUDIO_DEVICE_IN_BUS, AudioDeviceDescription{.type = AudioDeviceType::IN_BUS}},
255 {AUDIO_DEVICE_IN_PROXY,
256 AudioDeviceDescription{.type = AudioDeviceType::IN_AFE_PROXY,
257 .connection = AudioDeviceDescription::CONNECTION_VIRTUAL}},
258 {AUDIO_DEVICE_IN_USB_HEADSET,
259 AudioDeviceDescription{.type = AudioDeviceType::IN_HEADSET,
260 .connection = AudioDeviceDescription::CONNECTION_USB}},
261 {AUDIO_DEVICE_IN_HDMI_ARC,
262 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
263 .connection = AudioDeviceDescription::CONNECTION_HDMI_ARC}},
264 {AUDIO_DEVICE_IN_HDMI_EARC,
265 AudioDeviceDescription{.type = AudioDeviceType::IN_DEVICE,
266 .connection = AudioDeviceDescription::CONNECTION_HDMI_EARC}},
267 {AUDIO_DEVICE_IN_BLE_HEADSET,
268 AudioDeviceDescription{.type = AudioDeviceType::IN_HEADSET,
269 .connection = AudioDeviceDescription::CONNECTION_BT_LE}},
270 {AUDIO_DEVICE_IN_REMOTE_SUBMIX,
271 AudioDeviceDescription{.type = AudioDeviceType::IN_SUBMIX,
272 .connection = AudioDeviceDescription::CONNECTION_VIRTUAL}},
273 };
274
275 } // namespace
276
277 class EffectHalAidlTest : public testing::Test {
278 public:
SetUp()279 void SetUp() override {
280 mIEffectMock = ndk::SharedRefBase::make<IEffectMock>();
281 mIFactoryMock = ndk::SharedRefBase::make<IFactoryMock>();
282 mEffect = sp<EffectHalAidl>::make(mIFactoryMock, mIEffectMock, 0 /*session*/, 0 /*ioId*/,
283 mDescMock /* descriptor */, false /*isProxyEffect*/);
284 }
TearDown()285 void TearDown() override {
286 mIEffectMock.reset();
287 mIFactoryMock.reset();
288 mEffect.clear();
289 }
290
291 // Helper function to setDevice with one to multi (window size) device pairs set to effect, and
292 // expect the same from IEffect mocking object.
setDevicesWithWindow(size_t window=1)293 void setDevicesWithWindow(size_t window = 1) {
294 for (size_t i = 0; i + window < kAudioDevicePairs.size(); i += window) {
295 AudioDeviceTypeAddrVector deviceTypes;
296 std::vector<AudioDeviceDescription> deviceDescs;
297 for (size_t w = 0; w < window; w++) {
298 deviceTypes.emplace_back(kAudioDevicePairs[i + w].first /* audio_device_t */, "");
299 deviceDescs.emplace_back(
300 kAudioDevicePairs[i + w].second /* AudioDeviceDescription */);
301 }
302 const Parameter expect = Parameter::make<Parameter::deviceDescription>(deviceDescs);
303 mIEffectMock->setExpectParameter(expect);
304 EXPECT_EQ(OK, mEffect->setDevices(deviceTypes))
305 << " setDevices: "
306 << dumpAudioDeviceTypeAddrVector(deviceTypes, false /*includeSensitiveInfo*/)
307 << " expect: " << expect.toString();
308 }
309 }
310
311 protected:
312 std::shared_ptr<IEffectMock> mIEffectMock;
313 std::shared_ptr<IFactoryMock> mIFactoryMock;
314 Descriptor mDescMock;
315 sp<EffectHalAidl> mEffect;
316 };
317
TEST_F(EffectHalAidlTest,emptyDeviceSet)318 TEST_F(EffectHalAidlTest, emptyDeviceSet) {
319 AudioDeviceTypeAddr deviceType(AUDIO_DEVICE_NONE, "");
320 AudioDeviceTypeAddrVector deviceTypes{deviceType};
321 std::vector<AudioDeviceDescription> deviceDescs;
322
323 Parameter expect = Parameter::make<Parameter::deviceDescription>(deviceDescs);
324 mIEffectMock->setExpectParameter(expect);
325 EXPECT_NE(OK, mEffect->setDevices(deviceTypes))
326 << " expecting error with setDevices: "
327 << dumpAudioDeviceTypeAddrVector(deviceTypes, false /*includeSensitiveInfo*/)
328 << " expect: " << expect.toString();
329
330 deviceDescs.emplace_back(AudioDeviceDescription{.type = AudioDeviceType::NONE});
331 expect = Parameter::make<Parameter::deviceDescription>(deviceDescs);
332 mIEffectMock->setExpectParameter(expect);
333 EXPECT_EQ(OK, mEffect->setDevices(deviceTypes))
334 << " setDevices: "
335 << dumpAudioDeviceTypeAddrVector(deviceTypes, false /*includeSensitiveInfo*/)
336 << " expect: " << expect.toString();
337 }
338
339 // go over the `kAudioDevicePairs` pair, and setDevice for each pair
TEST_F(EffectHalAidlTest,deviceSinglePairSet)340 TEST_F(EffectHalAidlTest, deviceSinglePairSet) {
341 ASSERT_NO_FATAL_FAILURE(setDevicesWithWindow());
342 }
343
344 // SetDevice with multiple device pairs from `kAudioDevicePairs`
TEST_F(EffectHalAidlTest,deviceMultiplePairSet)345 TEST_F(EffectHalAidlTest, deviceMultiplePairSet) {
346 for (size_t window = 2; window < kAudioDevicePairs.size(); window++) {
347 ASSERT_NO_FATAL_FAILURE(setDevicesWithWindow(window));
348 }
349 }
350