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 #include <log/log.h>
18 #include <system/audio.h>
19 #include "primary_device.h"
20 #include "stream_in.h"
21 #include "stream_out.h"
22 #include "util.h"
23 #include "debug.h"
24 
25 namespace android {
26 namespace hardware {
27 namespace audio {
28 namespace V6_0 {
29 namespace implementation {
30 
31 constexpr size_t kInBufferDurationMs = 15;
32 constexpr size_t kOutBufferDurationMs = 22;
33 
34 using ::android::hardware::Void;
35 
PrimaryDevice()36 PrimaryDevice::PrimaryDevice() {}
37 
initCheck()38 Return<Result> PrimaryDevice::initCheck() {
39     return Result::OK;
40 }
41 
setMasterVolume(float volume)42 Return<Result> PrimaryDevice::setMasterVolume(float volume) {
43     if (isnan(volume) || volume < 0 || volume > 1.0) {
44         return FAILURE(Result::INVALID_ARGUMENTS);
45     }
46 
47     mMasterVolume = volume;
48     updateOutputStreamVolume(mMasterMute ? 0.0f : volume);
49     return Result::OK;
50 }
51 
getMasterVolume(getMasterVolume_cb _hidl_cb)52 Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
53     _hidl_cb(Result::OK, mMasterVolume);
54     return Void();
55 }
56 
setMicMute(bool mute)57 Return<Result> PrimaryDevice::PrimaryDevice::setMicMute(bool mute) {
58     mMicMute = mute;
59     updateInputStreamMicMute(mute);
60     return Result::OK;
61 }
62 
getMicMute(getMicMute_cb _hidl_cb)63 Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
64     _hidl_cb(Result::OK, mMicMute);
65     return Void();
66 }
67 
setMasterMute(bool mute)68 Return<Result> PrimaryDevice::setMasterMute(bool mute) {
69     mMasterMute = mute;
70     updateOutputStreamVolume(mute ? 0.0f : mMasterVolume);
71     return Result::OK;
72 }
73 
getMasterMute(getMasterMute_cb _hidl_cb)74 Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
75     _hidl_cb(Result::OK, mMasterMute);
76     return Void();
77 }
78 
getInputBufferSize(const AudioConfig & config,getInputBufferSize_cb _hidl_cb)79 Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
80                                                getInputBufferSize_cb _hidl_cb) {
81     AudioConfig suggestedConfig;
82     if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
83         const size_t sz =
84             suggestedConfig.frameCount
85             * util::countChannels(suggestedConfig.channelMask)
86             * util::getBytesPerSample(suggestedConfig.format);
87 
88         _hidl_cb(Result::OK, sz);
89     } else {
90         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
91         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), 0);
92     }
93 
94     return Void();
95 }
96 
openOutputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,hidl_bitfield<AudioOutputFlag> flags,const SourceMetadata & sourceMetadata,openOutputStream_cb _hidl_cb)97 Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
98                                              const DeviceAddress& device,
99                                              const AudioConfig& config,
100                                              hidl_bitfield<AudioOutputFlag> flags,
101                                              const SourceMetadata& sourceMetadata,
102                                              openOutputStream_cb _hidl_cb) {
103     AudioConfig suggestedConfig;
104     if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) {
105         auto stream = std::make_unique<StreamOut>(
106             this, ioHandle, device, suggestedConfig, flags, sourceMetadata);
107 
108         stream->setMasterVolume(mMasterMute ? 0.0f : mMasterVolume);
109 
110         {
111             std::lock_guard<std::mutex> guard(mMutex);
112             LOG_ALWAYS_FATAL_IF(!mOutputStreams.insert(stream.get()).second);
113         }
114 
115         _hidl_cb(Result::OK, stream.release(), config);
116     } else {
117         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
118         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig);
119     }
120 
121     return Void();
122 }
123 
openInputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,hidl_bitfield<AudioInputFlag> flags,const SinkMetadata & sinkMetadata,openInputStream_cb _hidl_cb)124 Return<void> PrimaryDevice::openInputStream(int32_t ioHandle,
125                                             const DeviceAddress& device,
126                                             const AudioConfig& config,
127                                             hidl_bitfield<AudioInputFlag> flags,
128                                             const SinkMetadata& sinkMetadata,
129                                             openInputStream_cb _hidl_cb) {
130     AudioConfig suggestedConfig;
131     if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
132         auto stream = std::make_unique<StreamIn>(
133             this, ioHandle, device, suggestedConfig, flags, sinkMetadata);
134 
135         stream->setMicMute(mMicMute);
136 
137         {
138             std::lock_guard<std::mutex> guard(mMutex);
139             LOG_ALWAYS_FATAL_IF(!mInputStreams.insert(stream.get()).second);
140         }
141 
142         _hidl_cb(Result::OK, stream.release(), config);
143     } else {
144         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
145         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig);
146     }
147 
148     return Void();
149 }
150 
supportsAudioPatches()151 Return<bool> PrimaryDevice::supportsAudioPatches() {
152     return true;
153 }
154 
createAudioPatch(const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,createAudioPatch_cb _hidl_cb)155 Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
156                                              const hidl_vec<AudioPortConfig>& sinks,
157                                              createAudioPatch_cb _hidl_cb) {
158     if (sources.size() == 1 && sinks.size() == 1) {
159         AudioPatch patch;
160         patch.source = sources[0];
161         patch.sink = sinks[0];
162 
163         AudioPatchHandle handle;
164         while (true) {
165             handle = mNextAudioPatchHandle;
166             mNextAudioPatchHandle = std::max(handle + 1, 0);
167             if (mAudioPatches.insert({handle, patch}).second) {
168                 break;
169             }
170         }
171 
172         _hidl_cb(Result::OK, handle);
173     } else {
174         _hidl_cb(FAILURE(Result::NOT_SUPPORTED), 0);
175     }
176 
177     return Void();
178 }
179 
releaseAudioPatch(AudioPatchHandle patchHandle)180 Return<Result> PrimaryDevice::releaseAudioPatch(AudioPatchHandle patchHandle) {
181     return (mAudioPatches.erase(patchHandle) == 1) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
182 }
183 
getAudioPort(const AudioPort & port,getAudioPort_cb _hidl_cb)184 Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
185     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), port);
186     return Void();
187 }
188 
setAudioPortConfig(const AudioPortConfig & config)189 Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
190     (void)config;
191     return FAILURE(Result::NOT_SUPPORTED);
192 }
193 
setScreenState(bool turnedOn)194 Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
195     (void)turnedOn;
196     return Result::OK;
197 }
198 
getHwAvSync(getHwAvSync_cb _hidl_cb)199 Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
200     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
201     return Void();
202 }
203 
getParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<hidl_string> & keys,getParameters_cb _hidl_cb)204 Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
205                                           const hidl_vec<hidl_string>& keys,
206                                           getParameters_cb _hidl_cb) {
207     (void)context;
208     if (keys.size() == 0) {
209         _hidl_cb(Result::OK, {});
210     } else {
211         _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
212     }
213     return Void();
214 }
215 
setParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<ParameterValue> & parameters)216 Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
217                                             const hidl_vec<ParameterValue>& parameters) {
218     (void)context;
219     (void)parameters;
220     return Result::OK;
221 }
222 
getMicrophones(getMicrophones_cb _hidl_cb)223 Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
224     _hidl_cb(Result::OK, {util::getMicrophoneInfo()});
225     return Void();
226 }
227 
setConnectedState(const DeviceAddress & dev_addr,bool connected)228 Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
229     (void)dev_addr;
230     (void)connected;
231     return FAILURE(Result::NOT_SUPPORTED);
232 }
233 
close()234 Return<Result> PrimaryDevice::close() {
235     std::lock_guard<std::mutex> guard(mMutex);
236 
237     return (mInputStreams.empty() && mOutputStreams.empty())
238         ? Result::OK : FAILURE(Result::INVALID_STATE);
239 }
240 
addDeviceEffect(AudioPortHandle device,uint64_t effectId)241 Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
242     (void)device;
243     (void)effectId;
244     return FAILURE(Result::NOT_SUPPORTED);
245 }
246 
removeDeviceEffect(AudioPortHandle device,uint64_t effectId)247 Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
248     (void)device;
249     (void)effectId;
250     return FAILURE(Result::NOT_SUPPORTED);
251 }
252 
setVoiceVolume(float volume)253 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
254     return (volume >= 0 && volume <= 1.0) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
255 }
256 
setMode(AudioMode mode)257 Return<Result> PrimaryDevice::setMode(AudioMode mode) {
258     switch (mode) {
259     case AudioMode::NORMAL:
260     case AudioMode::RINGTONE:
261     case AudioMode::IN_CALL:
262     case AudioMode::IN_COMMUNICATION:
263         return Result::OK;
264 
265     default:
266         return FAILURE(Result::INVALID_ARGUMENTS);
267     }
268 }
269 
setBtScoHeadsetDebugName(const hidl_string & name)270 Return<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
271     (void)name;
272     return FAILURE(Result::NOT_SUPPORTED);
273 }
274 
getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb)275 Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
276     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
277     return Void();
278 }
279 
setBtScoNrecEnabled(bool enabled)280 Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
281     (void)enabled;
282     return FAILURE(Result::NOT_SUPPORTED);
283 }
284 
getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb)285 Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) {
286     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
287     return Void();
288 }
289 
setBtScoWidebandEnabled(bool enabled)290 Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
291     (void)enabled;
292     return FAILURE(Result::NOT_SUPPORTED);
293 }
294 
getTtyMode(getTtyMode_cb _hidl_cb)295 Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
296     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), TtyMode::OFF);
297     return Void();
298 }
299 
setTtyMode(IPrimaryDevice::TtyMode mode)300 Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
301     (void)mode;
302     return FAILURE(Result::NOT_SUPPORTED);
303 }
304 
getHacEnabled(getHacEnabled_cb _hidl_cb)305 Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
306     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
307     return Void();
308 }
309 
setHacEnabled(bool enabled)310 Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
311     (void)enabled;
312     return FAILURE(Result::NOT_SUPPORTED);
313 }
314 
getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb)315 Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) {
316     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
317     return Void();
318 }
319 
setBtHfpEnabled(bool enabled)320 Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) {
321     (void)enabled;
322     return FAILURE(Result::NOT_SUPPORTED);
323 }
324 
setBtHfpSampleRate(uint32_t sampleRateHz)325 Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
326     (void)sampleRateHz;
327     return FAILURE(Result::NOT_SUPPORTED);
328 }
329 
setBtHfpVolume(float volume)330 Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
331     (void)volume;
332     return FAILURE(Result::NOT_SUPPORTED);
333 }
334 
updateRotation(IPrimaryDevice::Rotation rotation)335 Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
336     (void)rotation;
337     return FAILURE(Result::NOT_SUPPORTED);
338 }
339 
unrefDevice(StreamIn * sin)340 void PrimaryDevice::unrefDevice(StreamIn *sin) {
341     std::lock_guard<std::mutex> guard(mMutex);
342     LOG_ALWAYS_FATAL_IF(mInputStreams.erase(sin) < 1);
343 }
344 
unrefDevice(StreamOut * sout)345 void PrimaryDevice::unrefDevice(StreamOut *sout) {
346     std::lock_guard<std::mutex> guard(mMutex);
347     LOG_ALWAYS_FATAL_IF(mOutputStreams.erase(sout) < 1);
348 }
349 
updateOutputStreamVolume(float masterVolume) const350 void PrimaryDevice::updateOutputStreamVolume(float masterVolume) const {
351     std::lock_guard<std::mutex> guard(mMutex);
352     for (StreamOut *stream : mOutputStreams) {
353         stream->setMasterVolume(masterVolume);
354     }
355 }
356 
updateInputStreamMicMute(bool micMute) const357 void PrimaryDevice::updateInputStreamMicMute(bool micMute) const {
358     std::lock_guard<std::mutex> guard(mMutex);
359     for (StreamIn *stream : mInputStreams) {
360         stream->setMicMute(micMute);
361     }
362 }
363 
364 }  // namespace implementation
365 }  // namespace V6_0
366 }  // namespace audio
367 }  // namespace hardware
368 }  // namespace android
369