• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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