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