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