1 /*
2 * Copyright 2023 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 <memory>
18 #include <string>
19 #include <vector>
20
21 #define LOG_TAG "CoreAudioHalAidlTest"
22 #include <gtest/gtest.h>
23
24 #include <DeviceHalAidl.h>
25 #include <StreamHalAidl.h>
26 #include <aidl/android/hardware/audio/core/BnModule.h>
27 #include <aidl/android/hardware/audio/core/BnStreamCommon.h>
28 #include <aidl/android/media/audio/BnHalAdapterVendorExtension.h>
29 #include <aidl/android/media/audio/common/Int.h>
30 #include <utils/Log.h>
31
32 namespace {
33
34 using ::aidl::android::hardware::audio::core::VendorParameter;
35
36 class VendorParameterMock {
37 public:
getRetrievedParameterIds() const38 const std::vector<std::string>& getRetrievedParameterIds() const { return mGetParameterIds; }
getAsyncParameters() const39 const std::vector<VendorParameter>& getAsyncParameters() const { return mAsyncParameters; }
getSyncParameters() const40 const std::vector<VendorParameter>& getSyncParameters() const { return mSyncParameters; }
41
42 protected:
getVendorParametersImpl(const std::vector<std::string> & in_parameterIds)43 ndk::ScopedAStatus getVendorParametersImpl(const std::vector<std::string>& in_parameterIds) {
44 mGetParameterIds.insert(mGetParameterIds.end(), in_parameterIds.begin(),
45 in_parameterIds.end());
46 return ndk::ScopedAStatus::ok();
47 }
setVendorParametersImpl(const std::vector<VendorParameter> & in_parameters,bool async)48 ndk::ScopedAStatus setVendorParametersImpl(const std::vector<VendorParameter>& in_parameters,
49 bool async) {
50 if (async) {
51 mAsyncParameters.insert(mAsyncParameters.end(), in_parameters.begin(),
52 in_parameters.end());
53 } else {
54 mSyncParameters.insert(mSyncParameters.end(), in_parameters.begin(),
55 in_parameters.end());
56 }
57 return ndk::ScopedAStatus::ok();
58 }
59
60 private:
61 std::vector<std::string> mGetParameterIds;
62 std::vector<VendorParameter> mAsyncParameters;
63 std::vector<VendorParameter> mSyncParameters;
64 };
65
66 class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule,
67 public VendorParameterMock {
68 public:
isScreenTurnedOn() const69 bool isScreenTurnedOn() const { return mIsScreenTurnedOn; }
getScreenRotation() const70 ScreenRotation getScreenRotation() const { return mScreenRotation; }
71
72 private:
setModuleDebug(const::aidl::android::hardware::audio::core::ModuleDebug &)73 ndk::ScopedAStatus setModuleDebug(
74 const ::aidl::android::hardware::audio::core::ModuleDebug&) override {
75 return ndk::ScopedAStatus::ok();
76 }
getTelephony(std::shared_ptr<::aidl::android::hardware::audio::core::ITelephony> *)77 ndk::ScopedAStatus getTelephony(
78 std::shared_ptr<::aidl::android::hardware::audio::core::ITelephony>*) override {
79 return ndk::ScopedAStatus::ok();
80 }
getBluetooth(std::shared_ptr<::aidl::android::hardware::audio::core::IBluetooth> *)81 ndk::ScopedAStatus getBluetooth(
82 std::shared_ptr<::aidl::android::hardware::audio::core::IBluetooth>*) override {
83 return ndk::ScopedAStatus::ok();
84 }
getBluetoothA2dp(std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothA2dp> *)85 ndk::ScopedAStatus getBluetoothA2dp(
86 std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothA2dp>*) override {
87 return ndk::ScopedAStatus::ok();
88 }
getBluetoothLe(std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothLe> *)89 ndk::ScopedAStatus getBluetoothLe(
90 std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothLe>*) override {
91 return ndk::ScopedAStatus::ok();
92 }
connectExternalDevice(const::aidl::android::media::audio::common::AudioPort &,::aidl::android::media::audio::common::AudioPort *)93 ndk::ScopedAStatus connectExternalDevice(
94 const ::aidl::android::media::audio::common::AudioPort&,
95 ::aidl::android::media::audio::common::AudioPort*) override {
96 return ndk::ScopedAStatus::ok();
97 }
disconnectExternalDevice(int32_t)98 ndk::ScopedAStatus disconnectExternalDevice(int32_t) override {
99 return ndk::ScopedAStatus::ok();
100 }
getAudioPatches(std::vector<::aidl::android::hardware::audio::core::AudioPatch> *)101 ndk::ScopedAStatus getAudioPatches(
102 std::vector<::aidl::android::hardware::audio::core::AudioPatch>*) override {
103 return ndk::ScopedAStatus::ok();
104 }
getAudioPort(int32_t,::aidl::android::media::audio::common::AudioPort *)105 ndk::ScopedAStatus getAudioPort(int32_t,
106 ::aidl::android::media::audio::common::AudioPort*) override {
107 return ndk::ScopedAStatus::ok();
108 }
getAudioPortConfigs(std::vector<::aidl::android::media::audio::common::AudioPortConfig> *)109 ndk::ScopedAStatus getAudioPortConfigs(
110 std::vector<::aidl::android::media::audio::common::AudioPortConfig>*) override {
111 return ndk::ScopedAStatus::ok();
112 }
getAudioPorts(std::vector<::aidl::android::media::audio::common::AudioPort> *)113 ndk::ScopedAStatus getAudioPorts(
114 std::vector<::aidl::android::media::audio::common::AudioPort>*) override {
115 return ndk::ScopedAStatus::ok();
116 }
getAudioRoutes(std::vector<::aidl::android::hardware::audio::core::AudioRoute> *)117 ndk::ScopedAStatus getAudioRoutes(
118 std::vector<::aidl::android::hardware::audio::core::AudioRoute>*) override {
119 return ndk::ScopedAStatus::ok();
120 }
getAudioRoutesForAudioPort(int32_t,std::vector<::aidl::android::hardware::audio::core::AudioRoute> *)121 ndk::ScopedAStatus getAudioRoutesForAudioPort(
122 int32_t, std::vector<::aidl::android::hardware::audio::core::AudioRoute>*) override {
123 return ndk::ScopedAStatus::ok();
124 }
openInputStream(const OpenInputStreamArguments &,OpenInputStreamReturn *)125 ndk::ScopedAStatus openInputStream(const OpenInputStreamArguments&,
126 OpenInputStreamReturn*) override {
127 return ndk::ScopedAStatus::ok();
128 }
openOutputStream(const OpenOutputStreamArguments &,OpenOutputStreamReturn *)129 ndk::ScopedAStatus openOutputStream(const OpenOutputStreamArguments&,
130 OpenOutputStreamReturn*) override {
131 return ndk::ScopedAStatus::ok();
132 }
getSupportedPlaybackRateFactors(SupportedPlaybackRateFactors *)133 ndk::ScopedAStatus getSupportedPlaybackRateFactors(SupportedPlaybackRateFactors*) override {
134 return ndk::ScopedAStatus::ok();
135 }
setAudioPatch(const::aidl::android::hardware::audio::core::AudioPatch &,::aidl::android::hardware::audio::core::AudioPatch *)136 ndk::ScopedAStatus setAudioPatch(const ::aidl::android::hardware::audio::core::AudioPatch&,
137 ::aidl::android::hardware::audio::core::AudioPatch*) override {
138 return ndk::ScopedAStatus::ok();
139 }
setAudioPortConfig(const::aidl::android::media::audio::common::AudioPortConfig &,::aidl::android::media::audio::common::AudioPortConfig *,bool *)140 ndk::ScopedAStatus setAudioPortConfig(
141 const ::aidl::android::media::audio::common::AudioPortConfig&,
142 ::aidl::android::media::audio::common::AudioPortConfig*, bool*) override {
143 return ndk::ScopedAStatus::ok();
144 }
resetAudioPatch(int32_t)145 ndk::ScopedAStatus resetAudioPatch(int32_t) override { return ndk::ScopedAStatus::ok(); }
resetAudioPortConfig(int32_t)146 ndk::ScopedAStatus resetAudioPortConfig(int32_t) override { return ndk::ScopedAStatus::ok(); }
getMasterMute(bool *)147 ndk::ScopedAStatus getMasterMute(bool*) override { return ndk::ScopedAStatus::ok(); }
setMasterMute(bool)148 ndk::ScopedAStatus setMasterMute(bool) override { return ndk::ScopedAStatus::ok(); }
getMasterVolume(float *)149 ndk::ScopedAStatus getMasterVolume(float*) override { return ndk::ScopedAStatus::ok(); }
setMasterVolume(float)150 ndk::ScopedAStatus setMasterVolume(float) override { return ndk::ScopedAStatus::ok(); }
getMicMute(bool *)151 ndk::ScopedAStatus getMicMute(bool*) override { return ndk::ScopedAStatus::ok(); }
setMicMute(bool)152 ndk::ScopedAStatus setMicMute(bool) override { return ndk::ScopedAStatus::ok(); }
getMicrophones(std::vector<::aidl::android::media::audio::common::MicrophoneInfo> *)153 ndk::ScopedAStatus getMicrophones(
154 std::vector<::aidl::android::media::audio::common::MicrophoneInfo>*) override {
155 return ndk::ScopedAStatus::ok();
156 }
updateAudioMode(::aidl::android::media::audio::common::AudioMode)157 ndk::ScopedAStatus updateAudioMode(::aidl::android::media::audio::common::AudioMode) override {
158 return ndk::ScopedAStatus::ok();
159 }
updateScreenRotation(ScreenRotation in_rotation)160 ndk::ScopedAStatus updateScreenRotation(ScreenRotation in_rotation) override {
161 mScreenRotation = in_rotation;
162 return ndk::ScopedAStatus::ok();
163 }
updateScreenState(bool in_isTurnedOn)164 ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override {
165 mIsScreenTurnedOn = in_isTurnedOn;
166 return ndk::ScopedAStatus::ok();
167 }
getSoundDose(std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose> *)168 ndk::ScopedAStatus getSoundDose(
169 std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>*)
170 override {
171 return ndk::ScopedAStatus::ok();
172 }
generateHwAvSyncId(int32_t *)173 ndk::ScopedAStatus generateHwAvSyncId(int32_t*) override { return ndk::ScopedAStatus::ok(); }
getVendorParameters(const std::vector<std::string> & in_parameterIds,std::vector<VendorParameter> *)174 ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
175 std::vector<VendorParameter>*) override {
176 return getVendorParametersImpl(in_parameterIds);
177 }
setVendorParameters(const std::vector<VendorParameter> & in_parameters,bool async)178 ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
179 bool async) override {
180 return setVendorParametersImpl(in_parameters, async);
181 }
addDeviceEffect(int32_t,const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> &)182 ndk::ScopedAStatus addDeviceEffect(
183 int32_t,
184 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
185 return ndk::ScopedAStatus::ok();
186 }
removeDeviceEffect(int32_t,const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> &)187 ndk::ScopedAStatus removeDeviceEffect(
188 int32_t,
189 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
190 return ndk::ScopedAStatus::ok();
191 }
getMmapPolicyInfos(::aidl::android::media::audio::common::AudioMMapPolicyType,std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo> *)192 ndk::ScopedAStatus getMmapPolicyInfos(
193 ::aidl::android::media::audio::common::AudioMMapPolicyType,
194 std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>*) override {
195 return ndk::ScopedAStatus::ok();
196 }
supportsVariableLatency(bool *)197 ndk::ScopedAStatus supportsVariableLatency(bool*) override { return ndk::ScopedAStatus::ok(); }
getAAudioMixerBurstCount(int32_t *)198 ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t*) override {
199 return ndk::ScopedAStatus::ok();
200 }
getAAudioHardwareBurstMinUsec(int32_t *)201 ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t*) override {
202 return ndk::ScopedAStatus::ok();
203 }
204
205 bool mIsScreenTurnedOn = false;
206 ScreenRotation mScreenRotation = ScreenRotation::DEG_0;
207 };
208
209 class StreamCommonMock : public ::aidl::android::hardware::audio::core::BnStreamCommon,
210 public VendorParameterMock {
close()211 ndk::ScopedAStatus close() override { return ndk::ScopedAStatus::ok(); }
prepareToClose()212 ndk::ScopedAStatus prepareToClose() override { return ndk::ScopedAStatus::ok(); }
updateHwAvSyncId(int32_t)213 ndk::ScopedAStatus updateHwAvSyncId(int32_t) override { return ndk::ScopedAStatus::ok(); }
getVendorParameters(const std::vector<std::string> & in_parameterIds,std::vector<VendorParameter> *)214 ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_parameterIds,
215 std::vector<VendorParameter>*) override {
216 return getVendorParametersImpl(in_parameterIds);
217 }
setVendorParameters(const std::vector<VendorParameter> & in_parameters,bool async)218 ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
219 bool async) override {
220 return setVendorParametersImpl(in_parameters, async);
221 }
addEffect(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> &)222 ndk::ScopedAStatus addEffect(
223 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
224 return ndk::ScopedAStatus::ok();
225 }
removeEffect(const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> &)226 ndk::ScopedAStatus removeEffect(
227 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&) override {
228 return ndk::ScopedAStatus::ok();
229 }
230 };
231
makeVendorParameter(const std::string & id,int value)232 VendorParameter makeVendorParameter(const std::string& id, int value) {
233 VendorParameter result{.id = id};
234 // Note: in real life, a parcelable type defined by vendor must be used,
235 // here we use Int just for test purposes.
236 ::aidl::android::media::audio::common::Int vendorValue{.value = value};
237 result.ext.setParcelable(std::move(vendorValue));
238 return result;
239 }
240
parseVendorParameter(const VendorParameter & param,int * value)241 android::status_t parseVendorParameter(const VendorParameter& param, int* value) {
242 std::optional<::aidl::android::media::audio::common::Int> vendorValue;
243 RETURN_STATUS_IF_ERROR(param.ext.getParcelable(&vendorValue));
244 if (!vendorValue.has_value()) return android::BAD_VALUE;
245 *value = vendorValue.value().value;
246 return android::OK;
247 }
248
249 class TestHalAdapterVendorExtension
250 : public ::aidl::android::media::audio::BnHalAdapterVendorExtension {
251 public:
252 static const std::string kLegacyParameterKey;
253 static const std::string kLegacyAsyncParameterKey;
254 static const std::string kModuleVendorParameterId;
255 static const std::string kStreamVendorParameterId;
256
257 private:
parseVendorParameterIds(ParameterScope in_scope,const std::string & in_rawKeys,std::vector<std::string> * _aidl_return)258 ndk::ScopedAStatus parseVendorParameterIds(ParameterScope in_scope,
259 const std::string& in_rawKeys,
260 std::vector<std::string>* _aidl_return) override {
261 android::AudioParameter keys(android::String8(in_rawKeys.c_str()));
262 for (size_t i = 0; i < keys.size(); ++i) {
263 android::String8 key;
264 if (android::status_t status = keys.getAt(i, key); status != android::OK) {
265 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
266 }
267 switch (in_scope) {
268 case ParameterScope::MODULE:
269 if (key == android::String8(kLegacyParameterKey.c_str()) ||
270 key == android::String8(kLegacyAsyncParameterKey.c_str())) {
271 _aidl_return->push_back(kModuleVendorParameterId);
272 } else {
273 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
274 }
275 break;
276 case ParameterScope::STREAM:
277 if (key == android::String8(kLegacyParameterKey.c_str()) ||
278 key == android::String8(kLegacyAsyncParameterKey.c_str())) {
279 _aidl_return->push_back(kStreamVendorParameterId);
280 } else {
281 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
282 }
283 break;
284 }
285 }
286 return ndk::ScopedAStatus::ok();
287 }
parseVendorParameters(ParameterScope in_scope,const std::string & in_rawKeysAndValues,std::vector<VendorParameter> * out_syncParameters,std::vector<VendorParameter> * out_asyncParameters)288 ndk::ScopedAStatus parseVendorParameters(
289 ParameterScope in_scope, const std::string& in_rawKeysAndValues,
290 std::vector<VendorParameter>* out_syncParameters,
291 std::vector<VendorParameter>* out_asyncParameters) override {
292 android::AudioParameter legacy(android::String8(in_rawKeysAndValues.c_str()));
293 for (size_t i = 0; i < legacy.size(); ++i) {
294 android::String8 key;
295 if (android::status_t status = legacy.getAt(i, key); status != android::OK) {
296 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
297 }
298 int value;
299 if (android::status_t status = legacy.getInt(key, value); status != android::OK) {
300 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
301 }
302 std::string parameterId;
303 switch (in_scope) {
304 case ParameterScope::MODULE:
305 parameterId = kModuleVendorParameterId;
306 break;
307 case ParameterScope::STREAM:
308 parameterId = kStreamVendorParameterId;
309 break;
310 }
311 if (key == android::String8(kLegacyParameterKey.c_str())) {
312 out_syncParameters->push_back(makeVendorParameter(parameterId, value));
313 } else if (key == android::String8(kLegacyAsyncParameterKey.c_str())) {
314 out_asyncParameters->push_back(makeVendorParameter(parameterId, value));
315 } else {
316 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
317 }
318 }
319 return ndk::ScopedAStatus::ok();
320 }
parseBluetoothA2dpReconfigureOffload(const std::string &,std::vector<VendorParameter> *)321 ndk::ScopedAStatus parseBluetoothA2dpReconfigureOffload(
322 const std::string&, std::vector<VendorParameter>*) override {
323 return ndk::ScopedAStatus::ok();
324 }
parseBluetoothLeReconfigureOffload(const std::string &,std::vector<VendorParameter> *)325 ndk::ScopedAStatus parseBluetoothLeReconfigureOffload(const std::string&,
326 std::vector<VendorParameter>*) override {
327 return ndk::ScopedAStatus::ok();
328 }
processVendorParameters(ParameterScope in_scope,const std::vector<VendorParameter> & in_parameters,std::string * _aidl_return)329 ndk::ScopedAStatus processVendorParameters(ParameterScope in_scope,
330 const std::vector<VendorParameter>& in_parameters,
331 std::string* _aidl_return) override {
332 android::AudioParameter legacy;
333 for (const auto& vendorParam : in_parameters) {
334 if ((in_scope == ParameterScope::MODULE &&
335 vendorParam.id == kModuleVendorParameterId) ||
336 (in_scope == ParameterScope::STREAM &&
337 vendorParam.id == kStreamVendorParameterId)) {
338 int value;
339 if (android::status_t status = parseVendorParameter(vendorParam, &value);
340 status != android::OK) {
341 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
342 }
343 legacy.addInt(android::String8(kLegacyParameterKey.c_str()), value);
344 }
345 }
346 *_aidl_return = legacy.toString().c_str();
347 return ndk::ScopedAStatus::ok();
348 }
349 };
350
351 const std::string TestHalAdapterVendorExtension::kLegacyParameterKey = "aosp_test_param";
352 const std::string TestHalAdapterVendorExtension::kLegacyAsyncParameterKey = "aosp_test_param_async";
353 // Note: in real life, there is no need to explicitly separate "module" and "stream"
354 // parameters, here it's done just for test purposes.
355 const std::string TestHalAdapterVendorExtension::kModuleVendorParameterId =
356 "aosp.test.module.parameter";
357 const std::string TestHalAdapterVendorExtension::kStreamVendorParameterId =
358 "aosp.test.stream.parameter";
359
createParameterString(const std::string & key,const std::string & value)360 android::String8 createParameterString(const std::string& key, const std::string& value) {
361 android::AudioParameter params;
362 params.add(android::String8(key.c_str()), android::String8(value.c_str()));
363 return params.toString();
364 }
365
createParameterString(const std::string & key,int value)366 android::String8 createParameterString(const std::string& key, int value) {
367 android::AudioParameter params;
368 params.addInt(android::String8(key.c_str()), value);
369 return params.toString();
370 }
371
372 template <typename>
373 struct mf_traits {};
374 template <class T, class U>
375 struct mf_traits<U T::*> {
376 using member_type = U;
377 };
378
379 } // namespace
380
381 // Provide value printers for types generated from AIDL
382 // They need to be in the same namespace as the types we intend to print
383 namespace aidl::android::hardware::audio::core {
384 template <typename P>
385 std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>,
386 std::ostream&>
operator <<(std::ostream & os,const P & p)387 operator<<(std::ostream& os, const P& p) {
388 return os << p.toString();
389 }
390 template <typename E>
operator <<(std::ostream & os,const E & e)391 std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) {
392 return os << toString(e);
393 }
394 } // namespace aidl::android::hardware::audio::core
395
396 using namespace android;
397
398 class DeviceHalAidlTest : public testing::Test {
399 public:
SetUp()400 void SetUp() override {
401 mModule = ndk::SharedRefBase::make<ModuleMock>();
402 mDevice = sp<DeviceHalAidl>::make("test", mModule, nullptr /*vext*/);
403 }
TearDown()404 void TearDown() override {
405 mDevice.clear();
406 mModule.reset();
407 }
408
409 protected:
410 std::shared_ptr<ModuleMock> mModule;
411 sp<DeviceHalAidl> mDevice;
412 };
413
TEST_F(DeviceHalAidlTest,ScreenState)414 TEST_F(DeviceHalAidlTest, ScreenState) {
415 EXPECT_FALSE(mModule->isScreenTurnedOn());
416 EXPECT_EQ(OK, mDevice->setParameters(createParameterString(AudioParameter::keyScreenState,
417 AudioParameter::valueOn)));
418 EXPECT_TRUE(mModule->isScreenTurnedOn());
419 EXPECT_EQ(OK, mDevice->setParameters(createParameterString(AudioParameter::keyScreenState,
420 AudioParameter::valueOff)));
421 EXPECT_FALSE(mModule->isScreenTurnedOn());
422 // The adaptation layer only logs a warning.
423 EXPECT_EQ(OK, mDevice->setParameters(
424 createParameterString(AudioParameter::keyScreenState, "blah")));
425 EXPECT_FALSE(mModule->isScreenTurnedOn());
426 }
427
TEST_F(DeviceHalAidlTest,ScreenRotation)428 TEST_F(DeviceHalAidlTest, ScreenRotation) {
429 using ScreenRotation = ::aidl::android::hardware::audio::core::IModule::ScreenRotation;
430 EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
431 EXPECT_EQ(OK,
432 mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 90)));
433 EXPECT_EQ(ScreenRotation::DEG_90, mModule->getScreenRotation());
434 EXPECT_EQ(OK,
435 mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 0)));
436 EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
437 // The adaptation layer only logs a warning.
438 EXPECT_EQ(OK,
439 mDevice->setParameters(createParameterString(AudioParameter::keyScreenRotation, 42)));
440 EXPECT_EQ(ScreenRotation::DEG_0, mModule->getScreenRotation());
441 }
442
443 // Without a vendor extension, any unrecognized parameters must be ignored.
TEST_F(DeviceHalAidlTest,VendorParameterIgnored)444 TEST_F(DeviceHalAidlTest, VendorParameterIgnored) {
445 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
446 EXPECT_EQ(0UL, mModule->getSyncParameters().size());
447 EXPECT_EQ(OK, mDevice->setParameters(createParameterString("random_name", "random_value")));
448 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
449 EXPECT_EQ(0UL, mModule->getSyncParameters().size());
450
451 EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
452 String8 values;
453 EXPECT_EQ(OK, mDevice->getParameters(String8("random_name"), &values));
454 EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
455 EXPECT_TRUE(values.empty());
456 }
457
458 class DeviceHalAidlVendorParametersTest : public testing::Test {
459 public:
SetUp()460 void SetUp() override {
461 mModule = ndk::SharedRefBase::make<ModuleMock>();
462 mVendorExt = ndk::SharedRefBase::make<TestHalAdapterVendorExtension>();
463 mDevice = sp<DeviceHalAidl>::make("test", mModule, mVendorExt);
464 }
TearDown()465 void TearDown() override {
466 mDevice.clear();
467 mVendorExt.reset();
468 mModule.reset();
469 }
470
471 protected:
472 std::shared_ptr<ModuleMock> mModule;
473 std::shared_ptr<TestHalAdapterVendorExtension> mVendorExt;
474 sp<DeviceHalAidl> mDevice;
475 };
476
TEST_F(DeviceHalAidlVendorParametersTest,GetVendorParameter)477 TEST_F(DeviceHalAidlVendorParametersTest, GetVendorParameter) {
478 EXPECT_EQ(0UL, mModule->getRetrievedParameterIds().size());
479 String8 values;
480 EXPECT_EQ(OK, mDevice->getParameters(
481 String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()),
482 &values));
483 EXPECT_EQ(1UL, mModule->getRetrievedParameterIds().size());
484 if (mModule->getRetrievedParameterIds().size() >= 1) {
485 EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
486 mModule->getRetrievedParameterIds()[0]);
487 }
488 }
489
TEST_F(DeviceHalAidlVendorParametersTest,SetVendorParameter)490 TEST_F(DeviceHalAidlVendorParametersTest, SetVendorParameter) {
491 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
492 EXPECT_EQ(0UL, mModule->getSyncParameters().size());
493 EXPECT_EQ(OK, mDevice->setParameters(createParameterString(
494 TestHalAdapterVendorExtension::kLegacyParameterKey, 42)));
495 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
496 EXPECT_EQ(1UL, mModule->getSyncParameters().size());
497 EXPECT_EQ(OK, mDevice->setParameters(createParameterString(
498 TestHalAdapterVendorExtension::kLegacyAsyncParameterKey, 43)));
499 EXPECT_EQ(1UL, mModule->getAsyncParameters().size());
500 EXPECT_EQ(1UL, mModule->getSyncParameters().size());
501 if (mModule->getSyncParameters().size() >= 1) {
502 EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
503 mModule->getSyncParameters()[0].id);
504 int value{};
505 EXPECT_EQ(android::OK, parseVendorParameter(mModule->getSyncParameters()[0], &value));
506 EXPECT_EQ(42, value);
507 }
508 if (mModule->getAsyncParameters().size() >= 1) {
509 EXPECT_EQ(TestHalAdapterVendorExtension::kModuleVendorParameterId,
510 mModule->getAsyncParameters()[0].id);
511 int value{};
512 EXPECT_EQ(android::OK, parseVendorParameter(mModule->getAsyncParameters()[0], &value));
513 EXPECT_EQ(43, value);
514 }
515 }
516
TEST_F(DeviceHalAidlVendorParametersTest,SetInvalidVendorParameters)517 TEST_F(DeviceHalAidlVendorParametersTest, SetInvalidVendorParameters) {
518 android::AudioParameter legacy;
519 legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()), 42);
520 legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyAsyncParameterKey.c_str()),
521 43);
522 legacy.addInt(android::String8("random_name"), 44);
523 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
524 EXPECT_EQ(0UL, mModule->getSyncParameters().size());
525 // TestHalAdapterVendorExtension throws an error for unknown parameters.
526 EXPECT_EQ(android::BAD_VALUE, mDevice->setParameters(legacy.toString()));
527 EXPECT_EQ(0UL, mModule->getAsyncParameters().size());
528 EXPECT_EQ(0UL, mModule->getSyncParameters().size());
529 }
530
531 class StreamHalAidlVendorParametersTest : public testing::Test {
532 public:
SetUp()533 void SetUp() override {
534 mStreamCommon = ndk::SharedRefBase::make<StreamCommonMock>();
535 mVendorExt = ndk::SharedRefBase::make<TestHalAdapterVendorExtension>();
536 struct audio_config config = AUDIO_CONFIG_INITIALIZER;
537 ::aidl::android::hardware::audio::core::StreamDescriptor descriptor;
538 mStream = sp<StreamHalAidl>::make("test", false /*isInput*/, config, 0 /*nominalLatency*/,
539 StreamContextAidl(descriptor, false /*isAsynchronous*/),
540 mStreamCommon, mVendorExt);
541 }
TearDown()542 void TearDown() override {
543 mStream.clear();
544 mVendorExt.reset();
545 mStreamCommon.reset();
546 }
547
548 protected:
549 std::shared_ptr<StreamCommonMock> mStreamCommon;
550 std::shared_ptr<TestHalAdapterVendorExtension> mVendorExt;
551 sp<StreamHalAidl> mStream;
552 };
553
TEST_F(StreamHalAidlVendorParametersTest,GetVendorParameter)554 TEST_F(StreamHalAidlVendorParametersTest, GetVendorParameter) {
555 EXPECT_EQ(0UL, mStreamCommon->getRetrievedParameterIds().size());
556 String8 values;
557 EXPECT_EQ(OK, mStream->getParameters(
558 String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()),
559 &values));
560 EXPECT_EQ(1UL, mStreamCommon->getRetrievedParameterIds().size());
561 if (mStreamCommon->getRetrievedParameterIds().size() >= 1) {
562 EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
563 mStreamCommon->getRetrievedParameterIds()[0]);
564 }
565 }
566
TEST_F(StreamHalAidlVendorParametersTest,SetVendorParameter)567 TEST_F(StreamHalAidlVendorParametersTest, SetVendorParameter) {
568 EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
569 EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
570 EXPECT_EQ(OK, mStream->setParameters(createParameterString(
571 TestHalAdapterVendorExtension::kLegacyParameterKey, 42)));
572 EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
573 EXPECT_EQ(1UL, mStreamCommon->getSyncParameters().size());
574 EXPECT_EQ(OK, mStream->setParameters(createParameterString(
575 TestHalAdapterVendorExtension::kLegacyAsyncParameterKey, 43)));
576 EXPECT_EQ(1UL, mStreamCommon->getAsyncParameters().size());
577 EXPECT_EQ(1UL, mStreamCommon->getSyncParameters().size());
578 if (mStreamCommon->getSyncParameters().size() >= 1) {
579 EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
580 mStreamCommon->getSyncParameters()[0].id);
581 int value{};
582 EXPECT_EQ(android::OK, parseVendorParameter(mStreamCommon->getSyncParameters()[0], &value));
583 EXPECT_EQ(42, value);
584 }
585 if (mStreamCommon->getAsyncParameters().size() >= 1) {
586 EXPECT_EQ(TestHalAdapterVendorExtension::kStreamVendorParameterId,
587 mStreamCommon->getAsyncParameters()[0].id);
588 int value{};
589 EXPECT_EQ(android::OK,
590 parseVendorParameter(mStreamCommon->getAsyncParameters()[0], &value));
591 EXPECT_EQ(43, value);
592 }
593 }
594
TEST_F(StreamHalAidlVendorParametersTest,SetInvalidVendorParameters)595 TEST_F(StreamHalAidlVendorParametersTest, SetInvalidVendorParameters) {
596 android::AudioParameter legacy;
597 legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyParameterKey.c_str()), 42);
598 legacy.addInt(android::String8(TestHalAdapterVendorExtension::kLegacyAsyncParameterKey.c_str()),
599 43);
600 legacy.addInt(android::String8("random_name"), 44);
601 EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
602 EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
603 // TestHalAdapterVendorExtension throws an error for unknown parameters.
604 EXPECT_EQ(android::BAD_VALUE, mStream->setParameters(legacy.toString()));
605 EXPECT_EQ(0UL, mStreamCommon->getAsyncParameters().size());
606 EXPECT_EQ(0UL, mStreamCommon->getSyncParameters().size());
607 }
608