• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2016 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 "DeviceHAL"
18 //#define LOG_NDEBUG 0
19 
20 #include <algorithm>
21 #include <memory.h>
22 #include <string.h>
23 
24 #include <android/log.h>
25 
26 #include "Conversions.h"
27 #include "Device.h"
28 #include "HidlUtils.h"
29 #include "StreamIn.h"
30 #include "StreamOut.h"
31 #include "Util.h"
32 
33 namespace android {
34 namespace hardware {
35 namespace audio {
36 namespace V2_0 {
37 namespace implementation {
38 
Device(audio_hw_device_t * device)39 Device::Device(audio_hw_device_t* device)
40         : mDevice(device) {
41 }
42 
~Device()43 Device::~Device() {
44     int status = audio_hw_device_close(mDevice);
45     ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice,
46              strerror(-status));
47     mDevice = nullptr;
48 }
49 
analyzeStatus(const char * funcName,int status)50 Result Device::analyzeStatus(const char* funcName, int status) {
51     if (status != 0) {
52         ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status));
53     }
54     switch (status) {
55         case 0:
56             return Result::OK;
57         case -EINVAL:
58             return Result::INVALID_ARGUMENTS;
59         case -ENODATA:
60             return Result::INVALID_STATE;
61         case -ENODEV:
62             return Result::NOT_INITIALIZED;
63         case -ENOSYS:
64             return Result::NOT_SUPPORTED;
65         default:
66             return Result::INVALID_STATE;
67     }
68 }
69 
closeInputStream(audio_stream_in_t * stream)70 void Device::closeInputStream(audio_stream_in_t* stream) {
71     mDevice->close_input_stream(mDevice, stream);
72 }
73 
closeOutputStream(audio_stream_out_t * stream)74 void Device::closeOutputStream(audio_stream_out_t* stream) {
75     mDevice->close_output_stream(mDevice, stream);
76 }
77 
halGetParameters(const char * keys)78 char* Device::halGetParameters(const char* keys) {
79     return mDevice->get_parameters(mDevice, keys);
80 }
81 
halSetParameters(const char * keysAndValues)82 int Device::halSetParameters(const char* keysAndValues) {
83     return mDevice->set_parameters(mDevice, keysAndValues);
84 }
85 
86 // Methods from ::android::hardware::audio::V2_0::IDevice follow.
initCheck()87 Return<Result> Device::initCheck() {
88     return analyzeStatus("init_check", mDevice->init_check(mDevice));
89 }
90 
setMasterVolume(float volume)91 Return<Result> Device::setMasterVolume(float volume) {
92     if (mDevice->set_master_volume == NULL) {
93         return Result::NOT_SUPPORTED;
94     }
95     if (!isGainNormalized(volume)) {
96         ALOGW("Can not set a master volume (%f) outside [0,1]", volume);
97         return Result::INVALID_ARGUMENTS;
98     }
99     return analyzeStatus("set_master_volume",
100                          mDevice->set_master_volume(mDevice, volume));
101 }
102 
getMasterVolume(getMasterVolume_cb _hidl_cb)103 Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
104     Result retval(Result::NOT_SUPPORTED);
105     float volume = 0;
106     if (mDevice->get_master_volume != NULL) {
107         retval = analyzeStatus("get_master_volume",
108                                mDevice->get_master_volume(mDevice, &volume));
109     }
110     _hidl_cb(retval, volume);
111     return Void();
112 }
113 
setMicMute(bool mute)114 Return<Result> Device::setMicMute(bool mute) {
115     return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
116 }
117 
getMicMute(getMicMute_cb _hidl_cb)118 Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
119     bool mute = false;
120     Result retval =
121         analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
122     _hidl_cb(retval, mute);
123     return Void();
124 }
125 
setMasterMute(bool mute)126 Return<Result> Device::setMasterMute(bool mute) {
127     Result retval(Result::NOT_SUPPORTED);
128     if (mDevice->set_master_mute != NULL) {
129         retval = analyzeStatus("set_master_mute",
130                                mDevice->set_master_mute(mDevice, mute));
131     }
132     return retval;
133 }
134 
getMasterMute(getMasterMute_cb _hidl_cb)135 Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
136     Result retval(Result::NOT_SUPPORTED);
137     bool mute = false;
138     if (mDevice->get_master_mute != NULL) {
139         retval = analyzeStatus("get_master_mute",
140                                mDevice->get_master_mute(mDevice, &mute));
141     }
142     _hidl_cb(retval, mute);
143     return Void();
144 }
145 
getInputBufferSize(const AudioConfig & config,getInputBufferSize_cb _hidl_cb)146 Return<void> Device::getInputBufferSize(const AudioConfig& config,
147                                         getInputBufferSize_cb _hidl_cb) {
148     audio_config_t halConfig;
149     HidlUtils::audioConfigToHal(config, &halConfig);
150     size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
151     Result retval(Result::INVALID_ARGUMENTS);
152     uint64_t bufferSize = 0;
153     if (halBufferSize != 0) {
154         retval = Result::OK;
155         bufferSize = halBufferSize;
156     }
157     _hidl_cb(retval, bufferSize);
158     return Void();
159 }
160 
openOutputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioOutputFlag flags,openOutputStream_cb _hidl_cb)161 Return<void> Device::openOutputStream(int32_t ioHandle,
162                                       const DeviceAddress& device,
163                                       const AudioConfig& config,
164                                       AudioOutputFlag flags,
165                                       openOutputStream_cb _hidl_cb) {
166     audio_config_t halConfig;
167     HidlUtils::audioConfigToHal(config, &halConfig);
168     audio_stream_out_t* halStream;
169     ALOGV(
170         "open_output_stream handle: %d devices: %x flags: %#x "
171         "srate: %d format %#x channels %x address %s",
172         ioHandle, static_cast<audio_devices_t>(device.device),
173         static_cast<audio_output_flags_t>(flags), halConfig.sample_rate,
174         halConfig.format, halConfig.channel_mask,
175         deviceAddressToHal(device).c_str());
176     int status = mDevice->open_output_stream(
177         mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
178         static_cast<audio_output_flags_t>(flags), &halConfig, &halStream,
179         deviceAddressToHal(device).c_str());
180     ALOGV("open_output_stream status %d stream %p", status, halStream);
181     sp<IStreamOut> streamOut;
182     if (status == OK) {
183         streamOut = new StreamOut(this, halStream);
184     }
185     AudioConfig suggestedConfig;
186     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
187     _hidl_cb(analyzeStatus("open_output_stream", status), streamOut,
188              suggestedConfig);
189     return Void();
190 }
191 
openInputStream(int32_t ioHandle,const DeviceAddress & device,const AudioConfig & config,AudioInputFlag flags,AudioSource source,openInputStream_cb _hidl_cb)192 Return<void> Device::openInputStream(int32_t ioHandle,
193                                      const DeviceAddress& device,
194                                      const AudioConfig& config,
195                                      AudioInputFlag flags, AudioSource source,
196                                      openInputStream_cb _hidl_cb) {
197     audio_config_t halConfig;
198     HidlUtils::audioConfigToHal(config, &halConfig);
199     audio_stream_in_t* halStream;
200     ALOGV(
201         "open_input_stream handle: %d devices: %x flags: %#x "
202         "srate: %d format %#x channels %x address %s source %d",
203         ioHandle, static_cast<audio_devices_t>(device.device),
204         static_cast<audio_input_flags_t>(flags), halConfig.sample_rate,
205         halConfig.format, halConfig.channel_mask,
206         deviceAddressToHal(device).c_str(),
207         static_cast<audio_source_t>(source));
208     int status = mDevice->open_input_stream(
209         mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
210         &halConfig, &halStream, static_cast<audio_input_flags_t>(flags),
211         deviceAddressToHal(device).c_str(),
212         static_cast<audio_source_t>(source));
213     ALOGV("open_input_stream status %d stream %p", status, halStream);
214     sp<IStreamIn> streamIn;
215     if (status == OK) {
216         streamIn = new StreamIn(this, halStream);
217     }
218     AudioConfig suggestedConfig;
219     HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
220     _hidl_cb(analyzeStatus("open_input_stream", status), streamIn,
221              suggestedConfig);
222     return Void();
223 }
224 
supportsAudioPatches()225 Return<bool> Device::supportsAudioPatches() {
226     return version() >= AUDIO_DEVICE_API_VERSION_3_0;
227 }
228 
createAudioPatch(const hidl_vec<AudioPortConfig> & sources,const hidl_vec<AudioPortConfig> & sinks,createAudioPatch_cb _hidl_cb)229 Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
230                                       const hidl_vec<AudioPortConfig>& sinks,
231                                       createAudioPatch_cb _hidl_cb) {
232     Result retval(Result::NOT_SUPPORTED);
233     AudioPatchHandle patch = 0;
234     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
235         std::unique_ptr<audio_port_config[]> halSources(
236             HidlUtils::audioPortConfigsToHal(sources));
237         std::unique_ptr<audio_port_config[]> halSinks(
238             HidlUtils::audioPortConfigsToHal(sinks));
239         audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
240         retval = analyzeStatus(
241             "create_audio_patch",
242             mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0],
243                                         sinks.size(), &halSinks[0], &halPatch));
244         if (retval == Result::OK) {
245             patch = static_cast<AudioPatchHandle>(halPatch);
246         }
247     }
248     _hidl_cb(retval, patch);
249     return Void();
250 }
251 
releaseAudioPatch(int32_t patch)252 Return<Result> Device::releaseAudioPatch(int32_t patch) {
253     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
254         return analyzeStatus(
255             "release_audio_patch",
256             mDevice->release_audio_patch(
257                 mDevice, static_cast<audio_patch_handle_t>(patch)));
258     }
259     return Result::NOT_SUPPORTED;
260 }
261 
getAudioPort(const AudioPort & port,getAudioPort_cb _hidl_cb)262 Return<void> Device::getAudioPort(const AudioPort& port,
263                                   getAudioPort_cb _hidl_cb) {
264     audio_port halPort;
265     HidlUtils::audioPortToHal(port, &halPort);
266     Result retval = analyzeStatus("get_audio_port",
267                                   mDevice->get_audio_port(mDevice, &halPort));
268     AudioPort resultPort = port;
269     if (retval == Result::OK) {
270         HidlUtils::audioPortFromHal(halPort, &resultPort);
271     }
272     _hidl_cb(retval, resultPort);
273     return Void();
274 }
275 
setAudioPortConfig(const AudioPortConfig & config)276 Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
277     if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
278         struct audio_port_config halPortConfig;
279         HidlUtils::audioPortConfigToHal(config, &halPortConfig);
280         return analyzeStatus(
281             "set_audio_port_config",
282             mDevice->set_audio_port_config(mDevice, &halPortConfig));
283     }
284     return Result::NOT_SUPPORTED;
285 }
286 
getHwAvSync()287 Return<AudioHwSync> Device::getHwAvSync() {
288     int halHwAvSync;
289     Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
290     return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
291 }
292 
setScreenState(bool turnedOn)293 Return<Result> Device::setScreenState(bool turnedOn) {
294     return setParam(AudioParameter::keyScreenState, turnedOn);
295 }
296 
getParameters(const hidl_vec<hidl_string> & keys,getParameters_cb _hidl_cb)297 Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys,
298                                    getParameters_cb _hidl_cb) {
299     getParametersImpl(keys, _hidl_cb);
300     return Void();
301 }
302 
setParameters(const hidl_vec<ParameterValue> & parameters)303 Return<Result> Device::setParameters(
304     const hidl_vec<ParameterValue>& parameters) {
305     return setParametersImpl(parameters);
306 }
307 
debugDump(const hidl_handle & fd)308 Return<void> Device::debugDump(const hidl_handle& fd) {
309     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
310         analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
311     }
312     return Void();
313 }
314 
315 }  // namespace implementation
316 }  // namespace V2_0
317 }  // namespace audio
318 }  // namespace hardware
319 }  // namespace android
320