blob: d12f8c03194d553f6aa641a28580a7a485a609ac [file] [log] [blame]
Mikhail Naganov10548292016-10-31 10:39:47 -07001 /*
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"
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -080018//#define LOG_NDEBUG 0
Mikhail Naganov10548292016-10-31 10:39:47 -070019
20#include <algorithm>
21#include <memory.h>
22#include <string.h>
23
Yifan Hongf9d30342016-11-30 13:45:34 -080024#include <android/log.h>
Mikhail Naganov10548292016-10-31 10:39:47 -070025
26#include "Conversions.h"
27#include "Device.h"
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -080028#include "HidlUtils.h"
Mikhail Naganove4228e72017-04-28 13:20:56 -070029#include "ParametersUtil.h"
Mikhail Naganov10548292016-10-31 10:39:47 -070030#include "StreamIn.h"
31#include "StreamOut.h"
32
33namespace android {
34namespace hardware {
35namespace audio {
36namespace V2_0 {
37namespace implementation {
38
Mikhail Naganove4228e72017-04-28 13:20:56 -070039namespace {
40
41class ParametersUtilImpl : public ParametersUtil {
42 public:
43 ParametersUtilImpl(audio_hw_device_t* device) : mDevice{device} {}
44
45 char* halGetParameters(const char* keys) override {
46 return mDevice->get_parameters(mDevice, keys);
47 }
48
49 int halSetParameters(const char* keysAndValues) override {
50 return mDevice->set_parameters(mDevice, keysAndValues);
51 }
52
53 private:
54 audio_hw_device_t* mDevice;
55};
56
57} // namespace
58
Mikhail Naganov10548292016-10-31 10:39:47 -070059Device::Device(audio_hw_device_t* device)
Mikhail Naganove4228e72017-04-28 13:20:56 -070060 : mDevice{device}, mParameters{new ParametersUtilImpl(mDevice)} {}
Mikhail Naganov10548292016-10-31 10:39:47 -070061
62Device::~Device() {
63 int status = audio_hw_device_close(mDevice);
64 ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
65 mDevice = nullptr;
66}
67
Mikhail Naganov10548292016-10-31 10:39:47 -070068Result Device::analyzeStatus(const char* funcName, int status) {
69 if (status != 0) {
70 ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status));
71 }
72 switch (status) {
73 case 0: return Result::OK;
74 case -EINVAL: return Result::INVALID_ARGUMENTS;
75 case -ENODATA: return Result::INVALID_STATE;
76 case -ENODEV: return Result::NOT_INITIALIZED;
77 case -ENOSYS: return Result::NOT_SUPPORTED;
78 default: return Result::INVALID_STATE;
79 }
80}
81
Mikhail Naganov936279e2017-03-29 09:31:18 -070082void Device::closeInputStream(audio_stream_in_t* stream) {
83 mDevice->close_input_stream(mDevice, stream);
84}
85
86void Device::closeOutputStream(audio_stream_out_t* stream) {
87 mDevice->close_output_stream(mDevice, stream);
88}
89
Mikhail Naganove4228e72017-04-28 13:20:56 -070090Result Device::getParam(const char* name, bool* value) {
91 return mParameters->getParam(name, value);
Mikhail Naganov10548292016-10-31 10:39:47 -070092}
93
Mikhail Naganove4228e72017-04-28 13:20:56 -070094Result Device::getParam(const char* name, int* value) {
95 return mParameters->getParam(name, value);
96}
97
98Result Device::getParam(const char* name, String8* value) {
99 return mParameters->getParam(name, value);
100}
101
102Result Device::setParam(const char* name, bool value) {
103 return mParameters->setParam(name, value);
104}
105
106Result Device::setParam(const char* name, int value) {
107 return mParameters->setParam(name, value);
108}
109
110Result Device::setParam(const char* name, const char* value) {
111 return mParameters->setParam(name, value);
Mikhail Naganov10548292016-10-31 10:39:47 -0700112}
113
114// Methods from ::android::hardware::audio::V2_0::IDevice follow.
115Return<Result> Device::initCheck() {
116 return analyzeStatus("init_check", mDevice->init_check(mDevice));
117}
118
119Return<Result> Device::setMasterVolume(float volume) {
120 Result retval(Result::NOT_SUPPORTED);
121 if (mDevice->set_master_volume != NULL) {
122 retval = analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume));
123 }
124 return retval;
125}
126
127Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
128 Result retval(Result::NOT_SUPPORTED);
129 float volume = 0;
130 if (mDevice->get_master_volume != NULL) {
131 retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume));
132 }
133 _hidl_cb(retval, volume);
134 return Void();
135}
136
137Return<Result> Device::setMicMute(bool mute) {
138 return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
139}
140
141Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
142 bool mute = false;
143 Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
144 _hidl_cb(retval, mute);
145 return Void();
146}
147
148Return<Result> Device::setMasterMute(bool mute) {
149 Result retval(Result::NOT_SUPPORTED);
150 if (mDevice->set_master_mute != NULL) {
151 retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
152 }
153 return retval;
154}
155
156Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
157 Result retval(Result::NOT_SUPPORTED);
158 bool mute = false;
159 if (mDevice->get_master_mute != NULL) {
160 retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
161 }
162 _hidl_cb(retval, mute);
163 return Void();
164}
165
166Return<void> Device::getInputBufferSize(
167 const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
168 audio_config_t halConfig;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800169 HidlUtils::audioConfigToHal(config, &halConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700170 size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
171 Result retval(Result::INVALID_ARGUMENTS);
172 uint64_t bufferSize = 0;
173 if (halBufferSize != 0) {
174 retval = Result::OK;
175 bufferSize = halBufferSize;
176 }
177 _hidl_cb(retval, bufferSize);
178 return Void();
179}
180
181Return<void> Device::openOutputStream(
182 int32_t ioHandle,
183 const DeviceAddress& device,
184 const AudioConfig& config,
185 AudioOutputFlag flags,
186 openOutputStream_cb _hidl_cb) {
187 audio_config_t halConfig;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800188 HidlUtils::audioConfigToHal(config, &halConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700189 audio_stream_out_t *halStream;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800190 ALOGV("open_output_stream handle: %d devices: %x flags: %#x "
191 "srate: %d format %#x channels %x address %s",
192 ioHandle,
193 static_cast<audio_devices_t>(device.device), static_cast<audio_output_flags_t>(flags),
194 halConfig.sample_rate, halConfig.format, halConfig.channel_mask,
195 deviceAddressToHal(device).c_str());
Mikhail Naganov10548292016-10-31 10:39:47 -0700196 int status = mDevice->open_output_stream(
197 mDevice,
198 ioHandle,
199 static_cast<audio_devices_t>(device.device),
200 static_cast<audio_output_flags_t>(flags),
201 &halConfig,
202 &halStream,
203 deviceAddressToHal(device).c_str());
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800204 ALOGV("open_output_stream status %d stream %p", status, halStream);
Mikhail Naganov10548292016-10-31 10:39:47 -0700205 sp<IStreamOut> streamOut;
206 if (status == OK) {
Mikhail Naganov936279e2017-03-29 09:31:18 -0700207 streamOut = new StreamOut(this, halStream);
Mikhail Naganov10548292016-10-31 10:39:47 -0700208 }
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800209 AudioConfig suggestedConfig;
210 HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
211 _hidl_cb(analyzeStatus("open_output_stream", status), streamOut, suggestedConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700212 return Void();
213}
214
215Return<void> Device::openInputStream(
216 int32_t ioHandle,
217 const DeviceAddress& device,
218 const AudioConfig& config,
219 AudioInputFlag flags,
220 AudioSource source,
221 openInputStream_cb _hidl_cb) {
222 audio_config_t halConfig;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800223 HidlUtils::audioConfigToHal(config, &halConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700224 audio_stream_in_t *halStream;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800225 ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
226 "srate: %d format %#x channels %x address %s source %d",
227 ioHandle,
228 static_cast<audio_devices_t>(device.device), static_cast<audio_input_flags_t>(flags),
229 halConfig.sample_rate, halConfig.format, halConfig.channel_mask,
230 deviceAddressToHal(device).c_str(), static_cast<audio_source_t>(source));
Mikhail Naganov10548292016-10-31 10:39:47 -0700231 int status = mDevice->open_input_stream(
232 mDevice,
233 ioHandle,
234 static_cast<audio_devices_t>(device.device),
235 &halConfig,
236 &halStream,
237 static_cast<audio_input_flags_t>(flags),
238 deviceAddressToHal(device).c_str(),
239 static_cast<audio_source_t>(source));
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800240 ALOGV("open_input_stream status %d stream %p", status, halStream);
Mikhail Naganov10548292016-10-31 10:39:47 -0700241 sp<IStreamIn> streamIn;
242 if (status == OK) {
Mikhail Naganov936279e2017-03-29 09:31:18 -0700243 streamIn = new StreamIn(this, halStream);
Mikhail Naganov10548292016-10-31 10:39:47 -0700244 }
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800245 AudioConfig suggestedConfig;
246 HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
247 _hidl_cb(analyzeStatus("open_input_stream", status), streamIn, suggestedConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700248 return Void();
249}
250
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800251Return<bool> Device::supportsAudioPatches() {
252 return version() >= AUDIO_DEVICE_API_VERSION_3_0;
253}
254
Mikhail Naganov10548292016-10-31 10:39:47 -0700255Return<void> Device::createAudioPatch(
256 const hidl_vec<AudioPortConfig>& sources,
257 const hidl_vec<AudioPortConfig>& sinks,
258 createAudioPatch_cb _hidl_cb) {
259 Result retval(Result::NOT_SUPPORTED);
260 AudioPatchHandle patch = 0;
261 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800262 std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources));
263 std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks));
Derek Chenab24ecd2017-04-03 19:00:50 -0400264 audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
Mikhail Naganov10548292016-10-31 10:39:47 -0700265 retval = analyzeStatus(
266 "create_audio_patch",
267 mDevice->create_audio_patch(
268 mDevice,
269 sources.size(), &halSources[0],
270 sinks.size(), &halSinks[0],
271 &halPatch));
272 if (retval == Result::OK) {
273 patch = static_cast<AudioPatchHandle>(halPatch);
274 }
275 }
276 _hidl_cb(retval, patch);
277 return Void();
278}
279
280Return<Result> Device::releaseAudioPatch(int32_t patch) {
281 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
282 return analyzeStatus(
283 "release_audio_patch",
284 mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch)));
285 }
286 return Result::NOT_SUPPORTED;
287}
288
289Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
290 audio_port halPort;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800291 HidlUtils::audioPortToHal(port, &halPort);
Mikhail Naganov10548292016-10-31 10:39:47 -0700292 Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort));
293 AudioPort resultPort = port;
294 if (retval == Result::OK) {
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800295 HidlUtils::audioPortFromHal(halPort, &resultPort);
Mikhail Naganov10548292016-10-31 10:39:47 -0700296 }
297 _hidl_cb(retval, resultPort);
298 return Void();
299}
300
301Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
302 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
303 struct audio_port_config halPortConfig;
Mikhail Naganov6e81e9b2016-11-16 16:30:17 -0800304 HidlUtils::audioPortConfigToHal(config, &halPortConfig);
Mikhail Naganov10548292016-10-31 10:39:47 -0700305 return analyzeStatus(
306 "set_audio_port_config", mDevice->set_audio_port_config(mDevice, &halPortConfig));
307 }
308 return Result::NOT_SUPPORTED;
309}
310
311Return<AudioHwSync> Device::getHwAvSync() {
312 int halHwAvSync;
Mikhail Naganove4228e72017-04-28 13:20:56 -0700313 Result retval =
314 mParameters->getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
Mikhail Naganov10548292016-10-31 10:39:47 -0700315 return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
316}
317
318Return<Result> Device::setScreenState(bool turnedOn) {
Mikhail Naganove4228e72017-04-28 13:20:56 -0700319 return mParameters->setParam(AudioParameter::keyScreenState, turnedOn);
Mikhail Naganov10548292016-10-31 10:39:47 -0700320}
321
322Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
Mikhail Naganove4228e72017-04-28 13:20:56 -0700323 mParameters->getParametersImpl(keys, _hidl_cb);
Mikhail Naganov10548292016-10-31 10:39:47 -0700324 return Void();
325}
326
327Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) {
Mikhail Naganove4228e72017-04-28 13:20:56 -0700328 return mParameters->setParametersImpl(parameters);
Mikhail Naganov10548292016-10-31 10:39:47 -0700329}
330
Martijn Coenen70b9a152016-11-18 15:29:32 +0100331Return<void> Device::debugDump(const hidl_handle& fd) {
Mikhail Naganov3e6fe752017-04-24 10:44:08 -0700332 if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
Mikhail Naganov10548292016-10-31 10:39:47 -0700333 analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
334 }
335 return Void();
336}
337
338} // namespace implementation
339} // namespace V2_0
340} // namespace audio
341} // namespace hardware
342} // namespace android