1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "PrimaryDeviceHAL"
18 
19 #include "core/default/PrimaryDevice.h"
20 #include "core/default/Util.h"
21 
22 #if MAJOR_VERSION >= 4
23 #include <cmath>
24 #endif
25 
26 namespace android {
27 namespace hardware {
28 namespace audio {
29 namespace CPP_VERSION {
30 namespace implementation {
31 
32 namespace util {
33 using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util;
34 }
35 
PrimaryDevice(audio_hw_device_t * device)36 PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
37 
~PrimaryDevice()38 PrimaryDevice::~PrimaryDevice() {
39     // Do not call mDevice->close here. If there are any unclosed streams,
40     // they only hold IDevice instance, not IPrimaryDevice, thus IPrimaryDevice
41     // "part" of a device can be destroyed before the streams.
42 }
43 
44 // Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
initCheck()45 Return<Result> PrimaryDevice::initCheck() {
46     return mDevice->initCheck();
47 }
48 
setMasterVolume(float volume)49 Return<Result> PrimaryDevice::setMasterVolume(float volume) {
50     return mDevice->setMasterVolume(volume);
51 }
52 
getMasterVolume(getMasterVolume_cb _hidl_cb)53 Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
54     return mDevice->getMasterVolume(_hidl_cb);
55 }
56 
setMicMute(bool mute)57 Return<Result> PrimaryDevice::setMicMute(bool mute) {
58     return mDevice->setMicMute(mute);
59 }
60 
getMicMute(getMicMute_cb _hidl_cb)61 Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
62     return mDevice->getMicMute(_hidl_cb);
63 }
64 
setMasterMute(bool mute)65 Return<Result> PrimaryDevice::setMasterMute(bool mute) {
66     return mDevice->setMasterMute(mute);
67 }
68 
getMasterMute(getMasterMute_cb _hidl_cb)69 Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
70     return mDevice->getMasterMute(_hidl_cb);
71 }
72 
getInputBufferSize(const AudioConfig & config,getInputBufferSize_cb _hidl_cb)73 Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
74                                                getInputBufferSize_cb _hidl_cb) {
75     return mDevice->getInputBufferSize(config, _hidl_cb);
76 }
77 
78 #if MAJOR_VERSION == 2
openOutputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioOutputFlags flags,openOutputStream_cb _hidl_cb)79 Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
80                                              const AudioConfig& config, AudioOutputFlags flags,
81                                              openOutputStream_cb _hidl_cb) {
82     return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb);
83 }
84 
openInputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioInputFlags flags,AudioSource source,openInputStream_cb _hidl_cb)85 Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
86                                             const AudioConfig& config, AudioInputFlags flags,
87                                             AudioSource source, openInputStream_cb _hidl_cb) {
88     return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
89 }
90 #elif MAJOR_VERSION >= 4
openOutputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioOutputFlags flags,const SourceMetadata & sourceMetadata,openOutputStream_cb _hidl_cb)91 Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
92                                              const AudioConfig& config,
93 #if MAJOR_VERSION <= 6
94                                              AudioOutputFlags flags,
95 #else
96                                              const AudioOutputFlags& flags,
97 #endif
98                                              const SourceMetadata& sourceMetadata,
99                                              openOutputStream_cb _hidl_cb) {
100     return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb);
101 }
102 
openInputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioInputFlags flags,const SinkMetadata & sinkMetadata,openInputStream_cb _hidl_cb)103 Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
104                                             const AudioConfig& config,
105 #if MAJOR_VERSION <= 6
106                                             AudioInputFlags flags,
107 #else
108                                             const AudioInputFlags& flags,
109 #endif
110                                             const SinkMetadata& sinkMetadata,
111                                             openInputStream_cb _hidl_cb) {
112     return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb);
113 }
114 #endif
115 
supportsAudioPatches()116 Return<bool> PrimaryDevice::supportsAudioPatches() {
117     return mDevice->supportsAudioPatches();
118 }
119 
createAudioPatch(const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,createAudioPatch_cb _hidl_cb)120 Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
121                                              const hidl_vec<AudioPortConfig>& sinks,
122                                              createAudioPatch_cb _hidl_cb) {
123     return mDevice->createAudioPatch(sources, sinks, _hidl_cb);
124 }
125 
releaseAudioPatch(int32_t patch)126 Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch) {
127     return mDevice->releaseAudioPatch(patch);
128 }
129 
getAudioPort(const AudioPort & port,getAudioPort_cb _hidl_cb)130 Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
131     return mDevice->getAudioPort(port, _hidl_cb);
132 }
133 
setAudioPortConfig(const AudioPortConfig & config)134 Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
135     return mDevice->setAudioPortConfig(config);
136 }
137 
setScreenState(bool turnedOn)138 Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
139     return mDevice->setScreenState(turnedOn);
140 }
141 
142 #if MAJOR_VERSION == 2
getHwAvSync()143 Return<AudioHwSync> PrimaryDevice::getHwAvSync() {
144     return mDevice->getHwAvSync();
145 }
146 
getParameters(const hidl_vec<hidl_string> & keys,getParameters_cb _hidl_cb)147 Return<void> PrimaryDevice::getParameters(const hidl_vec<hidl_string>& keys,
148                                           getParameters_cb _hidl_cb) {
149     return mDevice->getParameters(keys, _hidl_cb);
150 }
151 
setParameters(const hidl_vec<ParameterValue> & parameters)152 Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& parameters) {
153     return mDevice->setParameters(parameters);
154 }
155 
debugDump(const hidl_handle & fd)156 Return<void> PrimaryDevice::debugDump(const hidl_handle& fd) {
157     return mDevice->debugDump(fd);
158 }
159 #elif MAJOR_VERSION >= 4
getHwAvSync(getHwAvSync_cb _hidl_cb)160 Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
161     return mDevice->getHwAvSync(_hidl_cb);
162 }
getParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<hidl_string> & keys,getParameters_cb _hidl_cb)163 Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
164                                           const hidl_vec<hidl_string>& keys,
165                                           getParameters_cb _hidl_cb) {
166     return mDevice->getParameters(context, keys, _hidl_cb);
167 }
setParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<ParameterValue> & parameters)168 Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
169                                             const hidl_vec<ParameterValue>& parameters) {
170     return mDevice->setParameters(context, parameters);
171 }
getMicrophones(getMicrophones_cb _hidl_cb)172 Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
173     return mDevice->getMicrophones(_hidl_cb);
174 }
setConnectedState(const DeviceAddress & address,bool connected)175 Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& address, bool connected) {
176     return mDevice->setConnectedState(address, connected);
177 }
178 #endif
179 #if MAJOR_VERSION >= 6
close()180 Return<Result> PrimaryDevice::close() {
181     return mDevice->close();
182 }
183 
addDeviceEffect(AudioPortHandle device,uint64_t effectId)184 Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
185     return mDevice->addDeviceEffect(device, effectId);
186 }
187 
removeDeviceEffect(AudioPortHandle device,uint64_t effectId)188 Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
189     return mDevice->removeDeviceEffect(device, effectId);
190 }
191 
updateAudioPatch(int32_t previousPatch,const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,updateAudioPatch_cb _hidl_cb)192 Return<void> PrimaryDevice::updateAudioPatch(int32_t previousPatch,
193                                              const hidl_vec<AudioPortConfig>& sources,
194                                              const hidl_vec<AudioPortConfig>& sinks,
195                                              updateAudioPatch_cb _hidl_cb) {
196     return mDevice->updateAudioPatch(previousPatch, sources, sinks, _hidl_cb);
197 }
198 #endif
199 
200 // Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
setVoiceVolume(float volume)201 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
202     if (!util::isGainNormalized(volume)) {
203         ALOGW("Can not set a voice volume (%f) outside [0,1]", volume);
204         return Result::INVALID_ARGUMENTS;
205     }
206     return mDevice->analyzeStatus("set_voice_volume",
207                                   mDevice->device()->set_voice_volume(mDevice->device(), volume));
208 }
209 
setMode(AudioMode mode)210 Return<Result> PrimaryDevice::setMode(AudioMode mode) {
211     // INVALID, CURRENT, CNT, MAX are reserved for internal use.
212     // TODO: remove the values from the HIDL interface
213     switch (mode) {
214         case AudioMode::NORMAL:
215         case AudioMode::RINGTONE:
216         case AudioMode::IN_CALL:
217         case AudioMode::IN_COMMUNICATION:
218 #if MAJOR_VERSION >= 6
219         case AudioMode::CALL_SCREEN:
220 #endif
221             break;  // Valid values
222         default:
223             return Result::INVALID_ARGUMENTS;
224     };
225 
226     return mDevice->analyzeStatus(
227         "set_mode",
228         mDevice->device()->set_mode(mDevice->device(), static_cast<audio_mode_t>(mode)));
229 }
230 
getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb)231 Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
232     bool enabled;
233     Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled);
234     _hidl_cb(retval, enabled);
235     return Void();
236 }
237 
setBtScoNrecEnabled(bool enabled)238 Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
239     return mDevice->setParam(AudioParameter::keyBtNrec, enabled);
240 }
241 
getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb)242 Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) {
243     bool enabled;
244     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, &enabled);
245     _hidl_cb(retval, enabled);
246     return Void();
247 }
248 
setBtScoWidebandEnabled(bool enabled)249 Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
250     return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled);
251 }
252 
convertTtyModeFromHIDL(IPrimaryDevice::TtyMode mode)253 static const char* convertTtyModeFromHIDL(IPrimaryDevice::TtyMode mode) {
254     switch (mode) {
255         case IPrimaryDevice::TtyMode::OFF:
256             return AUDIO_PARAMETER_VALUE_TTY_OFF;
257         case IPrimaryDevice::TtyMode::VCO:
258             return AUDIO_PARAMETER_VALUE_TTY_VCO;
259         case IPrimaryDevice::TtyMode::HCO:
260             return AUDIO_PARAMETER_VALUE_TTY_HCO;
261         case IPrimaryDevice::TtyMode::FULL:
262             return AUDIO_PARAMETER_VALUE_TTY_FULL;
263         default:
264             return nullptr;
265     }
266 }
convertTtyModeToHIDL(const char * halMode)267 static IPrimaryDevice::TtyMode convertTtyModeToHIDL(const char* halMode) {
268     if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
269         return IPrimaryDevice::TtyMode::OFF;
270     else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
271         return IPrimaryDevice::TtyMode::VCO;
272     else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
273         return IPrimaryDevice::TtyMode::HCO;
274     else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
275         return IPrimaryDevice::TtyMode::FULL;
276     return IPrimaryDevice::TtyMode(-1);
277 }
278 
getTtyMode(getTtyMode_cb _hidl_cb)279 Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
280     String8 halMode;
281     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode);
282     if (retval != Result::OK) {
283         _hidl_cb(retval, TtyMode::OFF);
284         return Void();
285     }
286     TtyMode mode = convertTtyModeToHIDL(halMode.c_str());
287     if (mode == TtyMode(-1)) {
288         ALOGE("HAL returned invalid TTY value: %s", halMode.c_str());
289         _hidl_cb(Result::INVALID_STATE, TtyMode::OFF);
290         return Void();
291     }
292     _hidl_cb(Result::OK, mode);
293     return Void();
294 }
295 
setTtyMode(IPrimaryDevice::TtyMode mode)296 Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
297     const char* modeStr = convertTtyModeFromHIDL(mode);
298     if (modeStr == nullptr) {
299         ALOGW("Can not set an invalid TTY value: %d", mode);
300         return Result::INVALID_ARGUMENTS;
301     }
302     return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, modeStr);
303 }
304 
getHacEnabled(getHacEnabled_cb _hidl_cb)305 Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
306     bool enabled;
307     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled);
308     _hidl_cb(retval, enabled);
309     return Void();
310 }
311 
setHacEnabled(bool enabled)312 Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
313     return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled);
314 }
315 
316 #if MAJOR_VERSION >= 4
setBtScoHeadsetDebugName(const hidl_string & name)317 Return<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
318     return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME, name.c_str());
319 }
getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb)320 Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) {
321     bool enabled;
322     Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, &enabled);
323     _hidl_cb(retval, enabled);
324     return Void();
325 }
setBtHfpEnabled(bool enabled)326 Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) {
327     return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, enabled);
328 }
setBtHfpSampleRate(uint32_t sampleRateHz)329 Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
330     return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz));
331 }
setBtHfpVolume(float volume)332 Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
333     if (!util::isGainNormalized(volume)) {
334         ALOGW("Can not set BT HFP volume (%f) outside [0,1]", volume);
335         return Result::INVALID_ARGUMENTS;
336     }
337     // Map the normalized volume onto the range of [0, 15]
338     return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_VOLUME,
339                              static_cast<int>(std::round(volume * 15)));
340 }
updateRotation(IPrimaryDevice::Rotation rotation)341 Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
342     // legacy API expects the rotation in degree
343     return mDevice->setParam(AUDIO_PARAMETER_KEY_ROTATION, int(rotation) * 90);
344 }
345 #endif
346 
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & options)347 Return<void> PrimaryDevice::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
348     return mDevice->debug(fd, options);
349 }
350 
351 }  // namespace implementation
352 }  // namespace CPP_VERSION
353 }  // namespace audio
354 }  // namespace hardware
355 }  // namespace android
356