• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         : mMixer(talsa::mixerOpen(talsa::kPcmDevice)) {
38     if (mMixer) {
39         mMixerMasterVolumeCtl = mixer_get_ctl_by_name(mMixer.get(), "Master Playback Volume");
40         mMixerCaptureVolumeCtl = mixer_get_ctl_by_name(mMixer.get(), "Capture Volume");
41         mMixerMasterPaybackSwitchCtl = mixer_get_ctl_by_name(mMixer.get(), "Master Playback Switch");
42         mMixerCaptureSwitchCtl = mixer_get_ctl_by_name(mMixer.get(), "Capture Switch");
43 
44         talsa::mixerSetPercentAll(mMixerMasterVolumeCtl, 100);
45         talsa::mixerSetPercentAll(mMixerCaptureVolumeCtl, 100);
46         talsa::mixerSetValueAll(mMixerMasterPaybackSwitchCtl, 1);
47         talsa::mixerSetValueAll(mMixerCaptureSwitchCtl, 1);
48     }
49 }
50 
initCheck()51 Return<Result> PrimaryDevice::initCheck() {
52     return mMixer ? Result::OK : FAILURE(Result::NOT_INITIALIZED);
53 }
54 
setMasterVolume(float volume)55 Return<Result> PrimaryDevice::setMasterVolume(float volume) {
56     if (isnan(volume) || volume < 0 || volume > 1.0) {
57         return FAILURE(Result::INVALID_ARGUMENTS);
58     }
59 
60     if (!mMixerMasterVolumeCtl) {
61         return FAILURE(Result::INVALID_STATE);
62     }
63 
64     talsa::mixerSetPercentAll(mMixerMasterVolumeCtl, int(100 * volume));
65     mMasterVolume = volume;
66     return Result::OK;
67 }
68 
getMasterVolume(getMasterVolume_cb _hidl_cb)69 Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
70     if (mMixerMasterVolumeCtl) {
71         _hidl_cb(Result::OK, mMasterVolume);
72     } else {
73         _hidl_cb(FAILURE(Result::INVALID_STATE), 0);
74     }
75 
76     return Void();
77 }
78 
setMicMute(bool mute)79 Return<Result> PrimaryDevice::PrimaryDevice::setMicMute(bool mute) {
80     if (mMixerCaptureSwitchCtl) {
81         talsa::mixerSetValueAll(mMixerCaptureSwitchCtl, mute ? 0 : 1);
82         return Result::OK;
83     } else {
84         return FAILURE(Result::INVALID_STATE);
85     }
86 }
87 
getMicMute(getMicMute_cb _hidl_cb)88 Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
89     if (mMixerCaptureSwitchCtl) {
90         const int value = mixer_ctl_get_value(mMixerCaptureSwitchCtl, 0);
91         _hidl_cb(Result::OK, value == 0);
92     } else {
93         _hidl_cb(FAILURE(Result::INVALID_STATE), 0);
94     }
95     return Void();
96 }
97 
setMasterMute(bool mute)98 Return<Result> PrimaryDevice::setMasterMute(bool mute) {
99     if (mMixerMasterPaybackSwitchCtl) {
100         talsa::mixerSetValueAll(mMixerMasterPaybackSwitchCtl, mute ? 0 : 1);
101         return Result::OK;
102     } else {
103         return FAILURE(Result::INVALID_STATE);
104     }
105 }
106 
getMasterMute(getMasterMute_cb _hidl_cb)107 Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
108     if (mMixerMasterPaybackSwitchCtl) {
109         const int value = mixer_ctl_get_value(mMixerMasterPaybackSwitchCtl, 0);
110         _hidl_cb(Result::OK, value == 0);
111     } else {
112         _hidl_cb(FAILURE(Result::NOT_SUPPORTED), 0);
113     }
114 
115     return Void();
116 }
117 
getInputBufferSize(const AudioConfig & config,getInputBufferSize_cb _hidl_cb)118 Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config,
119                                                getInputBufferSize_cb _hidl_cb) {
120     AudioConfig suggestedConfig;
121     if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
122         const size_t sz =
123             suggestedConfig.frameCount
124             * util::countChannels(suggestedConfig.channelMask)
125             * util::getBytesPerSample(suggestedConfig.format);
126 
127         _hidl_cb(Result::OK, sz);
128     } else {
129         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
130         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), 0);
131     }
132 
133     return Void();
134 }
135 
openOutputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,hidl_bitfield<AudioOutputFlag> flags,const SourceMetadata & sourceMetadata,openOutputStream_cb _hidl_cb)136 Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
137                                              const DeviceAddress& device,
138                                              const AudioConfig& config,
139                                              hidl_bitfield<AudioOutputFlag> flags,
140                                              const SourceMetadata& sourceMetadata,
141                                              openOutputStream_cb _hidl_cb) {
142     AudioConfig suggestedConfig;
143     if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) {
144         ++mNStreams;
145         _hidl_cb(Result::OK,
146                  new StreamOut(this, &unrefDevice,
147                                ioHandle, device, suggestedConfig, flags, sourceMetadata),
148                  config);
149     } else {
150         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
151         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig);
152     }
153 
154     return Void();
155 }
156 
openInputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,hidl_bitfield<AudioInputFlag> flags,const SinkMetadata & sinkMetadata,openInputStream_cb _hidl_cb)157 Return<void> PrimaryDevice::openInputStream(int32_t ioHandle,
158                                             const DeviceAddress& device,
159                                             const AudioConfig& config,
160                                             hidl_bitfield<AudioInputFlag> flags,
161                                             const SinkMetadata& sinkMetadata,
162                                             openInputStream_cb _hidl_cb) {
163     AudioConfig suggestedConfig;
164     if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
165         ++mNStreams;
166         _hidl_cb(Result::OK,
167                  new StreamIn(this, &unrefDevice,
168                               ioHandle, device, suggestedConfig, flags, sinkMetadata),
169                  config);
170     } else {
171         ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__);
172         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig);
173     }
174 
175     return Void();
176 }
177 
supportsAudioPatches()178 Return<bool> PrimaryDevice::supportsAudioPatches() {
179     return true;
180 }
181 
createAudioPatch(const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,createAudioPatch_cb _hidl_cb)182 Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
183                                              const hidl_vec<AudioPortConfig>& sinks,
184                                              createAudioPatch_cb _hidl_cb) {
185     if (sources.size() == 1 && sinks.size() == 1) {
186         AudioPatch patch;
187         patch.source = sources[0];
188         patch.sink = sinks[0];
189 
190         AudioPatchHandle handle;
191         while (true) {
192             handle = mNextAudioPatchHandle;
193             mNextAudioPatchHandle = std::max(handle + 1, 0);
194             if (mAudioPatches.insert({handle, patch}).second) {
195                 break;
196             }
197         }
198 
199         _hidl_cb(Result::OK, handle);
200     } else {
201         _hidl_cb(FAILURE(Result::NOT_SUPPORTED), 0);
202     }
203 
204     return Void();
205 }
206 
updateAudioPatch(AudioPatchHandle previousPatchHandle,const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,updateAudioPatch_cb _hidl_cb)207 Return<void> PrimaryDevice::updateAudioPatch(AudioPatchHandle previousPatchHandle,
208                                              const hidl_vec<AudioPortConfig>& sources,
209                                              const hidl_vec<AudioPortConfig>& sinks,
210                                              updateAudioPatch_cb _hidl_cb) {
211     const auto i = mAudioPatches.find(previousPatchHandle);
212     if (i == mAudioPatches.end()) {
213         _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), previousPatchHandle);
214     } else {
215         if (sources.size() == 1 && sinks.size() == 1) {
216             AudioPatch patch;
217             patch.source = sources[0];
218             patch.sink = sinks[0];
219             i->second = patch;
220 
221             _hidl_cb(Result::OK, previousPatchHandle);
222         } else {
223             _hidl_cb(Result::NOT_SUPPORTED, previousPatchHandle);
224         }
225     }
226 
227     return Void();
228 }
229 
releaseAudioPatch(AudioPatchHandle patchHandle)230 Return<Result> PrimaryDevice::releaseAudioPatch(AudioPatchHandle patchHandle) {
231     return (mAudioPatches.erase(patchHandle) == 1) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
232 }
233 
getAudioPort(const AudioPort & port,getAudioPort_cb _hidl_cb)234 Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
235     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), port);
236     return Void();
237 }
238 
setAudioPortConfig(const AudioPortConfig & config)239 Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
240     (void)config;
241     return FAILURE(Result::NOT_SUPPORTED);
242 }
243 
setScreenState(bool turnedOn)244 Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
245     (void)turnedOn;
246     return Result::OK;
247 }
248 
getHwAvSync(getHwAvSync_cb _hidl_cb)249 Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
250     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
251     return Void();
252 }
253 
getParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<hidl_string> & keys,getParameters_cb _hidl_cb)254 Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
255                                           const hidl_vec<hidl_string>& keys,
256                                           getParameters_cb _hidl_cb) {
257     (void)context;
258     if (keys.size() == 0) {
259         _hidl_cb(Result::OK, {});
260     } else {
261         _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
262     }
263     return Void();
264 }
265 
setParameters(const hidl_vec<ParameterValue> & context,const hidl_vec<ParameterValue> & parameters)266 Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
267                                             const hidl_vec<ParameterValue>& parameters) {
268     (void)context;
269     (void)parameters;
270     return Result::OK;
271 }
272 
getMicrophones(getMicrophones_cb _hidl_cb)273 Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
274     _hidl_cb(Result::OK, {util::getMicrophoneInfo()});
275     return Void();
276 }
277 
setConnectedState(const DeviceAddress & dev_addr,bool connected)278 Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
279     (void)dev_addr;
280     (void)connected;
281     return FAILURE(Result::NOT_SUPPORTED);
282 }
283 
close()284 Return<Result> PrimaryDevice::close() {
285     if (mNStreams > 0) {
286         return FAILURE(Result::INVALID_STATE);
287     } else if (mMixer) {
288         mMixerMasterVolumeCtl = nullptr;
289         mMixerCaptureVolumeCtl = nullptr;
290         mMixerMasterPaybackSwitchCtl = nullptr;
291         mMixerCaptureSwitchCtl = nullptr;
292         mMixer.reset();
293         return Result::OK;
294     } else {
295         return FAILURE(Result::INVALID_STATE);
296     }
297 }
298 
addDeviceEffect(AudioPortHandle device,uint64_t effectId)299 Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
300     (void)device;
301     (void)effectId;
302     return FAILURE(Result::NOT_SUPPORTED);
303 }
304 
removeDeviceEffect(AudioPortHandle device,uint64_t effectId)305 Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
306     (void)device;
307     (void)effectId;
308     return FAILURE(Result::NOT_SUPPORTED);
309 }
310 
setVoiceVolume(float volume)311 Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
312     return (volume >= 0 && volume <= 1.0) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
313 }
314 
setMode(AudioMode mode)315 Return<Result> PrimaryDevice::setMode(AudioMode mode) {
316     switch (mode) {
317     case AudioMode::NORMAL:
318     case AudioMode::RINGTONE:
319     case AudioMode::IN_CALL:
320     case AudioMode::IN_COMMUNICATION:
321         return Result::OK;
322 
323     default:
324         return FAILURE(Result::INVALID_ARGUMENTS);
325     }
326 }
327 
setBtScoHeadsetDebugName(const hidl_string & name)328 Return<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
329     (void)name;
330     return FAILURE(Result::NOT_SUPPORTED);
331 }
332 
getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb)333 Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
334     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
335     return Void();
336 }
337 
setBtScoNrecEnabled(bool enabled)338 Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
339     (void)enabled;
340     return FAILURE(Result::NOT_SUPPORTED);
341 }
342 
getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb)343 Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) {
344     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
345     return Void();
346 }
347 
setBtScoWidebandEnabled(bool enabled)348 Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
349     (void)enabled;
350     return FAILURE(Result::NOT_SUPPORTED);
351 }
352 
getTtyMode(getTtyMode_cb _hidl_cb)353 Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
354     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), TtyMode::OFF);
355     return Void();
356 }
357 
setTtyMode(IPrimaryDevice::TtyMode mode)358 Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
359     (void)mode;
360     return FAILURE(Result::NOT_SUPPORTED);
361 }
362 
getHacEnabled(getHacEnabled_cb _hidl_cb)363 Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
364     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
365     return Void();
366 }
367 
setHacEnabled(bool enabled)368 Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
369     (void)enabled;
370     return FAILURE(Result::NOT_SUPPORTED);
371 }
372 
getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb)373 Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) {
374     _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
375     return Void();
376 }
377 
setBtHfpEnabled(bool enabled)378 Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) {
379     (void)enabled;
380     return FAILURE(Result::NOT_SUPPORTED);
381 }
382 
setBtHfpSampleRate(uint32_t sampleRateHz)383 Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
384     (void)sampleRateHz;
385     return FAILURE(Result::NOT_SUPPORTED);
386 }
387 
setBtHfpVolume(float volume)388 Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
389     (void)volume;
390     return FAILURE(Result::NOT_SUPPORTED);
391 }
392 
updateRotation(IPrimaryDevice::Rotation rotation)393 Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
394     (void)rotation;
395     return FAILURE(Result::NOT_SUPPORTED);
396 }
397 
unrefDevice(IDevice * dev)398 void PrimaryDevice::unrefDevice(IDevice *dev) {
399     static_cast<PrimaryDevice *>(dev)->unrefDeviceImpl();
400 }
401 
unrefDeviceImpl()402 void PrimaryDevice::unrefDeviceImpl() {
403     LOG_ALWAYS_FATAL_IF(--mNStreams < 0);
404 }
405 
406 }  // namespace implementation
407 }  // namespace V6_0
408 }  // namespace audio
409 }  // namespace hardware
410 }  // namespace android
411