xref: /aosp_15_r20/frameworks/av/media/libaudiohal/impl/DeviceHalAidl.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "DeviceHalAidl"
18*ec779b8eSAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <algorithm>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/core/BnStreamCallback.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/core/BnStreamOutEventCallback.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/core/StreamDescriptor.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <android/binder_ibinder_platform.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <error/expected_utils.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversionCppNdk.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversionNdk.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversionNdkCpp.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversionUtil.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <mediautils/TimeCheck.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <system/audio.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <system/thread_defs.h>
34*ec779b8eSAndroid Build Coastguard Worker 
35*ec779b8eSAndroid Build Coastguard Worker #include <Utils.h>
36*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker #include "AidlUtils.h"
39*ec779b8eSAndroid Build Coastguard Worker #include "DeviceHalAidl.h"
40*ec779b8eSAndroid Build Coastguard Worker #include "EffectHalAidl.h"
41*ec779b8eSAndroid Build Coastguard Worker #include "StreamHalAidl.h"
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker using aidl::android::aidl_utils::statusTFromBinderStatus;
44*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::Boolean;
45*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioConfig;
46*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDevice;
47*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceType;
48*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioIoFlags;
49*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioLatencyMode;
50*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioMMapPolicy;
51*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioMMapPolicyInfo;
52*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioMMapPolicyType;
53*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioMode;
54*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioOutputFlags;
55*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPort;
56*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortConfig;
57*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortExt;
58*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioSource;
59*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::Float;
60*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::Int;
61*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::MicrophoneDynamicInfo;
62*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::common::MicrophoneInfo;
63*ec779b8eSAndroid Build Coastguard Worker using aidl::android::media::audio::IHalAdapterVendorExtension;
64*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::getFrameSizeInBytes;
65*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::isBitPositionFlagSet;
66*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::kDumpFromAudioServerArgument;
67*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::RecordTrackMetadata;
68*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::PlaybackTrackMetadata;
69*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::SourceMetadata;
70*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::sounddose::ISoundDose;
71*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::AudioPatch;
72*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::AudioRoute;
73*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::IBluetooth;
74*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::IBluetoothA2dp;
75*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::IBluetoothLe;
76*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::IModule;
77*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::ITelephony;
78*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::ModuleDebug;
79*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::VendorParameter;
80*ec779b8eSAndroid Build Coastguard Worker 
81*ec779b8eSAndroid Build Coastguard Worker #define RETURN_IF_MODULE_NOT_INIT(retVal)         \
82*ec779b8eSAndroid Build Coastguard Worker     if (!isModuleInitialized()) {                 \
83*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "module not initialized"); \
84*ec779b8eSAndroid Build Coastguard Worker         return retVal;                            \
85*ec779b8eSAndroid Build Coastguard Worker     }
86*ec779b8eSAndroid Build Coastguard Worker 
87*ec779b8eSAndroid Build Coastguard Worker #define RETURN_IF_TELEPHONY_NOT_INIT(retVal)         \
88*ec779b8eSAndroid Build Coastguard Worker     if (!isTelephonyInitialized()) {                  \
89*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "telephony not initialized"); \
90*ec779b8eSAndroid Build Coastguard Worker         return retVal;                               \
91*ec779b8eSAndroid Build Coastguard Worker     }
92*ec779b8eSAndroid Build Coastguard Worker 
93*ec779b8eSAndroid Build Coastguard Worker namespace android {
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker namespace {
96*ec779b8eSAndroid Build Coastguard Worker 
97*ec779b8eSAndroid Build Coastguard Worker // Note: these converters are for types defined in different AIDL files. Although these
98*ec779b8eSAndroid Build Coastguard Worker // AIDL files are copies of each other, however formally these are different types
99*ec779b8eSAndroid Build Coastguard Worker // thus we don't use a conversion via a parcelable.
ndk2cpp_AudioRoute(const AudioRoute & ndk)100*ec779b8eSAndroid Build Coastguard Worker ConversionResult<media::AudioRoute> ndk2cpp_AudioRoute(const AudioRoute& ndk) {
101*ec779b8eSAndroid Build Coastguard Worker     media::AudioRoute cpp;
102*ec779b8eSAndroid Build Coastguard Worker     cpp.sourcePortIds.insert(
103*ec779b8eSAndroid Build Coastguard Worker             cpp.sourcePortIds.end(), ndk.sourcePortIds.begin(), ndk.sourcePortIds.end());
104*ec779b8eSAndroid Build Coastguard Worker     cpp.sinkPortId = ndk.sinkPortId;
105*ec779b8eSAndroid Build Coastguard Worker     cpp.isExclusive = ndk.isExclusive;
106*ec779b8eSAndroid Build Coastguard Worker     return cpp;
107*ec779b8eSAndroid Build Coastguard Worker }
108*ec779b8eSAndroid Build Coastguard Worker 
109*ec779b8eSAndroid Build Coastguard Worker template<typename T>
retrieveSubInterface(const std::shared_ptr<IModule> & module,::ndk::ScopedAStatus (IModule::* getT)(std::shared_ptr<T> *))110*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<T> retrieveSubInterface(const std::shared_ptr<IModule>& module,
111*ec779b8eSAndroid Build Coastguard Worker         ::ndk::ScopedAStatus (IModule::*getT)(std::shared_ptr<T>*)) {
112*ec779b8eSAndroid Build Coastguard Worker     if (module != nullptr) {
113*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<T> instance;
114*ec779b8eSAndroid Build Coastguard Worker         if (auto status = (module.get()->*getT)(&instance); status.isOk()) {
115*ec779b8eSAndroid Build Coastguard Worker             return instance;
116*ec779b8eSAndroid Build Coastguard Worker         }
117*ec779b8eSAndroid Build Coastguard Worker     }
118*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
119*ec779b8eSAndroid Build Coastguard Worker }
120*ec779b8eSAndroid Build Coastguard Worker 
121*ec779b8eSAndroid Build Coastguard Worker }  // namespace
122*ec779b8eSAndroid Build Coastguard Worker 
DeviceHalAidl(const std::string & instance,const std::shared_ptr<IModule> & module,const std::shared_ptr<IHalAdapterVendorExtension> & vext)123*ec779b8eSAndroid Build Coastguard Worker DeviceHalAidl::DeviceHalAidl(const std::string& instance, const std::shared_ptr<IModule>& module,
124*ec779b8eSAndroid Build Coastguard Worker                              const std::shared_ptr<IHalAdapterVendorExtension>& vext)
125*ec779b8eSAndroid Build Coastguard Worker     : ConversionHelperAidl("DeviceHalAidl", instance),
126*ec779b8eSAndroid Build Coastguard Worker       mModule(module),
127*ec779b8eSAndroid Build Coastguard Worker       mTelephony(retrieveSubInterface<ITelephony>(module, &IModule::getTelephony)),
128*ec779b8eSAndroid Build Coastguard Worker       mBluetooth(retrieveSubInterface<IBluetooth>(module, &IModule::getBluetooth)),
129*ec779b8eSAndroid Build Coastguard Worker       mBluetoothA2dp(retrieveSubInterface<IBluetoothA2dp>(module, &IModule::getBluetoothA2dp)),
130*ec779b8eSAndroid Build Coastguard Worker       mBluetoothLe(retrieveSubInterface<IBluetoothLe>(module, &IModule::getBluetoothLe)),
131*ec779b8eSAndroid Build Coastguard Worker       mSoundDose(retrieveSubInterface<ISoundDose>(module, &IModule::getSoundDose)),
132*ec779b8eSAndroid Build Coastguard Worker       mVendorExt(vext),
133*ec779b8eSAndroid Build Coastguard Worker       mMapper(instance, module),
134*ec779b8eSAndroid Build Coastguard Worker       mMapperAccessor(mMapper, mLock) {}
135*ec779b8eSAndroid Build Coastguard Worker 
getAudioPorts(std::vector<media::audio::common::AudioPort> * ports)136*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
137*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
138*ec779b8eSAndroid Build Coastguard Worker     return mMapper.getAudioPorts(ports, ndk2cpp_AudioPort);
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker 
getAudioRoutes(std::vector<media::AudioRoute> * routes)141*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
142*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
143*ec779b8eSAndroid Build Coastguard Worker     return mMapper.getAudioRoutes(routes, ndk2cpp_AudioRoute);
144*ec779b8eSAndroid Build Coastguard Worker }
145*ec779b8eSAndroid Build Coastguard Worker 
getSupportedModes(std::vector<media::audio::common::AudioMode> * modes)146*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) {
147*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
148*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
149*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
150*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_TELEPHONY_NOT_INIT(INVALID_OPERATION);
151*ec779b8eSAndroid Build Coastguard Worker 
152*ec779b8eSAndroid Build Coastguard Worker     if (modes == nullptr) {
153*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized modes");
154*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
155*ec779b8eSAndroid Build Coastguard Worker     }
156*ec779b8eSAndroid Build Coastguard Worker     std::vector<AudioMode> aidlModes;
157*ec779b8eSAndroid Build Coastguard Worker     {
158*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
159*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(
160*ec779b8eSAndroid Build Coastguard Worker                 statusTFromBinderStatus(mTelephony->getSupportedAudioModes(&aidlModes)));
161*ec779b8eSAndroid Build Coastguard Worker     }
162*ec779b8eSAndroid Build Coastguard Worker     *modes = VALUE_OR_RETURN_STATUS(
163*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::convertContainer<std::vector<media::audio::common::AudioMode>>(
164*ec779b8eSAndroid Build Coastguard Worker                     aidlModes, ndk2cpp_AudioMode));
165*ec779b8eSAndroid Build Coastguard Worker     return OK;
166*ec779b8eSAndroid Build Coastguard Worker }
167*ec779b8eSAndroid Build Coastguard Worker 
getSupportedDevices(uint32_t *)168*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
169*ec779b8eSAndroid Build Coastguard Worker     // Obsolete.
170*ec779b8eSAndroid Build Coastguard Worker     return INVALID_OPERATION;
171*ec779b8eSAndroid Build Coastguard Worker }
172*ec779b8eSAndroid Build Coastguard Worker 
initCheck()173*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::initCheck() {
174*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
175*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
176*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
177*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
178*ec779b8eSAndroid Build Coastguard Worker     return mMapper.initialize();
179*ec779b8eSAndroid Build Coastguard Worker }
180*ec779b8eSAndroid Build Coastguard Worker 
setVoiceVolume(float volume)181*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setVoiceVolume(float volume) {
182*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "volume %f", volume);
183*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
184*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
185*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_TELEPHONY_NOT_INIT(INVALID_OPERATION);
186*ec779b8eSAndroid Build Coastguard Worker 
187*ec779b8eSAndroid Build Coastguard Worker     ITelephony::TelecomConfig inConfig{.voiceVolume = Float{volume}}, outConfig;
188*ec779b8eSAndroid Build Coastguard Worker     {
189*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
190*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(
191*ec779b8eSAndroid Build Coastguard Worker                 statusTFromBinderStatus(mTelephony->setTelecomConfig(inConfig, &outConfig)));
192*ec779b8eSAndroid Build Coastguard Worker     }
193*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG_IF(
194*ec779b8eSAndroid Build Coastguard Worker             W, outConfig.voiceVolume.has_value() && volume != outConfig.voiceVolume.value().value,
195*ec779b8eSAndroid Build Coastguard Worker             "the resulting voice volume %f is not the same as requested %f",
196*ec779b8eSAndroid Build Coastguard Worker             outConfig.voiceVolume.value().value, volume);
197*ec779b8eSAndroid Build Coastguard Worker     return OK;
198*ec779b8eSAndroid Build Coastguard Worker }
199*ec779b8eSAndroid Build Coastguard Worker 
setMasterVolume(float volume)200*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setMasterVolume(float volume) {
201*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "volume %f", volume);
202*ec779b8eSAndroid Build Coastguard Worker 
203*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
204*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
205*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
206*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->setMasterVolume(volume));
207*ec779b8eSAndroid Build Coastguard Worker }
208*ec779b8eSAndroid Build Coastguard Worker 
getMasterVolume(float * volume)209*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getMasterVolume(float *volume) {
210*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
211*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
212*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
213*ec779b8eSAndroid Build Coastguard Worker     if (volume == nullptr) {
214*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized volumes");
215*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
216*ec779b8eSAndroid Build Coastguard Worker     }
217*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
218*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->getMasterVolume(volume));
219*ec779b8eSAndroid Build Coastguard Worker }
220*ec779b8eSAndroid Build Coastguard Worker 
setMode(audio_mode_t mode)221*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setMode(audio_mode_t mode) {
222*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "mode %d", mode);
223*ec779b8eSAndroid Build Coastguard Worker 
224*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
225*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
226*ec779b8eSAndroid Build Coastguard Worker     AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
227*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
228*ec779b8eSAndroid Build Coastguard Worker     if (mTelephony != nullptr) {
229*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mTelephony->switchAudioMode(audioMode)));
230*ec779b8eSAndroid Build Coastguard Worker     }
231*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->updateAudioMode(audioMode));
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker 
setMicMute(bool state)234*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setMicMute(bool state) {
235*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "mute %d", state);
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
238*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
239*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
240*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->setMicMute(state));
241*ec779b8eSAndroid Build Coastguard Worker }
242*ec779b8eSAndroid Build Coastguard Worker 
getMicMute(bool * state)243*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getMicMute(bool *state) {
244*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
245*ec779b8eSAndroid Build Coastguard Worker 
246*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
247*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
248*ec779b8eSAndroid Build Coastguard Worker     if (state == nullptr) {
249*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized mute state");
250*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
251*ec779b8eSAndroid Build Coastguard Worker     }
252*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
253*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->getMicMute(state));
254*ec779b8eSAndroid Build Coastguard Worker }
255*ec779b8eSAndroid Build Coastguard Worker 
setMasterMute(bool state)256*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setMasterMute(bool state) {
257*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "mute %d", state);
258*ec779b8eSAndroid Build Coastguard Worker 
259*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
260*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
261*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
262*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->setMasterMute(state));
263*ec779b8eSAndroid Build Coastguard Worker }
264*ec779b8eSAndroid Build Coastguard Worker 
getMasterMute(bool * state)265*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getMasterMute(bool *state) {
266*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
267*ec779b8eSAndroid Build Coastguard Worker 
268*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
269*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
270*ec779b8eSAndroid Build Coastguard Worker     if (state == nullptr) {
271*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized mute state");
272*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
273*ec779b8eSAndroid Build Coastguard Worker     }
274*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
275*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->getMasterMute(state));
276*ec779b8eSAndroid Build Coastguard Worker }
277*ec779b8eSAndroid Build Coastguard Worker 
setParameters(const String8 & kvPairs)278*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
279*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
280*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
281*ec779b8eSAndroid Build Coastguard Worker     AudioParameter parameters(kvPairs);
282*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "parameters: \"%s\"", parameters.toString().c_str());
283*ec779b8eSAndroid Build Coastguard Worker 
284*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateBtA2dpParameters(parameters); status != OK) {
285*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateBtA2dpParameters failed: %d", status);
286*ec779b8eSAndroid Build Coastguard Worker     }
287*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateBtHfpParameters(parameters); status != OK) {
288*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateBtHfpParameters failed: %d", status);
289*ec779b8eSAndroid Build Coastguard Worker     }
290*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateBtLeParameters(parameters); status != OK) {
291*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateBtLeParameters failed: %d", status);
292*ec779b8eSAndroid Build Coastguard Worker     }
293*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateBtScoParameters(parameters); status != OK) {
294*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateBtScoParameters failed: %d", status);
295*ec779b8eSAndroid Build Coastguard Worker     }
296*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateScreenParameters(parameters); status != OK) {
297*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateScreenParameters failed: %d", status);
298*ec779b8eSAndroid Build Coastguard Worker     }
299*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndUpdateTelephonyParameters(parameters); status != OK) {
300*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndUpdateTelephonyParameters failed: %d", status);
301*ec779b8eSAndroid Build Coastguard Worker     }
302*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
303*ec779b8eSAndroid Build Coastguard Worker     return parseAndSetVendorParameters(mVendorExt, mModule, parameters);
304*ec779b8eSAndroid Build Coastguard Worker }
305*ec779b8eSAndroid Build Coastguard Worker 
getParameters(const String8 & keys,String8 * values)306*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
307*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "keys: \"%s\"", keys.c_str());
308*ec779b8eSAndroid Build Coastguard Worker 
309*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
310*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
311*ec779b8eSAndroid Build Coastguard Worker     if (values == nullptr) {
312*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid values");
313*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
314*ec779b8eSAndroid Build Coastguard Worker     }
315*ec779b8eSAndroid Build Coastguard Worker     AudioParameter parameterKeys(keys), result;
316*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndRetrieveBtA2dpParameters(parameterKeys, &result); status != OK) {
317*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndRetrieveBtA2dpParameters failed: %d", status);
318*ec779b8eSAndroid Build Coastguard Worker     }
319*ec779b8eSAndroid Build Coastguard Worker     if (status_t status = filterAndRetrieveBtLeParameters(parameterKeys, &result); status != OK) {
320*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "filterAndRetrieveBtLeParameters failed: %d", status);
321*ec779b8eSAndroid Build Coastguard Worker     }
322*ec779b8eSAndroid Build Coastguard Worker     *values = result.toString();
323*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
324*ec779b8eSAndroid Build Coastguard Worker     return parseAndGetVendorParameters(mVendorExt, mModule, parameterKeys, values);
325*ec779b8eSAndroid Build Coastguard Worker }
326*ec779b8eSAndroid Build Coastguard Worker 
getInputBufferSize(struct audio_config * config,size_t * size)327*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getInputBufferSize(struct audio_config* config, size_t* size) {
328*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
329*ec779b8eSAndroid Build Coastguard Worker 
330*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
331*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
332*ec779b8eSAndroid Build Coastguard Worker     if (config == nullptr || size == nullptr) {
333*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid config or size");
334*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
335*ec779b8eSAndroid Build Coastguard Worker     }
336*ec779b8eSAndroid Build Coastguard Worker     constexpr bool isInput = true;
337*ec779b8eSAndroid Build Coastguard Worker     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
338*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
339*ec779b8eSAndroid Build Coastguard Worker     AudioDevice aidlDevice;
340*ec779b8eSAndroid Build Coastguard Worker     aidlDevice.type.type = AudioDeviceType::IN_DEFAULT;
341*ec779b8eSAndroid Build Coastguard Worker     AudioSource aidlSource = AudioSource::DEFAULT;
342*ec779b8eSAndroid Build Coastguard Worker     AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::input>(0);
343*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig mixPortConfig;
344*ec779b8eSAndroid Build Coastguard Worker     Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
345*ec779b8eSAndroid Build Coastguard Worker     AudioPatch aidlPatch;
346*ec779b8eSAndroid Build Coastguard Worker     {
347*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
348*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(
349*ec779b8eSAndroid Build Coastguard Worker                         0 /*handle*/, aidlDevice, aidlFlags, aidlSource,
350*ec779b8eSAndroid Build Coastguard Worker                         &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
351*ec779b8eSAndroid Build Coastguard Worker     }
352*ec779b8eSAndroid Build Coastguard Worker     *config = VALUE_OR_RETURN_STATUS(
353*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
354*ec779b8eSAndroid Build Coastguard Worker     if (mixPortConfig.id == 0) return BAD_VALUE;  // HAL suggests a different config.
355*ec779b8eSAndroid Build Coastguard Worker     *size = aidlConfig.frameCount *
356*ec779b8eSAndroid Build Coastguard Worker             getFrameSizeInBytes(aidlConfig.base.format, aidlConfig.base.channelMask);
357*ec779b8eSAndroid Build Coastguard Worker     // Do not disarm cleanups to release temporary port configs.
358*ec779b8eSAndroid Build Coastguard Worker     return OK;
359*ec779b8eSAndroid Build Coastguard Worker }
360*ec779b8eSAndroid Build Coastguard Worker 
361*ec779b8eSAndroid Build Coastguard Worker namespace {
362*ec779b8eSAndroid Build Coastguard Worker 
363*ec779b8eSAndroid Build Coastguard Worker class StreamCallbackBase {
364*ec779b8eSAndroid Build Coastguard Worker   protected:
StreamCallbackBase(const sp<CallbackBroker> & broker)365*ec779b8eSAndroid Build Coastguard Worker     explicit StreamCallbackBase(const sp<CallbackBroker>& broker) : mBroker(broker) {}
366*ec779b8eSAndroid Build Coastguard Worker   public:
getCookie() const367*ec779b8eSAndroid Build Coastguard Worker     void* getCookie() const { return mCookie; }
setCookie(void * cookie)368*ec779b8eSAndroid Build Coastguard Worker     void setCookie(void* cookie) { mCookie = cookie; }
getBroker() const369*ec779b8eSAndroid Build Coastguard Worker     sp<CallbackBroker> getBroker() const {
370*ec779b8eSAndroid Build Coastguard Worker         if (void* cookie = mCookie; cookie != nullptr) return mBroker.promote();
371*ec779b8eSAndroid Build Coastguard Worker         return nullptr;
372*ec779b8eSAndroid Build Coastguard Worker     }
373*ec779b8eSAndroid Build Coastguard Worker   private:
374*ec779b8eSAndroid Build Coastguard Worker     const wp<CallbackBroker> mBroker;
375*ec779b8eSAndroid Build Coastguard Worker     std::atomic<void*> mCookie;
376*ec779b8eSAndroid Build Coastguard Worker };
377*ec779b8eSAndroid Build Coastguard Worker 
378*ec779b8eSAndroid Build Coastguard Worker template<class C>
379*ec779b8eSAndroid Build Coastguard Worker class StreamCallbackBaseHelper {
380*ec779b8eSAndroid Build Coastguard Worker   protected:
StreamCallbackBaseHelper(const StreamCallbackBase & base)381*ec779b8eSAndroid Build Coastguard Worker     explicit StreamCallbackBaseHelper(const StreamCallbackBase& base) : mBase(base) {}
382*ec779b8eSAndroid Build Coastguard Worker     sp<C> getCb(const sp<CallbackBroker>& broker, void* cookie);
383*ec779b8eSAndroid Build Coastguard Worker     using CbRef = const sp<C>&;
runCb(const std::function<void (CbRef cb)> & f)384*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus runCb(const std::function<void(CbRef cb)>& f) {
385*ec779b8eSAndroid Build Coastguard Worker         if (auto cb = getCb(mBase.getBroker(), mBase.getCookie()); cb != nullptr) f(cb);
386*ec779b8eSAndroid Build Coastguard Worker         return ndk::ScopedAStatus::ok();
387*ec779b8eSAndroid Build Coastguard Worker     }
388*ec779b8eSAndroid Build Coastguard Worker   private:
389*ec779b8eSAndroid Build Coastguard Worker     const StreamCallbackBase& mBase;
390*ec779b8eSAndroid Build Coastguard Worker };
391*ec779b8eSAndroid Build Coastguard Worker 
392*ec779b8eSAndroid Build Coastguard Worker template<>
getCb(const sp<CallbackBroker> & broker,void * cookie)393*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceCallback> StreamCallbackBaseHelper<StreamOutHalInterfaceCallback>::getCb(
394*ec779b8eSAndroid Build Coastguard Worker         const sp<CallbackBroker>& broker, void* cookie) {
395*ec779b8eSAndroid Build Coastguard Worker     if (broker != nullptr) return broker->getStreamOutCallback(cookie);
396*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
397*ec779b8eSAndroid Build Coastguard Worker }
398*ec779b8eSAndroid Build Coastguard Worker 
399*ec779b8eSAndroid Build Coastguard Worker template<>
400*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceEventCallback>
getCb(const sp<CallbackBroker> & broker,void * cookie)401*ec779b8eSAndroid Build Coastguard Worker StreamCallbackBaseHelper<StreamOutHalInterfaceEventCallback>::getCb(
402*ec779b8eSAndroid Build Coastguard Worker         const sp<CallbackBroker>& broker, void* cookie) {
403*ec779b8eSAndroid Build Coastguard Worker     if (broker != nullptr) return broker->getStreamOutEventCallback(cookie);
404*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
405*ec779b8eSAndroid Build Coastguard Worker }
406*ec779b8eSAndroid Build Coastguard Worker 
407*ec779b8eSAndroid Build Coastguard Worker template<>
408*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceLatencyModeCallback>
getCb(const sp<CallbackBroker> & broker,void * cookie)409*ec779b8eSAndroid Build Coastguard Worker StreamCallbackBaseHelper<StreamOutHalInterfaceLatencyModeCallback>::getCb(
410*ec779b8eSAndroid Build Coastguard Worker         const sp<CallbackBroker>& broker, void* cookie) {
411*ec779b8eSAndroid Build Coastguard Worker     if (broker != nullptr) return broker->getStreamOutLatencyModeCallback(cookie);
412*ec779b8eSAndroid Build Coastguard Worker     return nullptr;
413*ec779b8eSAndroid Build Coastguard Worker }
414*ec779b8eSAndroid Build Coastguard Worker 
415*ec779b8eSAndroid Build Coastguard Worker /*
416*ec779b8eSAndroid Build Coastguard Worker Note on the callback ownership.
417*ec779b8eSAndroid Build Coastguard Worker 
418*ec779b8eSAndroid Build Coastguard Worker In the Binder ownership model, the server implementation is kept alive
419*ec779b8eSAndroid Build Coastguard Worker as long as there is any client (proxy object) alive. This is done by
420*ec779b8eSAndroid Build Coastguard Worker incrementing the refcount of the server-side object by the Binder framework.
421*ec779b8eSAndroid Build Coastguard Worker When it detects that the last client is gone, it decrements the refcount back.
422*ec779b8eSAndroid Build Coastguard Worker 
423*ec779b8eSAndroid Build Coastguard Worker Thus, it is not needed to keep any references to StreamCallback on our
424*ec779b8eSAndroid Build Coastguard Worker side (after we have sent an instance to the client), because we are
425*ec779b8eSAndroid Build Coastguard Worker the server-side. The callback object will be kept alive as long as the HAL server
426*ec779b8eSAndroid Build Coastguard Worker holds a strong ref to IStreamCallback proxy.
427*ec779b8eSAndroid Build Coastguard Worker */
428*ec779b8eSAndroid Build Coastguard Worker 
429*ec779b8eSAndroid Build Coastguard Worker class OutputStreamCallbackAidl : public StreamCallbackBase,
430*ec779b8eSAndroid Build Coastguard Worker                              public StreamCallbackBaseHelper<StreamOutHalInterfaceCallback>,
431*ec779b8eSAndroid Build Coastguard Worker                              public ::aidl::android::hardware::audio::core::BnStreamCallback {
432*ec779b8eSAndroid Build Coastguard Worker   public:
OutputStreamCallbackAidl(const sp<CallbackBroker> & broker)433*ec779b8eSAndroid Build Coastguard Worker     explicit OutputStreamCallbackAidl(const sp<CallbackBroker>& broker)
434*ec779b8eSAndroid Build Coastguard Worker             : StreamCallbackBase(broker),
435*ec779b8eSAndroid Build Coastguard Worker               StreamCallbackBaseHelper<StreamOutHalInterfaceCallback>(
436*ec779b8eSAndroid Build Coastguard Worker                       *static_cast<StreamCallbackBase*>(this)) {}
onTransferReady()437*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus onTransferReady() override {
438*ec779b8eSAndroid Build Coastguard Worker         return runCb([](CbRef cb) { cb->onWriteReady(); });
439*ec779b8eSAndroid Build Coastguard Worker     }
onError()440*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus onError() override {
441*ec779b8eSAndroid Build Coastguard Worker         return runCb([](CbRef cb) { cb->onError(true /*isHardError*/); });
442*ec779b8eSAndroid Build Coastguard Worker     }
onDrainReady()443*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus onDrainReady() override {
444*ec779b8eSAndroid Build Coastguard Worker         return runCb([](CbRef cb) { cb->onDrainReady(); });
445*ec779b8eSAndroid Build Coastguard Worker     }
446*ec779b8eSAndroid Build Coastguard Worker };
447*ec779b8eSAndroid Build Coastguard Worker 
448*ec779b8eSAndroid Build Coastguard Worker class OutputStreamEventCallbackAidl :
449*ec779b8eSAndroid Build Coastguard Worker             public StreamCallbackBase,
450*ec779b8eSAndroid Build Coastguard Worker             public StreamCallbackBaseHelper<StreamOutHalInterfaceEventCallback>,
451*ec779b8eSAndroid Build Coastguard Worker             public StreamCallbackBaseHelper<StreamOutHalInterfaceLatencyModeCallback>,
452*ec779b8eSAndroid Build Coastguard Worker             public ::aidl::android::hardware::audio::core::BnStreamOutEventCallback {
453*ec779b8eSAndroid Build Coastguard Worker   public:
OutputStreamEventCallbackAidl(const sp<CallbackBroker> & broker)454*ec779b8eSAndroid Build Coastguard Worker     explicit OutputStreamEventCallbackAidl(const sp<CallbackBroker>& broker)
455*ec779b8eSAndroid Build Coastguard Worker             : StreamCallbackBase(broker),
456*ec779b8eSAndroid Build Coastguard Worker               StreamCallbackBaseHelper<StreamOutHalInterfaceEventCallback>(
457*ec779b8eSAndroid Build Coastguard Worker                       *static_cast<StreamCallbackBase*>(this)),
458*ec779b8eSAndroid Build Coastguard Worker               StreamCallbackBaseHelper<StreamOutHalInterfaceLatencyModeCallback>(
459*ec779b8eSAndroid Build Coastguard Worker                       *static_cast<StreamCallbackBase*>(this)) {}
onCodecFormatChanged(const std::vector<uint8_t> & halMetadata)460*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus onCodecFormatChanged(const std::vector<uint8_t>& halMetadata) override {
461*ec779b8eSAndroid Build Coastguard Worker         return StreamCallbackBaseHelper<StreamOutHalInterfaceEventCallback>::runCb(
462*ec779b8eSAndroid Build Coastguard Worker                 [&halMetadata](auto cb) { cb->onCodecFormatChanged(halMetadata); });
463*ec779b8eSAndroid Build Coastguard Worker     }
onRecommendedLatencyModeChanged(const std::vector<AudioLatencyMode> & in_modes)464*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus onRecommendedLatencyModeChanged(
465*ec779b8eSAndroid Build Coastguard Worker             const std::vector<AudioLatencyMode>& in_modes) override {
466*ec779b8eSAndroid Build Coastguard Worker         auto halModes = VALUE_OR_FATAL(
467*ec779b8eSAndroid Build Coastguard Worker                 ::aidl::android::convertContainer<std::vector<audio_latency_mode_t>>(
468*ec779b8eSAndroid Build Coastguard Worker                         in_modes,
469*ec779b8eSAndroid Build Coastguard Worker                         ::aidl::android::aidl2legacy_AudioLatencyMode_audio_latency_mode_t));
470*ec779b8eSAndroid Build Coastguard Worker         return StreamCallbackBaseHelper<StreamOutHalInterfaceLatencyModeCallback>::runCb(
471*ec779b8eSAndroid Build Coastguard Worker                 [&halModes](auto cb) { cb->onRecommendedLatencyModeChanged(halModes); });
472*ec779b8eSAndroid Build Coastguard Worker     }
473*ec779b8eSAndroid Build Coastguard Worker };
474*ec779b8eSAndroid Build Coastguard Worker 
475*ec779b8eSAndroid Build Coastguard Worker }  // namespace
476*ec779b8eSAndroid Build Coastguard Worker 
openOutputStream(audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,const char * address,sp<StreamOutHalInterface> * outStream,const std::vector<playback_track_metadata_v7_t> & sourceMetadata)477*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::openOutputStream(
478*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t handle, audio_devices_t devices,
479*ec779b8eSAndroid Build Coastguard Worker         audio_output_flags_t flags, struct audio_config* config,
480*ec779b8eSAndroid Build Coastguard Worker         const char* address,
481*ec779b8eSAndroid Build Coastguard Worker         sp<StreamOutHalInterface>* outStream,
482*ec779b8eSAndroid Build Coastguard Worker         const std::vector<playback_track_metadata_v7_t>& sourceMetadata) {
483*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "handle: %d devices %0x flags %0x", handle, devices, flags);
484*ec779b8eSAndroid Build Coastguard Worker 
485*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
486*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
487*ec779b8eSAndroid Build Coastguard Worker     if (outStream == nullptr || config == nullptr) {
488*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid outStream or config");
489*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
490*ec779b8eSAndroid Build Coastguard Worker     }
491*ec779b8eSAndroid Build Coastguard Worker     constexpr bool isInput = false;
492*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
493*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
494*ec779b8eSAndroid Build Coastguard Worker     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
495*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
496*ec779b8eSAndroid Build Coastguard Worker     AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
497*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
498*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlOutputFlags = VALUE_OR_RETURN_STATUS(
499*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
500*ec779b8eSAndroid Build Coastguard Worker     SourceMetadata aidlMetadata = VALUE_OR_RETURN_STATUS(
501*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_playback_track_metadata_v7_SourceMetadata(sourceMetadata));
502*ec779b8eSAndroid Build Coastguard Worker     AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::output>(aidlOutputFlags);
503*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig mixPortConfig;
504*ec779b8eSAndroid Build Coastguard Worker     AudioPatch aidlPatch;
505*ec779b8eSAndroid Build Coastguard Worker 
506*ec779b8eSAndroid Build Coastguard Worker     Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
507*ec779b8eSAndroid Build Coastguard Worker     {
508*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
509*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags,
510*ec779b8eSAndroid Build Coastguard Worker                         AudioSource::SYS_RESERVED_INVALID /*only needed for input*/,
511*ec779b8eSAndroid Build Coastguard Worker                         &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
512*ec779b8eSAndroid Build Coastguard Worker     }
513*ec779b8eSAndroid Build Coastguard Worker     *config = VALUE_OR_RETURN_STATUS(
514*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
515*ec779b8eSAndroid Build Coastguard Worker     if (mixPortConfig.id == 0) return BAD_VALUE;  // HAL suggests a different config.
516*ec779b8eSAndroid Build Coastguard Worker     ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
517*ec779b8eSAndroid Build Coastguard Worker     args.portConfigId = mixPortConfig.id;
518*ec779b8eSAndroid Build Coastguard Worker     const bool isOffload = isBitPositionFlagSet(
519*ec779b8eSAndroid Build Coastguard Worker             aidlOutputFlags, AudioOutputFlags::COMPRESS_OFFLOAD);
520*ec779b8eSAndroid Build Coastguard Worker     const bool isHwAvSync = isBitPositionFlagSet(
521*ec779b8eSAndroid Build Coastguard Worker             aidlOutputFlags, AudioOutputFlags::HW_AV_SYNC);
522*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<OutputStreamCallbackAidl> streamCb;
523*ec779b8eSAndroid Build Coastguard Worker     if (isOffload) {
524*ec779b8eSAndroid Build Coastguard Worker         streamCb = ndk::SharedRefBase::make<OutputStreamCallbackAidl>(this);
525*ec779b8eSAndroid Build Coastguard Worker         ndk::SpAIBinder binder = streamCb->asBinder();
526*ec779b8eSAndroid Build Coastguard Worker         AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
527*ec779b8eSAndroid Build Coastguard Worker         AIBinder_setInheritRt(binder.get(), true);
528*ec779b8eSAndroid Build Coastguard Worker     }
529*ec779b8eSAndroid Build Coastguard Worker     auto eventCb = ndk::SharedRefBase::make<OutputStreamEventCallbackAidl>(this);
530*ec779b8eSAndroid Build Coastguard Worker     ndk::SpAIBinder binder = eventCb->asBinder();
531*ec779b8eSAndroid Build Coastguard Worker     AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
532*ec779b8eSAndroid Build Coastguard Worker     AIBinder_setInheritRt(binder.get(), true);
533*ec779b8eSAndroid Build Coastguard Worker 
534*ec779b8eSAndroid Build Coastguard Worker     if (isOffload || isHwAvSync) {
535*ec779b8eSAndroid Build Coastguard Worker         args.offloadInfo = aidlConfig.offloadInfo;
536*ec779b8eSAndroid Build Coastguard Worker     }
537*ec779b8eSAndroid Build Coastguard Worker     if (isOffload) {
538*ec779b8eSAndroid Build Coastguard Worker         args.callback = streamCb;
539*ec779b8eSAndroid Build Coastguard Worker     }
540*ec779b8eSAndroid Build Coastguard Worker     args.bufferSizeFrames = aidlConfig.frameCount;
541*ec779b8eSAndroid Build Coastguard Worker     args.eventCallback = eventCb;
542*ec779b8eSAndroid Build Coastguard Worker     args.sourceMetadata = aidlMetadata;
543*ec779b8eSAndroid Build Coastguard Worker     ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
544*ec779b8eSAndroid Build Coastguard Worker     {
545*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
546*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openOutputStream(args, &ret)));
547*ec779b8eSAndroid Build Coastguard Worker     }
548*ec779b8eSAndroid Build Coastguard Worker     StreamContextAidl context(ret.desc, isOffload, aidlHandle);
549*ec779b8eSAndroid Build Coastguard Worker     if (!context.isValid()) {
550*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "Failed to created a valid stream context from the descriptor: %s",
551*ec779b8eSAndroid Build Coastguard Worker                     ret.desc.toString().c_str());
552*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
553*ec779b8eSAndroid Build Coastguard Worker     }
554*ec779b8eSAndroid Build Coastguard Worker     auto stream = sp<StreamOutHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
555*ec779b8eSAndroid Build Coastguard Worker             std::move(ret.stream), mVendorExt, this /*callbackBroker*/);
556*ec779b8eSAndroid Build Coastguard Worker     *outStream = stream;
557*ec779b8eSAndroid Build Coastguard Worker     /* StreamOutHalInterface* */ void* cbCookie = (*outStream).get();
558*ec779b8eSAndroid Build Coastguard Worker     {
559*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mCallbacksLock);
560*ec779b8eSAndroid Build Coastguard Worker         mCallbacks.emplace(cbCookie, Callbacks{});
561*ec779b8eSAndroid Build Coastguard Worker     }
562*ec779b8eSAndroid Build Coastguard Worker     {
563*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
564*ec779b8eSAndroid Build Coastguard Worker         mMapper.addStream(*outStream, mixPortConfig.id, aidlPatch.id);
565*ec779b8eSAndroid Build Coastguard Worker     }
566*ec779b8eSAndroid Build Coastguard Worker     if (streamCb) {
567*ec779b8eSAndroid Build Coastguard Worker         streamCb->setCookie(cbCookie);
568*ec779b8eSAndroid Build Coastguard Worker         // Although StreamOutHalAidl implements StreamOutHalInterfaceCallback,
569*ec779b8eSAndroid Build Coastguard Worker         // we always go via the CallbackBroker for consistency.
570*ec779b8eSAndroid Build Coastguard Worker         setStreamOutCallback(cbCookie, stream);
571*ec779b8eSAndroid Build Coastguard Worker     }
572*ec779b8eSAndroid Build Coastguard Worker     eventCb->setCookie(cbCookie);
573*ec779b8eSAndroid Build Coastguard Worker     cleanups.disarmAll();
574*ec779b8eSAndroid Build Coastguard Worker     return OK;
575*ec779b8eSAndroid Build Coastguard Worker }
576*ec779b8eSAndroid Build Coastguard Worker 
openInputStream(audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,audio_input_flags_t flags,const char * address,audio_source_t source,audio_devices_t outputDevice,const char * outputDeviceAddress,sp<StreamInHalInterface> * inStream)577*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::openInputStream(
578*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t handle, audio_devices_t devices,
579*ec779b8eSAndroid Build Coastguard Worker         struct audio_config* config, audio_input_flags_t flags,
580*ec779b8eSAndroid Build Coastguard Worker         const char* address, audio_source_t source,
581*ec779b8eSAndroid Build Coastguard Worker         audio_devices_t outputDevice, const char* outputDeviceAddress,
582*ec779b8eSAndroid Build Coastguard Worker         sp<StreamInHalInterface>* inStream) {
583*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "handle: %d devices %0x flags %0x", handle, devices, flags);
584*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
585*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
586*ec779b8eSAndroid Build Coastguard Worker     if (inStream == nullptr || config == nullptr) {
587*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid inStream or config");
588*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
589*ec779b8eSAndroid Build Coastguard Worker     }
590*ec779b8eSAndroid Build Coastguard Worker     constexpr bool isInput = true;
591*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
592*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
593*ec779b8eSAndroid Build Coastguard Worker     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
594*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
595*ec779b8eSAndroid Build Coastguard Worker     AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
596*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
597*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlInputFlags = VALUE_OR_RETURN_STATUS(
598*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
599*ec779b8eSAndroid Build Coastguard Worker     AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::input>(aidlInputFlags);
600*ec779b8eSAndroid Build Coastguard Worker     AudioSource aidlSource = VALUE_OR_RETURN_STATUS(
601*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_source_t_AudioSource(source));
602*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig mixPortConfig;
603*ec779b8eSAndroid Build Coastguard Worker     AudioPatch aidlPatch;
604*ec779b8eSAndroid Build Coastguard Worker     Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
605*ec779b8eSAndroid Build Coastguard Worker     {
606*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
607*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(
608*ec779b8eSAndroid Build Coastguard Worker                         aidlHandle, aidlDevice, aidlFlags, aidlSource,
609*ec779b8eSAndroid Build Coastguard Worker                         &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
610*ec779b8eSAndroid Build Coastguard Worker     }
611*ec779b8eSAndroid Build Coastguard Worker     *config = VALUE_OR_RETURN_STATUS(
612*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
613*ec779b8eSAndroid Build Coastguard Worker     if (mixPortConfig.id == 0) return BAD_VALUE;  // HAL suggests a different config.
614*ec779b8eSAndroid Build Coastguard Worker     ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
615*ec779b8eSAndroid Build Coastguard Worker     args.portConfigId = mixPortConfig.id;
616*ec779b8eSAndroid Build Coastguard Worker     RecordTrackMetadata aidlTrackMetadata{
617*ec779b8eSAndroid Build Coastguard Worker         .source = aidlSource, .gain = 1, .channelMask = aidlConfig.base.channelMask };
618*ec779b8eSAndroid Build Coastguard Worker     if (outputDevice != AUDIO_DEVICE_NONE) {
619*ec779b8eSAndroid Build Coastguard Worker         aidlTrackMetadata.destinationDevice = VALUE_OR_RETURN_STATUS(
620*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_device_AudioDevice(
621*ec779b8eSAndroid Build Coastguard Worker                     outputDevice, outputDeviceAddress));
622*ec779b8eSAndroid Build Coastguard Worker     }
623*ec779b8eSAndroid Build Coastguard Worker     args.sinkMetadata.tracks.push_back(std::move(aidlTrackMetadata));
624*ec779b8eSAndroid Build Coastguard Worker     args.bufferSizeFrames = aidlConfig.frameCount;
625*ec779b8eSAndroid Build Coastguard Worker     ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
626*ec779b8eSAndroid Build Coastguard Worker     {
627*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
628*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->openInputStream(args, &ret)));
629*ec779b8eSAndroid Build Coastguard Worker     }
630*ec779b8eSAndroid Build Coastguard Worker     StreamContextAidl context(ret.desc, false /*isAsynchronous*/, aidlHandle);
631*ec779b8eSAndroid Build Coastguard Worker     if (!context.isValid()) {
632*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "Failed to created a valid stream context from the descriptor: %s",
633*ec779b8eSAndroid Build Coastguard Worker                     ret.desc.toString().c_str());
634*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
635*ec779b8eSAndroid Build Coastguard Worker     }
636*ec779b8eSAndroid Build Coastguard Worker     *inStream = sp<StreamInHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
637*ec779b8eSAndroid Build Coastguard Worker             std::move(ret.stream), mVendorExt, this /*micInfoProvider*/);
638*ec779b8eSAndroid Build Coastguard Worker     {
639*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
640*ec779b8eSAndroid Build Coastguard Worker         mMapper.addStream(*inStream, mixPortConfig.id, aidlPatch.id);
641*ec779b8eSAndroid Build Coastguard Worker     }
642*ec779b8eSAndroid Build Coastguard Worker     cleanups.disarmAll();
643*ec779b8eSAndroid Build Coastguard Worker     return OK;
644*ec779b8eSAndroid Build Coastguard Worker }
645*ec779b8eSAndroid Build Coastguard Worker 
supportsAudioPatches(bool * supportsPatches)646*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::supportsAudioPatches(bool* supportsPatches) {
647*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
648*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
649*ec779b8eSAndroid Build Coastguard Worker     if (supportsPatches == nullptr) {
650*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized supportsPatches");
651*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
652*ec779b8eSAndroid Build Coastguard Worker     }
653*ec779b8eSAndroid Build Coastguard Worker     *supportsPatches = true;
654*ec779b8eSAndroid Build Coastguard Worker     return OK;
655*ec779b8eSAndroid Build Coastguard Worker }
656*ec779b8eSAndroid Build Coastguard Worker 
createAudioPatch(unsigned int num_sources,const struct audio_port_config * sources,unsigned int num_sinks,const struct audio_port_config * sinks,audio_patch_handle_t * patch)657*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
658*ec779b8eSAndroid Build Coastguard Worker                                          const struct audio_port_config* sources,
659*ec779b8eSAndroid Build Coastguard Worker                                          unsigned int num_sinks,
660*ec779b8eSAndroid Build Coastguard Worker                                          const struct audio_port_config* sinks,
661*ec779b8eSAndroid Build Coastguard Worker                                          audio_patch_handle_t* patch) {
662*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "sources: %d sinks %d", num_sources, num_sinks);
663*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
664*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
665*ec779b8eSAndroid Build Coastguard Worker     if (num_sinks > AUDIO_PATCH_PORTS_MAX || num_sources > AUDIO_PATCH_PORTS_MAX) {
666*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid sources %d or sinks %d ", num_sources, num_sinks);
667*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
668*ec779b8eSAndroid Build Coastguard Worker     }
669*ec779b8eSAndroid Build Coastguard Worker 
670*ec779b8eSAndroid Build Coastguard Worker     if (sources == nullptr || sinks == nullptr || patch == nullptr) {
671*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "uninitialized sources %d or sinks %d or patches %d", (sources == nullptr),
672*ec779b8eSAndroid Build Coastguard Worker                     (sinks == nullptr), (patch == nullptr));
673*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
674*ec779b8eSAndroid Build Coastguard Worker     }
675*ec779b8eSAndroid Build Coastguard Worker 
676*ec779b8eSAndroid Build Coastguard Worker     // When the patch handle (*patch) is AUDIO_PATCH_HANDLE_NONE, it means
677*ec779b8eSAndroid Build Coastguard Worker     // the framework wants to create a new patch. The handle has to be generated
678*ec779b8eSAndroid Build Coastguard Worker     // by the HAL. Since handles generated this way can only be unique within
679*ec779b8eSAndroid Build Coastguard Worker     // a HAL module, the framework generates a globally unique handle, and maps
680*ec779b8eSAndroid Build Coastguard Worker     // it on the <HAL module, patch handle> pair.
681*ec779b8eSAndroid Build Coastguard Worker     // When the patch handle is set, it meant the framework intends to update
682*ec779b8eSAndroid Build Coastguard Worker     // an existing patch.
683*ec779b8eSAndroid Build Coastguard Worker     //
684*ec779b8eSAndroid Build Coastguard Worker     // This behavior corresponds to HAL module behavior, with the only difference
685*ec779b8eSAndroid Build Coastguard Worker     // that the HAL module uses `int32_t` for patch IDs. The following assert ensures
686*ec779b8eSAndroid Build Coastguard Worker     // that both the framework and the HAL use the same value for "no ID":
687*ec779b8eSAndroid Build Coastguard Worker     static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
688*ec779b8eSAndroid Build Coastguard Worker 
689*ec779b8eSAndroid Build Coastguard Worker     // Upon conversion, mix port configs contain audio configuration, while
690*ec779b8eSAndroid Build Coastguard Worker     // device port configs contain device address. This data is used to find
691*ec779b8eSAndroid Build Coastguard Worker     // or create HAL configs.
692*ec779b8eSAndroid Build Coastguard Worker     std::vector<AudioPortConfig> aidlSources, aidlSinks;
693*ec779b8eSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < num_sources; ++i) {
694*ec779b8eSAndroid Build Coastguard Worker         bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
695*ec779b8eSAndroid Build Coastguard Worker                         sources[i].role, sources[i].type)) ==
696*ec779b8eSAndroid Build Coastguard Worker                 ::aidl::android::AudioPortDirection::INPUT;
697*ec779b8eSAndroid Build Coastguard Worker         aidlSources.push_back(VALUE_OR_RETURN_STATUS(
698*ec779b8eSAndroid Build Coastguard Worker                         ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
699*ec779b8eSAndroid Build Coastguard Worker                                 sources[i], isInput, 0)));
700*ec779b8eSAndroid Build Coastguard Worker     }
701*ec779b8eSAndroid Build Coastguard Worker     for (unsigned int i = 0; i < num_sinks; ++i) {
702*ec779b8eSAndroid Build Coastguard Worker         bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
703*ec779b8eSAndroid Build Coastguard Worker                         sinks[i].role, sinks[i].type)) ==
704*ec779b8eSAndroid Build Coastguard Worker                 ::aidl::android::AudioPortDirection::INPUT;
705*ec779b8eSAndroid Build Coastguard Worker         aidlSinks.push_back(VALUE_OR_RETURN_STATUS(
706*ec779b8eSAndroid Build Coastguard Worker                         ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
707*ec779b8eSAndroid Build Coastguard Worker                                 sinks[i], isInput, 0)));
708*ec779b8eSAndroid Build Coastguard Worker     }
709*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlPatchId = static_cast<int32_t>(*patch);
710*ec779b8eSAndroid Build Coastguard Worker     Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
711*ec779b8eSAndroid Build Coastguard Worker     {
712*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
713*ec779b8eSAndroid Build Coastguard Worker         // Check for patches that only exist for the framework, or have different HAL patch ID.
714*ec779b8eSAndroid Build Coastguard Worker         if (int32_t aidlHalPatchId = mMapper.findFwkPatch(aidlPatchId); aidlHalPatchId != 0) {
715*ec779b8eSAndroid Build Coastguard Worker             if (aidlHalPatchId == aidlPatchId) {
716*ec779b8eSAndroid Build Coastguard Worker                 // This patch was previously released by the HAL. Thus we need to pass '0'
717*ec779b8eSAndroid Build Coastguard Worker                 // to the HAL to obtain a new patch.
718*ec779b8eSAndroid Build Coastguard Worker                 int32_t newAidlPatchId = 0;
719*ec779b8eSAndroid Build Coastguard Worker                 RETURN_STATUS_IF_ERROR(mMapper.createOrUpdatePatch(
720*ec779b8eSAndroid Build Coastguard Worker                                 aidlSources, aidlSinks, &newAidlPatchId, &cleanups));
721*ec779b8eSAndroid Build Coastguard Worker                 mMapper.updateFwkPatch(aidlPatchId, newAidlPatchId);
722*ec779b8eSAndroid Build Coastguard Worker             } else {
723*ec779b8eSAndroid Build Coastguard Worker                 RETURN_STATUS_IF_ERROR(mMapper.createOrUpdatePatch(
724*ec779b8eSAndroid Build Coastguard Worker                                 aidlSources, aidlSinks, &aidlHalPatchId, &cleanups));
725*ec779b8eSAndroid Build Coastguard Worker             }
726*ec779b8eSAndroid Build Coastguard Worker         } else {
727*ec779b8eSAndroid Build Coastguard Worker             RETURN_STATUS_IF_ERROR(mMapper.createOrUpdatePatch(
728*ec779b8eSAndroid Build Coastguard Worker                             aidlSources, aidlSinks, &aidlPatchId, &cleanups));
729*ec779b8eSAndroid Build Coastguard Worker         }
730*ec779b8eSAndroid Build Coastguard Worker     }
731*ec779b8eSAndroid Build Coastguard Worker     *patch = static_cast<audio_patch_handle_t>(aidlPatchId);
732*ec779b8eSAndroid Build Coastguard Worker     cleanups.disarmAll();
733*ec779b8eSAndroid Build Coastguard Worker     return OK;
734*ec779b8eSAndroid Build Coastguard Worker }
735*ec779b8eSAndroid Build Coastguard Worker 
releaseAudioPatch(audio_patch_handle_t patch)736*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
737*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "patch: %d", patch);
738*ec779b8eSAndroid Build Coastguard Worker 
739*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
740*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
741*ec779b8eSAndroid Build Coastguard Worker     static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
742*ec779b8eSAndroid Build Coastguard Worker     if (patch == AUDIO_PATCH_HANDLE_NONE) {
743*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
744*ec779b8eSAndroid Build Coastguard Worker     }
745*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
746*ec779b8eSAndroid Build Coastguard Worker     // Check for patches that only exist for the framework, or have different HAL patch ID.
747*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlPatchId = static_cast<int32_t>(patch);
748*ec779b8eSAndroid Build Coastguard Worker     if (int32_t aidlHalPatchId = mMapper.findFwkPatch(aidlPatchId); aidlHalPatchId != 0) {
749*ec779b8eSAndroid Build Coastguard Worker         if (aidlHalPatchId == aidlPatchId) {
750*ec779b8eSAndroid Build Coastguard Worker             // This patch was previously released by the HAL, just need to finish its removal.
751*ec779b8eSAndroid Build Coastguard Worker             mMapper.eraseFwkPatch(aidlPatchId);
752*ec779b8eSAndroid Build Coastguard Worker             return OK;
753*ec779b8eSAndroid Build Coastguard Worker         } else {
754*ec779b8eSAndroid Build Coastguard Worker             // This patch has a HAL patch ID which is different
755*ec779b8eSAndroid Build Coastguard Worker             aidlPatchId = aidlHalPatchId;
756*ec779b8eSAndroid Build Coastguard Worker         }
757*ec779b8eSAndroid Build Coastguard Worker     }
758*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(mMapper.releaseAudioPatch(aidlPatchId));
759*ec779b8eSAndroid Build Coastguard Worker     return OK;
760*ec779b8eSAndroid Build Coastguard Worker }
761*ec779b8eSAndroid Build Coastguard Worker 
getAudioPort(struct audio_port * port)762*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getAudioPort(struct audio_port* port) {
763*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
764*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
765*ec779b8eSAndroid Build Coastguard Worker     if (port == nullptr) {
766*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "port not initialized");
767*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
768*ec779b8eSAndroid Build Coastguard Worker     }
769*ec779b8eSAndroid Build Coastguard Worker     audio_port_v7 portV7;
770*ec779b8eSAndroid Build Coastguard Worker     audio_populate_audio_port_v7(port, &portV7);
771*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(getAudioPort(&portV7));
772*ec779b8eSAndroid Build Coastguard Worker     return audio_populate_audio_port(&portV7, port) ? OK : BAD_VALUE;
773*ec779b8eSAndroid Build Coastguard Worker }
774*ec779b8eSAndroid Build Coastguard Worker 
getAudioPort(struct audio_port_v7 * port)775*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port) {
776*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
777*ec779b8eSAndroid Build Coastguard Worker 
778*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
779*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
780*ec779b8eSAndroid Build Coastguard Worker     if (port == nullptr) {
781*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "port not initialized");
782*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
783*ec779b8eSAndroid Build Coastguard Worker     }
784*ec779b8eSAndroid Build Coastguard Worker     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(port->role, port->type)) ==
785*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::AudioPortDirection::INPUT;
786*ec779b8eSAndroid Build Coastguard Worker     auto aidlPort = VALUE_OR_RETURN_STATUS(
787*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_v7_AudioPort(*port, isInput));
788*ec779b8eSAndroid Build Coastguard Worker     if (aidlPort.ext.getTag() != AudioPortExt::device) {
789*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "provided port is not a device port %s", aidlPort.toString().c_str());
790*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
791*ec779b8eSAndroid Build Coastguard Worker     }
792*ec779b8eSAndroid Build Coastguard Worker     const auto& matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
793*ec779b8eSAndroid Build Coastguard Worker     // It seems that we don't have to call HAL since all valid ports have been added either
794*ec779b8eSAndroid Build Coastguard Worker     // during initialization, or while handling connection of an external device.
795*ec779b8eSAndroid Build Coastguard Worker     const int32_t fwkId = aidlPort.id;
796*ec779b8eSAndroid Build Coastguard Worker     {
797*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
798*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.getAudioPortCached(matchDevice, &aidlPort));
799*ec779b8eSAndroid Build Coastguard Worker     }
800*ec779b8eSAndroid Build Coastguard Worker     aidlPort.id = fwkId;
801*ec779b8eSAndroid Build Coastguard Worker     *port = VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioPort_audio_port_v7(
802*ec779b8eSAndroid Build Coastguard Worker                     aidlPort, isInput));
803*ec779b8eSAndroid Build Coastguard Worker     return OK;
804*ec779b8eSAndroid Build Coastguard Worker }
805*ec779b8eSAndroid Build Coastguard Worker 
getAudioMixPort(const struct audio_port_v7 * devicePort,struct audio_port_v7 * mixPort)806*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getAudioMixPort(const struct audio_port_v7 *devicePort,
807*ec779b8eSAndroid Build Coastguard Worker                                         struct audio_port_v7 *mixPort) {
808*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
809*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
810*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
811*ec779b8eSAndroid Build Coastguard Worker 
812*ec779b8eSAndroid Build Coastguard Worker     if (devicePort == nullptr || mixPort == nullptr || devicePort->type != AUDIO_PORT_TYPE_DEVICE ||
813*ec779b8eSAndroid Build Coastguard Worker         mixPort->type != AUDIO_PORT_TYPE_MIX) {
814*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "invalid device or mix port");
815*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
816*ec779b8eSAndroid Build Coastguard Worker     }
817*ec779b8eSAndroid Build Coastguard Worker     const int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
818*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(mixPort->ext.mix.handle));
819*ec779b8eSAndroid Build Coastguard Worker     AudioPort port;
820*ec779b8eSAndroid Build Coastguard Worker     {
821*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
822*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.getAudioMixPort(aidlHandle, &port));
823*ec779b8eSAndroid Build Coastguard Worker     }
824*ec779b8eSAndroid Build Coastguard Worker     const bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
825*ec779b8eSAndroid Build Coastguard Worker             mixPort->role, mixPort->type)) == ::aidl::android::AudioPortDirection::INPUT;
826*ec779b8eSAndroid Build Coastguard Worker     *mixPort = VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioPort_audio_port_v7(
827*ec779b8eSAndroid Build Coastguard Worker             port, isInput));
828*ec779b8eSAndroid Build Coastguard Worker     return OK;
829*ec779b8eSAndroid Build Coastguard Worker }
830*ec779b8eSAndroid Build Coastguard Worker 
setAudioPortConfig(const struct audio_port_config * config)831*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
832*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
833*ec779b8eSAndroid Build Coastguard Worker 
834*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
835*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
836*ec779b8eSAndroid Build Coastguard Worker     if (config == nullptr) {
837*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "config not initialized");
838*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
839*ec779b8eSAndroid Build Coastguard Worker     }
840*ec779b8eSAndroid Build Coastguard Worker     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
841*ec779b8eSAndroid Build Coastguard Worker                     config->role, config->type)) == ::aidl::android::AudioPortDirection::INPUT;
842*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig requestedPortConfig = VALUE_OR_RETURN_STATUS(
843*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
844*ec779b8eSAndroid Build Coastguard Worker                     *config, isInput, 0 /*portId*/));
845*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig portConfig;
846*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
847*ec779b8eSAndroid Build Coastguard Worker     return mMapper.setPortConfig(requestedPortConfig, std::set<int32_t>(), &portConfig);
848*ec779b8eSAndroid Build Coastguard Worker }
849*ec779b8eSAndroid Build Coastguard Worker 
getMicrophoneInfo()850*ec779b8eSAndroid Build Coastguard Worker MicrophoneInfoProvider::Info const* DeviceHalAidl::getMicrophoneInfo() {
851*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
852*ec779b8eSAndroid Build Coastguard Worker 
853*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
854*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT({});
855*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
856*ec779b8eSAndroid Build Coastguard Worker     if (mMicrophones.status == Microphones::Status::UNKNOWN) {
857*ec779b8eSAndroid Build Coastguard Worker         TIME_CHECK();
858*ec779b8eSAndroid Build Coastguard Worker         std::vector<MicrophoneInfo> aidlInfo;
859*ec779b8eSAndroid Build Coastguard Worker         status_t status = statusTFromBinderStatus(mModule->getMicrophones(&aidlInfo));
860*ec779b8eSAndroid Build Coastguard Worker         if (status == OK) {
861*ec779b8eSAndroid Build Coastguard Worker             mMicrophones.status = Microphones::Status::QUERIED;
862*ec779b8eSAndroid Build Coastguard Worker             mMicrophones.info = std::move(aidlInfo);
863*ec779b8eSAndroid Build Coastguard Worker         } else if (status == INVALID_OPERATION) {
864*ec779b8eSAndroid Build Coastguard Worker             mMicrophones.status = Microphones::Status::NOT_SUPPORTED;
865*ec779b8eSAndroid Build Coastguard Worker         } else {
866*ec779b8eSAndroid Build Coastguard Worker             AUGMENT_LOG(E, "Unexpected status from HAL: %d", status);
867*ec779b8eSAndroid Build Coastguard Worker             return {};
868*ec779b8eSAndroid Build Coastguard Worker         }
869*ec779b8eSAndroid Build Coastguard Worker     }
870*ec779b8eSAndroid Build Coastguard Worker     if (mMicrophones.status == Microphones::Status::QUERIED) {
871*ec779b8eSAndroid Build Coastguard Worker         return &mMicrophones.info;
872*ec779b8eSAndroid Build Coastguard Worker     }
873*ec779b8eSAndroid Build Coastguard Worker     return {};  // NOT_SUPPORTED
874*ec779b8eSAndroid Build Coastguard Worker }
875*ec779b8eSAndroid Build Coastguard Worker 
getMicrophones(std::vector<audio_microphone_characteristic_t> * microphones)876*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getMicrophones(
877*ec779b8eSAndroid Build Coastguard Worker         std::vector<audio_microphone_characteristic_t>* microphones) {
878*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
879*ec779b8eSAndroid Build Coastguard Worker 
880*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
881*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
882*ec779b8eSAndroid Build Coastguard Worker     if (microphones == nullptr) {
883*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "microphones not initialized");
884*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
885*ec779b8eSAndroid Build Coastguard Worker     }
886*ec779b8eSAndroid Build Coastguard Worker     auto staticInfo = getMicrophoneInfo();
887*ec779b8eSAndroid Build Coastguard Worker     if (!staticInfo) return INVALID_OPERATION;
888*ec779b8eSAndroid Build Coastguard Worker     std::vector<MicrophoneDynamicInfo> emptyDynamicInfo;
889*ec779b8eSAndroid Build Coastguard Worker     emptyDynamicInfo.reserve(staticInfo->size());
890*ec779b8eSAndroid Build Coastguard Worker     std::transform(staticInfo->begin(), staticInfo->end(), std::back_inserter(emptyDynamicInfo),
891*ec779b8eSAndroid Build Coastguard Worker             [](const auto& info) { return MicrophoneDynamicInfo{ .id = info.id }; });
892*ec779b8eSAndroid Build Coastguard Worker     *microphones = VALUE_OR_RETURN_STATUS(
893*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::convertContainers<std::vector<audio_microphone_characteristic_t>>(
894*ec779b8eSAndroid Build Coastguard Worker                     *staticInfo, emptyDynamicInfo,
895*ec779b8eSAndroid Build Coastguard Worker                     ::aidl::android::aidl2legacy_MicrophoneInfos_audio_microphone_characteristic_t)
896*ec779b8eSAndroid Build Coastguard Worker     );
897*ec779b8eSAndroid Build Coastguard Worker     return OK;
898*ec779b8eSAndroid Build Coastguard Worker }
899*ec779b8eSAndroid Build Coastguard Worker 
addDeviceEffect(const struct audio_port_config * device,sp<EffectHalInterface> effect)900*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::addDeviceEffect(
901*ec779b8eSAndroid Build Coastguard Worker         const struct audio_port_config *device, sp<EffectHalInterface> effect) {
902*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
903*ec779b8eSAndroid Build Coastguard Worker 
904*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
905*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
906*ec779b8eSAndroid Build Coastguard Worker     if (device == nullptr || effect == nullptr) {
907*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "device or effect not initialized");
908*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
909*ec779b8eSAndroid Build Coastguard Worker     }
910*ec779b8eSAndroid Build Coastguard Worker     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
911*ec779b8eSAndroid Build Coastguard Worker                     device->role, device->type)) == ::aidl::android::AudioPortDirection::INPUT;
912*ec779b8eSAndroid Build Coastguard Worker     auto requestedPortConfig = VALUE_OR_RETURN_STATUS(
913*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
914*ec779b8eSAndroid Build Coastguard Worker                     *device, isInput, 0));
915*ec779b8eSAndroid Build Coastguard Worker     if (requestedPortConfig.ext.getTag() != AudioPortExt::Tag::device) {
916*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "provided port config is not a device port config: %s",
917*ec779b8eSAndroid Build Coastguard Worker                     requestedPortConfig.toString().c_str());
918*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
919*ec779b8eSAndroid Build Coastguard Worker     }
920*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig devicePortConfig;
921*ec779b8eSAndroid Build Coastguard Worker     Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
922*ec779b8eSAndroid Build Coastguard Worker     {
923*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
924*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.setPortConfig(
925*ec779b8eSAndroid Build Coastguard Worker                     requestedPortConfig, {} /*destinationPortIds*/, &devicePortConfig, &cleanups));
926*ec779b8eSAndroid Build Coastguard Worker     }
927*ec779b8eSAndroid Build Coastguard Worker     auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
928*ec779b8eSAndroid Build Coastguard Worker     {
929*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
930*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
931*ec779b8eSAndroid Build Coastguard Worker                 mModule->addDeviceEffect(devicePortConfig.id, aidlEffect->getIEffect())));
932*ec779b8eSAndroid Build Coastguard Worker     }
933*ec779b8eSAndroid Build Coastguard Worker     cleanups.disarmAll();
934*ec779b8eSAndroid Build Coastguard Worker     return OK;
935*ec779b8eSAndroid Build Coastguard Worker }
removeDeviceEffect(const struct audio_port_config * device,sp<EffectHalInterface> effect)936*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::removeDeviceEffect(
937*ec779b8eSAndroid Build Coastguard Worker         const struct audio_port_config *device, sp<EffectHalInterface> effect) {
938*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
939*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
940*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
941*ec779b8eSAndroid Build Coastguard Worker     if (device == nullptr || effect == nullptr) {
942*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "device or effect not initialized");
943*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
944*ec779b8eSAndroid Build Coastguard Worker     }
945*ec779b8eSAndroid Build Coastguard Worker     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
946*ec779b8eSAndroid Build Coastguard Worker                     device->role, device->type)) == ::aidl::android::AudioPortDirection::INPUT;
947*ec779b8eSAndroid Build Coastguard Worker     auto requestedPortConfig = VALUE_OR_RETURN_STATUS(
948*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
949*ec779b8eSAndroid Build Coastguard Worker                     *device, isInput, 0));
950*ec779b8eSAndroid Build Coastguard Worker     if (requestedPortConfig.ext.getTag() != AudioPortExt::Tag::device) {
951*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "provided port config is not a device port config: %s",
952*ec779b8eSAndroid Build Coastguard Worker                     requestedPortConfig.toString().c_str());
953*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
954*ec779b8eSAndroid Build Coastguard Worker     }
955*ec779b8eSAndroid Build Coastguard Worker     AudioPortConfig devicePortConfig;
956*ec779b8eSAndroid Build Coastguard Worker     {
957*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
958*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(mMapper.findPortConfig(
959*ec779b8eSAndroid Build Coastguard Worker                         requestedPortConfig.ext.get<AudioPortExt::Tag::device>().device,
960*ec779b8eSAndroid Build Coastguard Worker                         &devicePortConfig));
961*ec779b8eSAndroid Build Coastguard Worker     }
962*ec779b8eSAndroid Build Coastguard Worker     auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
963*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
964*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->removeDeviceEffect(
965*ec779b8eSAndroid Build Coastguard Worker                     devicePortConfig.id, aidlEffect->getIEffect()));
966*ec779b8eSAndroid Build Coastguard Worker }
967*ec779b8eSAndroid Build Coastguard Worker 
getMmapPolicyInfos(media::audio::common::AudioMMapPolicyType policyType,std::vector<media::audio::common::AudioMMapPolicyInfo> * policyInfos)968*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getMmapPolicyInfos(
969*ec779b8eSAndroid Build Coastguard Worker         media::audio::common::AudioMMapPolicyType policyType,
970*ec779b8eSAndroid Build Coastguard Worker         std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) {
971*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
972*ec779b8eSAndroid Build Coastguard Worker 
973*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
974*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
975*ec779b8eSAndroid Build Coastguard Worker 
976*ec779b8eSAndroid Build Coastguard Worker     AudioMMapPolicyType mmapPolicyType =
977*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(cpp2ndk_AudioMMapPolicyType(policyType));
978*ec779b8eSAndroid Build Coastguard Worker 
979*ec779b8eSAndroid Build Coastguard Worker     std::vector<AudioMMapPolicyInfo> mmapPolicyInfos;
980*ec779b8eSAndroid Build Coastguard Worker 
981*ec779b8eSAndroid Build Coastguard Worker     {
982*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
983*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
984*ec779b8eSAndroid Build Coastguard Worker                         mModule->getMmapPolicyInfos(mmapPolicyType, &mmapPolicyInfos)));
985*ec779b8eSAndroid Build Coastguard Worker     }
986*ec779b8eSAndroid Build Coastguard Worker 
987*ec779b8eSAndroid Build Coastguard Worker     *policyInfos = VALUE_OR_RETURN_STATUS(
988*ec779b8eSAndroid Build Coastguard Worker             convertContainer<std::vector<media::audio::common::AudioMMapPolicyInfo>>(
989*ec779b8eSAndroid Build Coastguard Worker                 mmapPolicyInfos, ndk2cpp_AudioMMapPolicyInfo));
990*ec779b8eSAndroid Build Coastguard Worker     return OK;
991*ec779b8eSAndroid Build Coastguard Worker }
992*ec779b8eSAndroid Build Coastguard Worker 
getAAudioMixerBurstCount()993*ec779b8eSAndroid Build Coastguard Worker int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
994*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
995*ec779b8eSAndroid Build Coastguard Worker 
996*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
997*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
998*ec779b8eSAndroid Build Coastguard Worker     int32_t mixerBurstCount = 0;
999*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1000*ec779b8eSAndroid Build Coastguard Worker     return mModule->getAAudioMixerBurstCount(&mixerBurstCount).isOk() ? mixerBurstCount : 0;
1001*ec779b8eSAndroid Build Coastguard Worker }
1002*ec779b8eSAndroid Build Coastguard Worker 
getAAudioHardwareBurstMinUsec()1003*ec779b8eSAndroid Build Coastguard Worker int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
1004*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
1005*ec779b8eSAndroid Build Coastguard Worker 
1006*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1007*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1008*ec779b8eSAndroid Build Coastguard Worker     int32_t hardwareBurstMinUsec = 0;
1009*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1010*ec779b8eSAndroid Build Coastguard Worker     return mModule->getAAudioHardwareBurstMinUsec(&hardwareBurstMinUsec).isOk() ?
1011*ec779b8eSAndroid Build Coastguard Worker             hardwareBurstMinUsec : 0;
1012*ec779b8eSAndroid Build Coastguard Worker }
1013*ec779b8eSAndroid Build Coastguard Worker 
getHwAvSync()1014*ec779b8eSAndroid Build Coastguard Worker error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
1015*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
1016*ec779b8eSAndroid Build Coastguard Worker 
1017*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1018*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1019*ec779b8eSAndroid Build Coastguard Worker     int32_t aidlHwAvSync;
1020*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1021*ec779b8eSAndroid Build Coastguard Worker     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->generateHwAvSyncId(&aidlHwAvSync)));
1022*ec779b8eSAndroid Build Coastguard Worker     return VALUE_OR_RETURN_STATUS(
1023*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::aidl2legacy_int32_t_audio_hw_sync_t(aidlHwAvSync));
1024*ec779b8eSAndroid Build Coastguard Worker }
1025*ec779b8eSAndroid Build Coastguard Worker 
dump(int fd,const Vector<String16> & args)1026*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
1027*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1028*ec779b8eSAndroid Build Coastguard Worker     if (!isModuleInitialized()) return NO_INIT;
1029*ec779b8eSAndroid Build Coastguard Worker     Vector<String16> newArgs = args;
1030*ec779b8eSAndroid Build Coastguard Worker     newArgs.push(String16(kDumpFromAudioServerArgument));
1031*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1032*ec779b8eSAndroid Build Coastguard Worker     return mModule->dump(fd, Args(newArgs).args(), newArgs.size());
1033*ec779b8eSAndroid Build Coastguard Worker }
1034*ec779b8eSAndroid Build Coastguard Worker 
supportsBluetoothVariableLatency(bool * supports)1035*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports) {
1036*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D);
1037*ec779b8eSAndroid Build Coastguard Worker 
1038*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1039*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1040*ec779b8eSAndroid Build Coastguard Worker     if (supports == nullptr) {
1041*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1042*ec779b8eSAndroid Build Coastguard Worker     }
1043*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1044*ec779b8eSAndroid Build Coastguard Worker     return statusTFromBinderStatus(mModule->supportsVariableLatency(supports));
1045*ec779b8eSAndroid Build Coastguard Worker }
1046*ec779b8eSAndroid Build Coastguard Worker 
getSoundDoseInterface(const std::string & module,::ndk::SpAIBinder * soundDoseBinder)1047*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::getSoundDoseInterface([[maybe_unused]] const std::string& module,
1048*ec779b8eSAndroid Build Coastguard Worker                                               ::ndk::SpAIBinder* soundDoseBinder) {
1049*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
1050*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1051*ec779b8eSAndroid Build Coastguard Worker 
1052*ec779b8eSAndroid Build Coastguard Worker     if (soundDoseBinder == nullptr) {
1053*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1054*ec779b8eSAndroid Build Coastguard Worker     }
1055*ec779b8eSAndroid Build Coastguard Worker     if (mSoundDose == nullptr) {
1056*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "failed to retrieve the sound dose interface");
1057*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
1058*ec779b8eSAndroid Build Coastguard Worker     }
1059*ec779b8eSAndroid Build Coastguard Worker 
1060*ec779b8eSAndroid Build Coastguard Worker     *soundDoseBinder = mSoundDose->asBinder();
1061*ec779b8eSAndroid Build Coastguard Worker     if (soundDoseBinder == nullptr) {
1062*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "failed to return the sound dose interface not implemented");
1063*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
1064*ec779b8eSAndroid Build Coastguard Worker     }
1065*ec779b8eSAndroid Build Coastguard Worker 
1066*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(I, "using audio AIDL HAL sound dose interface");
1067*ec779b8eSAndroid Build Coastguard Worker     return OK;
1068*ec779b8eSAndroid Build Coastguard Worker }
1069*ec779b8eSAndroid Build Coastguard Worker 
prepareToDisconnectExternalDevice(const struct audio_port_v7 * port)1070*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::prepareToDisconnectExternalDevice(const struct audio_port_v7* port) {
1071*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
1072*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1073*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1074*ec779b8eSAndroid Build Coastguard Worker     if (port == nullptr) {
1075*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "port not initialized");
1076*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1077*ec779b8eSAndroid Build Coastguard Worker     }
1078*ec779b8eSAndroid Build Coastguard Worker     const bool isInput =
1079*ec779b8eSAndroid Build Coastguard Worker             VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(port->role, port->type)) ==
1080*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::AudioPortDirection::INPUT;
1081*ec779b8eSAndroid Build Coastguard Worker     AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
1082*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_v7_AudioPort(*port, isInput));
1083*ec779b8eSAndroid Build Coastguard Worker     if (aidlPort.ext.getTag() != AudioPortExt::device) {
1084*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "provided port is not a device port: %s", aidlPort.toString().c_str());
1085*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1086*ec779b8eSAndroid Build Coastguard Worker     }
1087*ec779b8eSAndroid Build Coastguard Worker 
1088*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "device %s", aidlPort.toString().c_str());
1089*ec779b8eSAndroid Build Coastguard Worker 
1090*ec779b8eSAndroid Build Coastguard Worker     status_t status = NO_ERROR;
1091*ec779b8eSAndroid Build Coastguard Worker     {
1092*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
1093*ec779b8eSAndroid Build Coastguard Worker         status = mMapper.prepareToDisconnectExternalDevice(aidlPort);
1094*ec779b8eSAndroid Build Coastguard Worker     }
1095*ec779b8eSAndroid Build Coastguard Worker     if (status == UNKNOWN_TRANSACTION) {
1096*ec779b8eSAndroid Build Coastguard Worker         // If there is not AIDL API defined for `prepareToDisconnectExternalDevice`.
1097*ec779b8eSAndroid Build Coastguard Worker         // Call `setConnectedState` instead.
1098*ec779b8eSAndroid Build Coastguard Worker         RETURN_STATUS_IF_ERROR(setConnectedState(port, false /*connected*/));
1099*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
1100*ec779b8eSAndroid Build Coastguard Worker         mDeviceDisconnectionNotified.insert(port->id);
1101*ec779b8eSAndroid Build Coastguard Worker         // Return that there was no error as otherwise the disconnection procedure will not be
1102*ec779b8eSAndroid Build Coastguard Worker         // considered complete for upper layers, and 'setConnectedState' will not be called again
1103*ec779b8eSAndroid Build Coastguard Worker         return OK;
1104*ec779b8eSAndroid Build Coastguard Worker     } else {
1105*ec779b8eSAndroid Build Coastguard Worker         return status;
1106*ec779b8eSAndroid Build Coastguard Worker     }
1107*ec779b8eSAndroid Build Coastguard Worker }
1108*ec779b8eSAndroid Build Coastguard Worker 
setConnectedState(const struct audio_port_v7 * port,bool connected)1109*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
1110*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
1111*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1112*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1113*ec779b8eSAndroid Build Coastguard Worker     if (port == nullptr) {
1114*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "port not initialized");
1115*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1116*ec779b8eSAndroid Build Coastguard Worker     }
1117*ec779b8eSAndroid Build Coastguard Worker     if (!connected) {
1118*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
1119*ec779b8eSAndroid Build Coastguard Worker         if (mDeviceDisconnectionNotified.erase(port->id) > 0) {
1120*ec779b8eSAndroid Build Coastguard Worker             // For device disconnection, APM will first call `prepareToDisconnectExternalDevice`
1121*ec779b8eSAndroid Build Coastguard Worker             // and then call `setConnectedState`. If `prepareToDisconnectExternalDevice` doesn't
1122*ec779b8eSAndroid Build Coastguard Worker             // exit, `setConnectedState` will be called when calling
1123*ec779b8eSAndroid Build Coastguard Worker             // `prepareToDisconnectExternalDevice`. Do not call to the HAL if previous call is
1124*ec779b8eSAndroid Build Coastguard Worker             // successful. Also remove the cache here to avoid a large cache after a long run.
1125*ec779b8eSAndroid Build Coastguard Worker             return OK;
1126*ec779b8eSAndroid Build Coastguard Worker         }
1127*ec779b8eSAndroid Build Coastguard Worker     }
1128*ec779b8eSAndroid Build Coastguard Worker     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(port->role, port->type)) ==
1129*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::AudioPortDirection::INPUT;
1130*ec779b8eSAndroid Build Coastguard Worker     AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
1131*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::legacy2aidl_audio_port_v7_AudioPort(*port, isInput));
1132*ec779b8eSAndroid Build Coastguard Worker     if (aidlPort.ext.getTag() != AudioPortExt::device) {
1133*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(E, "provided port is not a device port: %s", aidlPort.toString().c_str());
1134*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
1135*ec779b8eSAndroid Build Coastguard Worker     }
1136*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(D, "connected %d port: %s", connected, aidlPort.toString().c_str());
1137*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1138*ec779b8eSAndroid Build Coastguard Worker     return mMapper.setDevicePortConnectedState(aidlPort, connected);
1139*ec779b8eSAndroid Build Coastguard Worker }
1140*ec779b8eSAndroid Build Coastguard Worker 
setSimulateDeviceConnections(bool enabled)1141*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::setSimulateDeviceConnections(bool enabled) {
1142*ec779b8eSAndroid Build Coastguard Worker     AUGMENT_LOG(V);
1143*ec779b8eSAndroid Build Coastguard Worker     TIME_CHECK();
1144*ec779b8eSAndroid Build Coastguard Worker     RETURN_IF_MODULE_NOT_INIT(NO_INIT);
1145*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1146*ec779b8eSAndroid Build Coastguard Worker     mMapper.resetUnusedPatchesAndPortConfigs();
1147*ec779b8eSAndroid Build Coastguard Worker     ModuleDebug debug{ .simulateDeviceConnections = enabled };
1148*ec779b8eSAndroid Build Coastguard Worker     status_t status = statusTFromBinderStatus(mModule->setModuleDebug(debug));
1149*ec779b8eSAndroid Build Coastguard Worker     // This is important to log as it affects HAL behavior.
1150*ec779b8eSAndroid Build Coastguard Worker     if (status == OK) {
1151*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(I, "set enabled: %d", enabled);
1152*ec779b8eSAndroid Build Coastguard Worker     } else {
1153*ec779b8eSAndroid Build Coastguard Worker         AUGMENT_LOG(W, "set enabled to %d failed: %d", enabled, status);
1154*ec779b8eSAndroid Build Coastguard Worker     }
1155*ec779b8eSAndroid Build Coastguard Worker     return status;
1156*ec779b8eSAndroid Build Coastguard Worker }
1157*ec779b8eSAndroid Build Coastguard Worker 
filterAndRetrieveBtA2dpParameters(AudioParameter & keys,AudioParameter * result)1158*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndRetrieveBtA2dpParameters(
1159*ec779b8eSAndroid Build Coastguard Worker         AudioParameter &keys, AudioParameter *result) {
1160*ec779b8eSAndroid Build Coastguard Worker     if (String8 key = String8(AudioParameter::keyReconfigA2dpSupported); keys.containsKey(key)) {
1161*ec779b8eSAndroid Build Coastguard Worker         keys.remove(key);
1162*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
1163*ec779b8eSAndroid Build Coastguard Worker         if (mBluetoothA2dp != nullptr) {
1164*ec779b8eSAndroid Build Coastguard Worker             bool supports;
1165*ec779b8eSAndroid Build Coastguard Worker             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
1166*ec779b8eSAndroid Build Coastguard Worker                             mBluetoothA2dp->supportsOffloadReconfiguration(&supports)));
1167*ec779b8eSAndroid Build Coastguard Worker             result->addInt(key, supports ? 1 : 0);
1168*ec779b8eSAndroid Build Coastguard Worker         } else {
1169*ec779b8eSAndroid Build Coastguard Worker             AUGMENT_LOG(I, "no IBluetoothA2dp");
1170*ec779b8eSAndroid Build Coastguard Worker             result->addInt(key, 0);
1171*ec779b8eSAndroid Build Coastguard Worker         }
1172*ec779b8eSAndroid Build Coastguard Worker     }
1173*ec779b8eSAndroid Build Coastguard Worker     return OK;
1174*ec779b8eSAndroid Build Coastguard Worker }
1175*ec779b8eSAndroid Build Coastguard Worker 
filterAndRetrieveBtLeParameters(AudioParameter & keys,AudioParameter * result)1176*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndRetrieveBtLeParameters(
1177*ec779b8eSAndroid Build Coastguard Worker         AudioParameter &keys, AudioParameter *result) {
1178*ec779b8eSAndroid Build Coastguard Worker     if (String8 key = String8(AudioParameter::keyReconfigLeSupported); keys.containsKey(key)) {
1179*ec779b8eSAndroid Build Coastguard Worker         keys.remove(key);
1180*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mLock);
1181*ec779b8eSAndroid Build Coastguard Worker         if (mBluetoothLe != nullptr) {
1182*ec779b8eSAndroid Build Coastguard Worker             bool supports;
1183*ec779b8eSAndroid Build Coastguard Worker             RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
1184*ec779b8eSAndroid Build Coastguard Worker                             mBluetoothLe->supportsOffloadReconfiguration(&supports)));
1185*ec779b8eSAndroid Build Coastguard Worker             result->addInt(key, supports ? 1 : 0);
1186*ec779b8eSAndroid Build Coastguard Worker         } else {
1187*ec779b8eSAndroid Build Coastguard Worker             AUGMENT_LOG(I, "no mBluetoothLe");
1188*ec779b8eSAndroid Build Coastguard Worker             result->addInt(key, 0);
1189*ec779b8eSAndroid Build Coastguard Worker         }
1190*ec779b8eSAndroid Build Coastguard Worker     }
1191*ec779b8eSAndroid Build Coastguard Worker     return OK;
1192*ec779b8eSAndroid Build Coastguard Worker }
1193*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateBtA2dpParameters(AudioParameter & parameters)1194*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateBtA2dpParameters(AudioParameter &parameters) {
1195*ec779b8eSAndroid Build Coastguard Worker     std::optional<bool> a2dpEnabled;
1196*ec779b8eSAndroid Build Coastguard Worker     std::optional<std::vector<VendorParameter>> reconfigureOffload;
1197*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1198*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtA2dpSuspended),
1199*ec779b8eSAndroid Build Coastguard Worker             [&a2dpEnabled, this](const String8& trueOrFalse) {
1200*ec779b8eSAndroid Build Coastguard Worker                 if (trueOrFalse == AudioParameter::valueTrue) {
1201*ec779b8eSAndroid Build Coastguard Worker                     a2dpEnabled = false;  // 'suspended' == true
1202*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1203*ec779b8eSAndroid Build Coastguard Worker                 } else if (trueOrFalse == AudioParameter::valueFalse) {
1204*ec779b8eSAndroid Build Coastguard Worker                     a2dpEnabled = true;  // 'suspended' == false
1205*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1206*ec779b8eSAndroid Build Coastguard Worker                 }
1207*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1208*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtA2dpSuspended, trueOrFalse.c_str());
1209*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1210*ec779b8eSAndroid Build Coastguard Worker             }));
1211*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1212*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyReconfigA2dp),
1213*ec779b8eSAndroid Build Coastguard Worker             [&](const String8& value) -> status_t {
1214*ec779b8eSAndroid Build Coastguard Worker                 std::vector<VendorParameter> result;
1215*ec779b8eSAndroid Build Coastguard Worker                 RETURN_STATUS_IF_ERROR(
1216*ec779b8eSAndroid Build Coastguard Worker                         statusTFromBinderStatus(mVendorExt->parseBluetoothA2dpReconfigureOffload(
1217*ec779b8eSAndroid Build Coastguard Worker                                 std::string(value.c_str()), &result)));
1218*ec779b8eSAndroid Build Coastguard Worker                 reconfigureOffload = std::move(result);
1219*ec779b8eSAndroid Build Coastguard Worker                 return OK;
1220*ec779b8eSAndroid Build Coastguard Worker             }));
1221*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1222*ec779b8eSAndroid Build Coastguard Worker     if (mBluetoothA2dp != nullptr && a2dpEnabled.has_value()) {
1223*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mBluetoothA2dp->setEnabled(a2dpEnabled.value()));
1224*ec779b8eSAndroid Build Coastguard Worker     }
1225*ec779b8eSAndroid Build Coastguard Worker     if (mBluetoothA2dp != nullptr && reconfigureOffload.has_value()) {
1226*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mBluetoothA2dp->reconfigureOffload(
1227*ec779b8eSAndroid Build Coastguard Worker                         reconfigureOffload.value()));
1228*ec779b8eSAndroid Build Coastguard Worker     }
1229*ec779b8eSAndroid Build Coastguard Worker     return OK;
1230*ec779b8eSAndroid Build Coastguard Worker }
1231*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateBtHfpParameters(AudioParameter & parameters)1232*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateBtHfpParameters(AudioParameter &parameters) {
1233*ec779b8eSAndroid Build Coastguard Worker     IBluetooth::HfpConfig hfpConfig;
1234*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1235*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtHfpEnable),
1236*ec779b8eSAndroid Build Coastguard Worker             [&hfpConfig, this](const String8& trueOrFalse) {
1237*ec779b8eSAndroid Build Coastguard Worker                 if (trueOrFalse == AudioParameter::valueTrue) {
1238*ec779b8eSAndroid Build Coastguard Worker                     hfpConfig.isEnabled = Boolean{.value = true};
1239*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1240*ec779b8eSAndroid Build Coastguard Worker                 } else if (trueOrFalse == AudioParameter::valueFalse) {
1241*ec779b8eSAndroid Build Coastguard Worker                     hfpConfig.isEnabled = Boolean{.value = false};
1242*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1243*ec779b8eSAndroid Build Coastguard Worker                 }
1244*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1245*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtHfpEnable, trueOrFalse.c_str());
1246*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1247*ec779b8eSAndroid Build Coastguard Worker             }));
1248*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
1249*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtHfpSamplingRate),
1250*ec779b8eSAndroid Build Coastguard Worker             [&hfpConfig](int sampleRate) {
1251*ec779b8eSAndroid Build Coastguard Worker                 return sampleRate > 0 ? hfpConfig.sampleRate = Int{.value = sampleRate},
1252*ec779b8eSAndroid Build Coastguard Worker                                         OK : BAD_VALUE;
1253*ec779b8eSAndroid Build Coastguard Worker             }));
1254*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
1255*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtHfpVolume), [&hfpConfig](int volume0to15) {
1256*ec779b8eSAndroid Build Coastguard Worker                 if (volume0to15 >= 0 && volume0to15 <= 15) {
1257*ec779b8eSAndroid Build Coastguard Worker                     hfpConfig.volume = Float{.value = volume0to15 / 15.0f};
1258*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1259*ec779b8eSAndroid Build Coastguard Worker                 }
1260*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1261*ec779b8eSAndroid Build Coastguard Worker             }));
1262*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1263*ec779b8eSAndroid Build Coastguard Worker     if (mBluetooth != nullptr && hfpConfig != IBluetooth::HfpConfig{}) {
1264*ec779b8eSAndroid Build Coastguard Worker         IBluetooth::HfpConfig newHfpConfig;
1265*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mBluetooth->setHfpConfig(hfpConfig, &newHfpConfig));
1266*ec779b8eSAndroid Build Coastguard Worker     }
1267*ec779b8eSAndroid Build Coastguard Worker     return OK;
1268*ec779b8eSAndroid Build Coastguard Worker }
1269*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateBtLeParameters(AudioParameter & parameters)1270*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateBtLeParameters(AudioParameter &parameters) {
1271*ec779b8eSAndroid Build Coastguard Worker     std::optional<bool> leEnabled;
1272*ec779b8eSAndroid Build Coastguard Worker     std::optional<std::vector<VendorParameter>> reconfigureOffload;
1273*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1274*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtLeSuspended),
1275*ec779b8eSAndroid Build Coastguard Worker             [&leEnabled, this](const String8& trueOrFalse) {
1276*ec779b8eSAndroid Build Coastguard Worker                 if (trueOrFalse == AudioParameter::valueTrue) {
1277*ec779b8eSAndroid Build Coastguard Worker                     leEnabled = false;  // 'suspended' == true
1278*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1279*ec779b8eSAndroid Build Coastguard Worker                 } else if (trueOrFalse == AudioParameter::valueFalse) {
1280*ec779b8eSAndroid Build Coastguard Worker                     leEnabled = true;  // 'suspended' == false
1281*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1282*ec779b8eSAndroid Build Coastguard Worker                 }
1283*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1284*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtLeSuspended, trueOrFalse.c_str());
1285*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1286*ec779b8eSAndroid Build Coastguard Worker             }));
1287*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1288*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyReconfigLe),
1289*ec779b8eSAndroid Build Coastguard Worker             [&](const String8& value) -> status_t {
1290*ec779b8eSAndroid Build Coastguard Worker                 if (mVendorExt != nullptr) {
1291*ec779b8eSAndroid Build Coastguard Worker                     std::vector<VendorParameter> result;
1292*ec779b8eSAndroid Build Coastguard Worker                     RETURN_STATUS_IF_ERROR(
1293*ec779b8eSAndroid Build Coastguard Worker                             statusTFromBinderStatus(mVendorExt->parseBluetoothLeReconfigureOffload(
1294*ec779b8eSAndroid Build Coastguard Worker                                     std::string(value.c_str()), &result)));
1295*ec779b8eSAndroid Build Coastguard Worker                     reconfigureOffload = std::move(result);
1296*ec779b8eSAndroid Build Coastguard Worker                 } else {
1297*ec779b8eSAndroid Build Coastguard Worker                     reconfigureOffload = std::vector<VendorParameter>();
1298*ec779b8eSAndroid Build Coastguard Worker                 }
1299*ec779b8eSAndroid Build Coastguard Worker                 return OK;
1300*ec779b8eSAndroid Build Coastguard Worker             }));
1301*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1302*ec779b8eSAndroid Build Coastguard Worker     if (mBluetoothLe != nullptr && leEnabled.has_value()) {
1303*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mBluetoothLe->setEnabled(leEnabled.value()));
1304*ec779b8eSAndroid Build Coastguard Worker     }
1305*ec779b8eSAndroid Build Coastguard Worker     if (mBluetoothLe != nullptr && reconfigureOffload.has_value()) {
1306*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(
1307*ec779b8eSAndroid Build Coastguard Worker                 mBluetoothLe->reconfigureOffload(reconfigureOffload.value()));
1308*ec779b8eSAndroid Build Coastguard Worker     }
1309*ec779b8eSAndroid Build Coastguard Worker     return OK;
1310*ec779b8eSAndroid Build Coastguard Worker }
1311*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateBtScoParameters(AudioParameter & parameters)1312*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateBtScoParameters(AudioParameter &parameters) {
1313*ec779b8eSAndroid Build Coastguard Worker     IBluetooth::ScoConfig scoConfig;
1314*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1315*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtSco),
1316*ec779b8eSAndroid Build Coastguard Worker             [&scoConfig, this](const String8& onOrOff) {
1317*ec779b8eSAndroid Build Coastguard Worker                 if (onOrOff == AudioParameter::valueOn) {
1318*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.isEnabled = Boolean{.value = true};
1319*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1320*ec779b8eSAndroid Build Coastguard Worker                 } else if (onOrOff == AudioParameter::valueOff) {
1321*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.isEnabled = Boolean{.value = false};
1322*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1323*ec779b8eSAndroid Build Coastguard Worker                 }
1324*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1325*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtSco, onOrOff.c_str());
1326*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1327*ec779b8eSAndroid Build Coastguard Worker             }));
1328*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1329*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtScoHeadsetName),
1330*ec779b8eSAndroid Build Coastguard Worker             [&scoConfig](const String8& name) {
1331*ec779b8eSAndroid Build Coastguard Worker                 scoConfig.debugName = name;
1332*ec779b8eSAndroid Build Coastguard Worker                 return OK;
1333*ec779b8eSAndroid Build Coastguard Worker             }));
1334*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1335*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtNrec),
1336*ec779b8eSAndroid Build Coastguard Worker             [&scoConfig, this](const String8& onOrOff) {
1337*ec779b8eSAndroid Build Coastguard Worker                 if (onOrOff == AudioParameter::valueOn) {
1338*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.isNrecEnabled = Boolean{.value = true};
1339*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1340*ec779b8eSAndroid Build Coastguard Worker                 } else if (onOrOff == AudioParameter::valueOff) {
1341*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.isNrecEnabled = Boolean{.value = false};
1342*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1343*ec779b8eSAndroid Build Coastguard Worker                 }
1344*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1345*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtNrec, onOrOff.c_str());
1346*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1347*ec779b8eSAndroid Build Coastguard Worker             }));
1348*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1349*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyBtScoWb),
1350*ec779b8eSAndroid Build Coastguard Worker             [&scoConfig, this](const String8& onOrOff) {
1351*ec779b8eSAndroid Build Coastguard Worker                 if (onOrOff == AudioParameter::valueOn) {
1352*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.mode = IBluetooth::ScoConfig::Mode::SCO_WB;
1353*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1354*ec779b8eSAndroid Build Coastguard Worker                 } else if (onOrOff == AudioParameter::valueOff) {
1355*ec779b8eSAndroid Build Coastguard Worker                     scoConfig.mode = IBluetooth::ScoConfig::Mode::SCO;
1356*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1357*ec779b8eSAndroid Build Coastguard Worker                 }
1358*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1359*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyBtScoWb, onOrOff.c_str());
1360*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1361*ec779b8eSAndroid Build Coastguard Worker             }));
1362*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1363*ec779b8eSAndroid Build Coastguard Worker     if (mBluetooth != nullptr && scoConfig != IBluetooth::ScoConfig{}) {
1364*ec779b8eSAndroid Build Coastguard Worker         IBluetooth::ScoConfig newScoConfig;
1365*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mBluetooth->setScoConfig(scoConfig, &newScoConfig));
1366*ec779b8eSAndroid Build Coastguard Worker     }
1367*ec779b8eSAndroid Build Coastguard Worker     return OK;
1368*ec779b8eSAndroid Build Coastguard Worker }
1369*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateScreenParameters(AudioParameter & parameters)1370*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateScreenParameters(AudioParameter &parameters) {
1371*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1372*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyScreenState),
1373*ec779b8eSAndroid Build Coastguard Worker             [&, this](const String8& onOrOff) -> status_t {
1374*ec779b8eSAndroid Build Coastguard Worker                 std::optional<bool> isTurnedOn;
1375*ec779b8eSAndroid Build Coastguard Worker                 if (onOrOff == AudioParameter::valueOn) {
1376*ec779b8eSAndroid Build Coastguard Worker                     isTurnedOn = true;
1377*ec779b8eSAndroid Build Coastguard Worker                 } else if (onOrOff == AudioParameter::valueOff) {
1378*ec779b8eSAndroid Build Coastguard Worker                     isTurnedOn = false;
1379*ec779b8eSAndroid Build Coastguard Worker                 }
1380*ec779b8eSAndroid Build Coastguard Worker                 if (!isTurnedOn.has_value()) {
1381*ec779b8eSAndroid Build Coastguard Worker                     AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1382*ec779b8eSAndroid Build Coastguard Worker                                 AudioParameter::keyScreenState, onOrOff.c_str());
1383*ec779b8eSAndroid Build Coastguard Worker                     return BAD_VALUE;
1384*ec779b8eSAndroid Build Coastguard Worker                 }
1385*ec779b8eSAndroid Build Coastguard Worker                 std::lock_guard l(mLock);
1386*ec779b8eSAndroid Build Coastguard Worker                 return statusTFromBinderStatus(mModule->updateScreenState(isTurnedOn.value()));
1387*ec779b8eSAndroid Build Coastguard Worker             }));
1388*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
1389*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyScreenRotation),
1390*ec779b8eSAndroid Build Coastguard Worker             [&, this](int rotationDegrees) -> status_t {
1391*ec779b8eSAndroid Build Coastguard Worker                 IModule::ScreenRotation rotation;
1392*ec779b8eSAndroid Build Coastguard Worker                 switch (rotationDegrees) {
1393*ec779b8eSAndroid Build Coastguard Worker                     case 0:
1394*ec779b8eSAndroid Build Coastguard Worker                         rotation = IModule::ScreenRotation::DEG_0;
1395*ec779b8eSAndroid Build Coastguard Worker                         break;
1396*ec779b8eSAndroid Build Coastguard Worker                     case 90:
1397*ec779b8eSAndroid Build Coastguard Worker                         rotation = IModule::ScreenRotation::DEG_90;
1398*ec779b8eSAndroid Build Coastguard Worker                         break;
1399*ec779b8eSAndroid Build Coastguard Worker                     case 180:
1400*ec779b8eSAndroid Build Coastguard Worker                         rotation = IModule::ScreenRotation::DEG_180;
1401*ec779b8eSAndroid Build Coastguard Worker                         break;
1402*ec779b8eSAndroid Build Coastguard Worker                     case 270:
1403*ec779b8eSAndroid Build Coastguard Worker                         rotation = IModule::ScreenRotation::DEG_270;
1404*ec779b8eSAndroid Build Coastguard Worker                         break;
1405*ec779b8eSAndroid Build Coastguard Worker                     default:
1406*ec779b8eSAndroid Build Coastguard Worker                         AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value %d",
1407*ec779b8eSAndroid Build Coastguard Worker                                     AudioParameter::keyScreenRotation, rotationDegrees);
1408*ec779b8eSAndroid Build Coastguard Worker                         return BAD_VALUE;
1409*ec779b8eSAndroid Build Coastguard Worker                 }
1410*ec779b8eSAndroid Build Coastguard Worker                 std::lock_guard l(mLock);
1411*ec779b8eSAndroid Build Coastguard Worker                 return statusTFromBinderStatus(mModule->updateScreenRotation(rotation));
1412*ec779b8eSAndroid Build Coastguard Worker             }));
1413*ec779b8eSAndroid Build Coastguard Worker     return OK;
1414*ec779b8eSAndroid Build Coastguard Worker }
1415*ec779b8eSAndroid Build Coastguard Worker 
filterAndUpdateTelephonyParameters(AudioParameter & parameters)1416*ec779b8eSAndroid Build Coastguard Worker status_t DeviceHalAidl::filterAndUpdateTelephonyParameters(AudioParameter &parameters) {
1417*ec779b8eSAndroid Build Coastguard Worker     using TtyMode = ITelephony::TelecomConfig::TtyMode;
1418*ec779b8eSAndroid Build Coastguard Worker     ITelephony::TelecomConfig telConfig;
1419*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1420*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyTtyMode),
1421*ec779b8eSAndroid Build Coastguard Worker             [&telConfig, this](const String8& mode) {
1422*ec779b8eSAndroid Build Coastguard Worker                 if (mode == AudioParameter::valueTtyModeOff) {
1423*ec779b8eSAndroid Build Coastguard Worker                     telConfig.ttyMode = TtyMode::OFF;
1424*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1425*ec779b8eSAndroid Build Coastguard Worker                 } else if (mode == AudioParameter::valueTtyModeFull) {
1426*ec779b8eSAndroid Build Coastguard Worker                     telConfig.ttyMode = TtyMode::FULL;
1427*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1428*ec779b8eSAndroid Build Coastguard Worker                 } else if (mode == AudioParameter::valueTtyModeHco) {
1429*ec779b8eSAndroid Build Coastguard Worker                     telConfig.ttyMode = TtyMode::HCO;
1430*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1431*ec779b8eSAndroid Build Coastguard Worker                 } else if (mode == AudioParameter::valueTtyModeVco) {
1432*ec779b8eSAndroid Build Coastguard Worker                     telConfig.ttyMode = TtyMode::VCO;
1433*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1434*ec779b8eSAndroid Build Coastguard Worker                 }
1435*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1436*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyTtyMode, mode.c_str());
1437*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1438*ec779b8eSAndroid Build Coastguard Worker             }));
1439*ec779b8eSAndroid Build Coastguard Worker     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
1440*ec779b8eSAndroid Build Coastguard Worker             parameters, String8(AudioParameter::keyHacSetting),
1441*ec779b8eSAndroid Build Coastguard Worker             [&telConfig, this](const String8& onOrOff) {
1442*ec779b8eSAndroid Build Coastguard Worker                 if (onOrOff == AudioParameter::valueHacOn) {
1443*ec779b8eSAndroid Build Coastguard Worker                     telConfig.isHacEnabled = Boolean{.value = true};
1444*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1445*ec779b8eSAndroid Build Coastguard Worker                 } else if (onOrOff == AudioParameter::valueHacOff) {
1446*ec779b8eSAndroid Build Coastguard Worker                     telConfig.isHacEnabled = Boolean{.value = false};
1447*ec779b8eSAndroid Build Coastguard Worker                     return OK;
1448*ec779b8eSAndroid Build Coastguard Worker                 }
1449*ec779b8eSAndroid Build Coastguard Worker                 AUGMENT_LOG(E, "setParameters: parameter key \"%s\" has invalid value \"%s\"",
1450*ec779b8eSAndroid Build Coastguard Worker                             AudioParameter::keyHacSetting, onOrOff.c_str());
1451*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
1452*ec779b8eSAndroid Build Coastguard Worker             }));
1453*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mLock);
1454*ec779b8eSAndroid Build Coastguard Worker     if (mTelephony != nullptr && telConfig != ITelephony::TelecomConfig{}) {
1455*ec779b8eSAndroid Build Coastguard Worker         ITelephony::TelecomConfig newTelConfig;
1456*ec779b8eSAndroid Build Coastguard Worker         return statusTFromBinderStatus(mTelephony->setTelecomConfig(telConfig, &newTelConfig));
1457*ec779b8eSAndroid Build Coastguard Worker     }
1458*ec779b8eSAndroid Build Coastguard Worker     return OK;
1459*ec779b8eSAndroid Build Coastguard Worker }
1460*ec779b8eSAndroid Build Coastguard Worker 
clearCallbacks(void * cookie)1461*ec779b8eSAndroid Build Coastguard Worker void DeviceHalAidl::clearCallbacks(void* cookie) {
1462*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mCallbacksLock);
1463*ec779b8eSAndroid Build Coastguard Worker     mCallbacks.erase(cookie);
1464*ec779b8eSAndroid Build Coastguard Worker }
1465*ec779b8eSAndroid Build Coastguard Worker 
getStreamOutCallback(void * cookie)1466*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceCallback> DeviceHalAidl::getStreamOutCallback(void* cookie) {
1467*ec779b8eSAndroid Build Coastguard Worker     return getCallbackImpl(cookie, &Callbacks::out);
1468*ec779b8eSAndroid Build Coastguard Worker }
1469*ec779b8eSAndroid Build Coastguard Worker 
setStreamOutCallback(void * cookie,const sp<StreamOutHalInterfaceCallback> & cb)1470*ec779b8eSAndroid Build Coastguard Worker void DeviceHalAidl::setStreamOutCallback(
1471*ec779b8eSAndroid Build Coastguard Worker         void* cookie, const sp<StreamOutHalInterfaceCallback>& cb) {
1472*ec779b8eSAndroid Build Coastguard Worker     setCallbackImpl(cookie, &Callbacks::out, cb);
1473*ec779b8eSAndroid Build Coastguard Worker }
1474*ec779b8eSAndroid Build Coastguard Worker 
getStreamOutEventCallback(void * cookie)1475*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceEventCallback> DeviceHalAidl::getStreamOutEventCallback(
1476*ec779b8eSAndroid Build Coastguard Worker         void* cookie) {
1477*ec779b8eSAndroid Build Coastguard Worker     return getCallbackImpl(cookie, &Callbacks::event);
1478*ec779b8eSAndroid Build Coastguard Worker }
1479*ec779b8eSAndroid Build Coastguard Worker 
setStreamOutEventCallback(void * cookie,const sp<StreamOutHalInterfaceEventCallback> & cb)1480*ec779b8eSAndroid Build Coastguard Worker void DeviceHalAidl::setStreamOutEventCallback(
1481*ec779b8eSAndroid Build Coastguard Worker         void* cookie, const sp<StreamOutHalInterfaceEventCallback>& cb) {
1482*ec779b8eSAndroid Build Coastguard Worker     setCallbackImpl(cookie, &Callbacks::event, cb);
1483*ec779b8eSAndroid Build Coastguard Worker }
1484*ec779b8eSAndroid Build Coastguard Worker 
getStreamOutLatencyModeCallback(void * cookie)1485*ec779b8eSAndroid Build Coastguard Worker sp<StreamOutHalInterfaceLatencyModeCallback> DeviceHalAidl::getStreamOutLatencyModeCallback(
1486*ec779b8eSAndroid Build Coastguard Worker         void* cookie) {
1487*ec779b8eSAndroid Build Coastguard Worker     return getCallbackImpl(cookie, &Callbacks::latency);
1488*ec779b8eSAndroid Build Coastguard Worker }
1489*ec779b8eSAndroid Build Coastguard Worker 
setStreamOutLatencyModeCallback(void * cookie,const sp<StreamOutHalInterfaceLatencyModeCallback> & cb)1490*ec779b8eSAndroid Build Coastguard Worker void DeviceHalAidl::setStreamOutLatencyModeCallback(
1491*ec779b8eSAndroid Build Coastguard Worker         void* cookie, const sp<StreamOutHalInterfaceLatencyModeCallback>& cb) {
1492*ec779b8eSAndroid Build Coastguard Worker     setCallbackImpl(cookie, &Callbacks::latency, cb);
1493*ec779b8eSAndroid Build Coastguard Worker }
1494*ec779b8eSAndroid Build Coastguard Worker 
1495*ec779b8eSAndroid Build Coastguard Worker template <class C>
getCallbackImpl(void * cookie,wp<C> DeviceHalAidl::Callbacks::* field)1496*ec779b8eSAndroid Build Coastguard Worker sp<C> DeviceHalAidl::getCallbackImpl(void* cookie, wp<C> DeviceHalAidl::Callbacks::* field) {
1497*ec779b8eSAndroid Build Coastguard Worker     wp<C> result;
1498*ec779b8eSAndroid Build Coastguard Worker     {
1499*ec779b8eSAndroid Build Coastguard Worker         std::lock_guard l(mCallbacksLock);
1500*ec779b8eSAndroid Build Coastguard Worker         if (auto it = mCallbacks.find(cookie); it != mCallbacks.end()) {
1501*ec779b8eSAndroid Build Coastguard Worker             result = (it->second).*field;
1502*ec779b8eSAndroid Build Coastguard Worker         }
1503*ec779b8eSAndroid Build Coastguard Worker     }
1504*ec779b8eSAndroid Build Coastguard Worker     return result.promote();
1505*ec779b8eSAndroid Build Coastguard Worker }
1506*ec779b8eSAndroid Build Coastguard Worker template<class C>
setCallbackImpl(void * cookie,wp<C> DeviceHalAidl::Callbacks::* field,const sp<C> & cb)1507*ec779b8eSAndroid Build Coastguard Worker void DeviceHalAidl::setCallbackImpl(
1508*ec779b8eSAndroid Build Coastguard Worker         void* cookie, wp<C> DeviceHalAidl::Callbacks::* field, const sp<C>& cb) {
1509*ec779b8eSAndroid Build Coastguard Worker     std::lock_guard l(mCallbacksLock);
1510*ec779b8eSAndroid Build Coastguard Worker     if (auto it = mCallbacks.find(cookie); it != mCallbacks.end()) {
1511*ec779b8eSAndroid Build Coastguard Worker         (it->second).*field = cb;
1512*ec779b8eSAndroid Build Coastguard Worker     }
1513*ec779b8eSAndroid Build Coastguard Worker }
1514*ec779b8eSAndroid Build Coastguard Worker 
1515*ec779b8eSAndroid Build Coastguard Worker } // namespace android
1516