blob: 8f73f118df52f17dad38b111fb76614f116cdaa7 [file] [log] [blame]
Dima Zavin8cc353a2011-04-20 16:38:05 -07001/*
2 * Copyright (C) 2011 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 "audio_hw_default"
18//#define LOG_NDEBUG 0
19
20#include <errno.h>
Elliott Hughes07c08552015-01-29 21:19:10 -080021#include <malloc.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070022#include <pthread.h>
23#include <stdint.h>
Mark Salyzynd88dfe82017-04-11 08:56:09 -070024#include <stdlib.h>
25#include <string.h>
26#include <time.h>
27#include <unistd.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070028
Steven Moreland02b5d162017-04-11 09:36:38 -070029#include <log/log.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070030
Mark Salyzynd88dfe82017-04-11 08:56:09 -070031#include <hardware/audio.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070032#include <hardware/hardware.h>
Dima Zavinaa211722011-05-11 14:15:53 -070033#include <system/audio.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070034
35struct stub_audio_device {
36 struct audio_hw_device device;
37};
38
39struct stub_stream_out {
40 struct audio_stream_out stream;
Andy Hung0caeee82016-06-24 19:41:06 -070041 int64_t last_write_time_us;
Dima Zavin8cc353a2011-04-20 16:38:05 -070042};
43
44struct stub_stream_in {
45 struct audio_stream_in stream;
Andy Hung0caeee82016-06-24 19:41:06 -070046 int64_t last_read_time_us;
Dima Zavin8cc353a2011-04-20 16:38:05 -070047};
48
49static uint32_t out_get_sample_rate(const struct audio_stream *stream)
50{
51 return 44100;
52}
53
54static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
55{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080056 ALOGV("out_set_sample_rate: %d", 0);
57 return -ENOSYS;
Dima Zavin8cc353a2011-04-20 16:38:05 -070058}
59
60static size_t out_get_buffer_size(const struct audio_stream *stream)
61{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080062 ALOGV("out_get_buffer_size: %d", 4096);
Dima Zavin8cc353a2011-04-20 16:38:05 -070063 return 4096;
64}
65
Glenn Kastena6354492012-06-19 12:16:04 -070066static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -070067{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080068 ALOGV("out_get_channels");
Dima Zavin8cc353a2011-04-20 16:38:05 -070069 return AUDIO_CHANNEL_OUT_STEREO;
70}
71
Glenn Kastenfe79eb32012-01-12 14:55:57 -080072static audio_format_t out_get_format(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -070073{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080074 ALOGV("out_get_format");
Dima Zavin8cc353a2011-04-20 16:38:05 -070075 return AUDIO_FORMAT_PCM_16_BIT;
76}
77
Glenn Kastenfe79eb32012-01-12 14:55:57 -080078static int out_set_format(struct audio_stream *stream, audio_format_t format)
Dima Zavin8cc353a2011-04-20 16:38:05 -070079{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080080 ALOGV("out_set_format: %d",format);
81 return -ENOSYS;
Dima Zavin8cc353a2011-04-20 16:38:05 -070082}
83
84static int out_standby(struct audio_stream *stream)
85{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080086 ALOGV("out_standby");
Andy Hung0caeee82016-06-24 19:41:06 -070087 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
Dima Zavin8cc353a2011-04-20 16:38:05 -070088 return 0;
89}
90
91static int out_dump(const struct audio_stream *stream, int fd)
92{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080093 ALOGV("out_dump");
Dima Zavin8cc353a2011-04-20 16:38:05 -070094 return 0;
95}
96
97static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
98{
Ricardo Garcia37cd7722015-02-23 15:42:26 -080099 ALOGV("out_set_parameters");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700100 return 0;
101}
102
103static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
104{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800105 ALOGV("out_get_parameters");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700106 return strdup("");
107}
108
109static uint32_t out_get_latency(const struct audio_stream_out *stream)
110{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800111 ALOGV("out_get_latency");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700112 return 0;
113}
114
115static int out_set_volume(struct audio_stream_out *stream, float left,
116 float right)
117{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800118 ALOGV("out_set_volume: Left:%f Right:%f", left, right);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700119 return 0;
120}
121
122static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
123 size_t bytes)
124{
Greg Kaiser6c59aad2016-06-30 16:08:53 -0700125 ALOGV("out_write: bytes: %zu", bytes);
Andy Hung0caeee82016-06-24 19:41:06 -0700126
Dima Zavin8cc353a2011-04-20 16:38:05 -0700127 /* XXX: fake timing for audio output */
Andy Hung0caeee82016-06-24 19:41:06 -0700128 struct stub_stream_out *out = (struct stub_stream_out *)stream;
129 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
130 clock_gettime(CLOCK_MONOTONIC, &t);
131 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
132 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
133 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
134 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
135 if (sleep_time > 0) {
136 usleep(sleep_time);
137 } else {
138 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
139 sleep_time = 0;
140 }
141 out->last_write_time_us = now + sleep_time;
142 // last_write_time_us is an approximation of when the (simulated) alsa
143 // buffer is believed completely full. The usleep above waits for more space
144 // in the buffer, but by the end of the sleep the buffer is considered
145 // topped-off.
146 //
147 // On the subsequent out_write(), we measure the elapsed time spent in
148 // the mixer. This is subtracted from the sleep estimate based on frames,
149 // thereby accounting for drain in the alsa buffer during mixing.
150 // This is a crude approximation; we don't handle underruns precisely.
Dima Zavin8cc353a2011-04-20 16:38:05 -0700151 return bytes;
152}
153
154static int out_get_render_position(const struct audio_stream_out *stream,
155 uint32_t *dsp_frames)
156{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800157 *dsp_frames = 0;
Glenn Kastene03bfa42015-03-23 10:52:31 -0700158 ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700159 return -EINVAL;
160}
161
Eric Laurentf3008aa2011-06-17 16:53:12 -0700162static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
163{
Glenn Kastene03bfa42015-03-23 10:52:31 -0700164 ALOGV("out_add_audio_effect: %p", effect);
Eric Laurentf3008aa2011-06-17 16:53:12 -0700165 return 0;
166}
167
168static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
169{
Glenn Kastene03bfa42015-03-23 10:52:31 -0700170 ALOGV("out_remove_audio_effect: %p", effect);
Eric Laurentf3008aa2011-06-17 16:53:12 -0700171 return 0;
172}
173
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700174static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
175 int64_t *timestamp)
176{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800177 *timestamp = 0;
178 ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700179 return -EINVAL;
180}
181
Dima Zavin8cc353a2011-04-20 16:38:05 -0700182/** audio_stream_in implementation **/
183static uint32_t in_get_sample_rate(const struct audio_stream *stream)
184{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800185 ALOGV("in_get_sample_rate");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700186 return 8000;
187}
188
189static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
190{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800191 ALOGV("in_set_sample_rate: %d", rate);
192 return -ENOSYS;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700193}
194
195static size_t in_get_buffer_size(const struct audio_stream *stream)
196{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800197 ALOGV("in_get_buffer_size: %d", 320);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700198 return 320;
199}
200
Glenn Kastena6354492012-06-19 12:16:04 -0700201static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700202{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800203 ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700204 return AUDIO_CHANNEL_IN_MONO;
205}
206
Glenn Kastenfe79eb32012-01-12 14:55:57 -0800207static audio_format_t in_get_format(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700208{
209 return AUDIO_FORMAT_PCM_16_BIT;
210}
211
Glenn Kastenfe79eb32012-01-12 14:55:57 -0800212static int in_set_format(struct audio_stream *stream, audio_format_t format)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700213{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800214 return -ENOSYS;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700215}
216
217static int in_standby(struct audio_stream *stream)
218{
Andy Hung0caeee82016-06-24 19:41:06 -0700219 struct stub_stream_in *in = (struct stub_stream_in *)stream;
220 in->last_read_time_us = 0;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700221 return 0;
222}
223
224static int in_dump(const struct audio_stream *stream, int fd)
225{
226 return 0;
227}
228
229static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
230{
231 return 0;
232}
233
234static char * in_get_parameters(const struct audio_stream *stream,
235 const char *keys)
236{
237 return strdup("");
238}
239
240static int in_set_gain(struct audio_stream_in *stream, float gain)
241{
242 return 0;
243}
244
245static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
246 size_t bytes)
247{
Greg Kaiser6c59aad2016-06-30 16:08:53 -0700248 ALOGV("in_read: bytes %zu", bytes);
Andy Hung0caeee82016-06-24 19:41:06 -0700249
Dima Zavin8cc353a2011-04-20 16:38:05 -0700250 /* XXX: fake timing for audio input */
Andy Hung0caeee82016-06-24 19:41:06 -0700251 struct stub_stream_in *in = (struct stub_stream_in *)stream;
252 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
253 clock_gettime(CLOCK_MONOTONIC, &t);
254 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
255
256 // we do a full sleep when exiting standby.
257 const bool standby = in->last_read_time_us == 0;
258 const int64_t elapsed_time_since_last_read = standby ?
259 0 : now - in->last_read_time_us;
260 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
261 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
262 if (sleep_time > 0) {
263 usleep(sleep_time);
264 } else {
265 sleep_time = 0;
266 }
267 in->last_read_time_us = now + sleep_time;
268 // last_read_time_us is an approximation of when the (simulated) alsa
269 // buffer is drained by the read, and is empty.
270 //
271 // On the subsequent in_read(), we measure the elapsed time spent in
272 // the recording thread. This is subtracted from the sleep estimate based on frames,
273 // thereby accounting for fill in the alsa buffer during the interim.
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800274 memset(buffer, 0, bytes);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700275 return bytes;
276}
277
278static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
279{
280 return 0;
281}
282
Eric Laurentf3008aa2011-06-17 16:53:12 -0700283static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
284{
285 return 0;
286}
287
288static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
289{
290 return 0;
291}
Dima Zavin8cc353a2011-04-20 16:38:05 -0700292
293static int adev_open_output_stream(struct audio_hw_device *dev,
Eric Laurent55786bc2012-04-10 16:56:32 -0700294 audio_io_handle_t handle,
295 audio_devices_t devices,
296 audio_output_flags_t flags,
297 struct audio_config *config,
Eric Laurentf5e24692014-07-27 16:14:57 -0700298 struct audio_stream_out **stream_out,
299 const char *address __unused)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700300{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800301 ALOGV("adev_open_output_stream...");
302
Glenn Kasten2494cae2016-09-19 18:16:16 -0700303 *stream_out = NULL;
304 struct stub_stream_out *out =
305 (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
Dima Zavin8cc353a2011-04-20 16:38:05 -0700306 if (!out)
307 return -ENOMEM;
308
309 out->stream.common.get_sample_rate = out_get_sample_rate;
310 out->stream.common.set_sample_rate = out_set_sample_rate;
311 out->stream.common.get_buffer_size = out_get_buffer_size;
312 out->stream.common.get_channels = out_get_channels;
313 out->stream.common.get_format = out_get_format;
314 out->stream.common.set_format = out_set_format;
315 out->stream.common.standby = out_standby;
316 out->stream.common.dump = out_dump;
317 out->stream.common.set_parameters = out_set_parameters;
318 out->stream.common.get_parameters = out_get_parameters;
Eric Laurentf3008aa2011-06-17 16:53:12 -0700319 out->stream.common.add_audio_effect = out_add_audio_effect;
320 out->stream.common.remove_audio_effect = out_remove_audio_effect;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700321 out->stream.get_latency = out_get_latency;
322 out->stream.set_volume = out_set_volume;
323 out->stream.write = out_write;
324 out->stream.get_render_position = out_get_render_position;
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700325 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700326
327 *stream_out = &out->stream;
328 return 0;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700329}
330
331static void adev_close_output_stream(struct audio_hw_device *dev,
332 struct audio_stream_out *stream)
333{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800334 ALOGV("adev_close_output_stream...");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700335 free(stream);
336}
337
338static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
339{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800340 ALOGV("adev_set_parameters");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700341 return -ENOSYS;
342}
343
344static char * adev_get_parameters(const struct audio_hw_device *dev,
345 const char *keys)
346{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800347 ALOGV("adev_get_parameters");
348 return strdup("");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700349}
350
351static int adev_init_check(const struct audio_hw_device *dev)
352{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800353 ALOGV("adev_init_check");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700354 return 0;
355}
356
357static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
358{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800359 ALOGV("adev_set_voice_volume: %f", volume);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700360 return -ENOSYS;
361}
362
363static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
364{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800365 ALOGV("adev_set_master_volume: %f", volume);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700366 return -ENOSYS;
367}
368
John Grossman47bf3d72012-07-17 11:54:04 -0700369static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
370{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800371 ALOGV("adev_get_master_volume: %f", *volume);
John Grossman47bf3d72012-07-17 11:54:04 -0700372 return -ENOSYS;
373}
374
375static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
376{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800377 ALOGV("adev_set_master_mute: %d", muted);
John Grossman47bf3d72012-07-17 11:54:04 -0700378 return -ENOSYS;
379}
380
381static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700382{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800383 ALOGV("adev_get_master_mute: %d", *muted);
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700384 return -ENOSYS;
385}
386
Glenn Kasten6df641e2012-01-09 10:41:30 -0800387static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700388{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800389 ALOGV("adev_set_mode: %d", mode);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700390 return 0;
391}
392
393static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
394{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800395 ALOGV("adev_set_mic_mute: %d",state);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700396 return -ENOSYS;
397}
398
399static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
400{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800401 ALOGV("adev_get_mic_mute");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700402 return -ENOSYS;
403}
404
405static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
Eric Laurent55786bc2012-04-10 16:56:32 -0700406 const struct audio_config *config)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700407{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800408 ALOGV("adev_get_input_buffer_size: %d", 320);
Dima Zavin8cc353a2011-04-20 16:38:05 -0700409 return 320;
410}
411
Eric Laurent55786bc2012-04-10 16:56:32 -0700412static int adev_open_input_stream(struct audio_hw_device *dev,
413 audio_io_handle_t handle,
414 audio_devices_t devices,
415 struct audio_config *config,
Glenn Kasten7d973ad2014-07-15 11:10:38 -0700416 struct audio_stream_in **stream_in,
Eric Laurentf5e24692014-07-27 16:14:57 -0700417 audio_input_flags_t flags __unused,
418 const char *address __unused,
419 audio_source_t source __unused)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700420{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800421 ALOGV("adev_open_input_stream...");
422
Glenn Kasten2494cae2016-09-19 18:16:16 -0700423 *stream_in = NULL;
424 struct stub_stream_in *in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
Dima Zavin8cc353a2011-04-20 16:38:05 -0700425 if (!in)
426 return -ENOMEM;
427
428 in->stream.common.get_sample_rate = in_get_sample_rate;
429 in->stream.common.set_sample_rate = in_set_sample_rate;
430 in->stream.common.get_buffer_size = in_get_buffer_size;
431 in->stream.common.get_channels = in_get_channels;
432 in->stream.common.get_format = in_get_format;
433 in->stream.common.set_format = in_set_format;
434 in->stream.common.standby = in_standby;
435 in->stream.common.dump = in_dump;
436 in->stream.common.set_parameters = in_set_parameters;
437 in->stream.common.get_parameters = in_get_parameters;
Eric Laurentf3008aa2011-06-17 16:53:12 -0700438 in->stream.common.add_audio_effect = in_add_audio_effect;
439 in->stream.common.remove_audio_effect = in_remove_audio_effect;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700440 in->stream.set_gain = in_set_gain;
441 in->stream.read = in_read;
442 in->stream.get_input_frames_lost = in_get_input_frames_lost;
443
444 *stream_in = &in->stream;
445 return 0;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700446}
447
448static void adev_close_input_stream(struct audio_hw_device *dev,
449 struct audio_stream_in *in)
450{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800451 ALOGV("adev_close_input_stream...");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700452 return;
453}
454
455static int adev_dump(const audio_hw_device_t *device, int fd)
456{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800457 ALOGV("adev_dump");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700458 return 0;
459}
460
461static int adev_close(hw_device_t *device)
462{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800463 ALOGV("adev_close");
Dima Zavin8cc353a2011-04-20 16:38:05 -0700464 free(device);
465 return 0;
466}
467
Dima Zavin8cc353a2011-04-20 16:38:05 -0700468static int adev_open(const hw_module_t* module, const char* name,
469 hw_device_t** device)
470{
Ricardo Garcia37cd7722015-02-23 15:42:26 -0800471 ALOGV("adev_open: %s", name);
472
Dima Zavin8cc353a2011-04-20 16:38:05 -0700473 struct stub_audio_device *adev;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700474
475 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
476 return -EINVAL;
477
478 adev = calloc(1, sizeof(struct stub_audio_device));
479 if (!adev)
480 return -ENOMEM;
481
482 adev->device.common.tag = HARDWARE_DEVICE_TAG;
Eric Laurent85e08e22012-08-28 14:30:35 -0700483 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700484 adev->device.common.module = (struct hw_module_t *) module;
485 adev->device.common.close = adev_close;
486
Dima Zavin8cc353a2011-04-20 16:38:05 -0700487 adev->device.init_check = adev_init_check;
488 adev->device.set_voice_volume = adev_set_voice_volume;
489 adev->device.set_master_volume = adev_set_master_volume;
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700490 adev->device.get_master_volume = adev_get_master_volume;
John Grossman47bf3d72012-07-17 11:54:04 -0700491 adev->device.set_master_mute = adev_set_master_mute;
492 adev->device.get_master_mute = adev_get_master_mute;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700493 adev->device.set_mode = adev_set_mode;
494 adev->device.set_mic_mute = adev_set_mic_mute;
495 adev->device.get_mic_mute = adev_get_mic_mute;
496 adev->device.set_parameters = adev_set_parameters;
497 adev->device.get_parameters = adev_get_parameters;
498 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
499 adev->device.open_output_stream = adev_open_output_stream;
500 adev->device.close_output_stream = adev_close_output_stream;
501 adev->device.open_input_stream = adev_open_input_stream;
502 adev->device.close_input_stream = adev_close_input_stream;
503 adev->device.dump = adev_dump;
504
505 *device = &adev->device.common;
506
507 return 0;
508}
509
510static struct hw_module_methods_t hal_module_methods = {
511 .open = adev_open,
512};
513
514struct audio_module HAL_MODULE_INFO_SYM = {
515 .common = {
516 .tag = HARDWARE_MODULE_TAG,
Eric Laurent55786bc2012-04-10 16:56:32 -0700517 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
518 .hal_api_version = HARDWARE_HAL_API_VERSION,
Dima Zavin8cc353a2011-04-20 16:38:05 -0700519 .id = AUDIO_HARDWARE_MODULE_ID,
520 .name = "Default audio HW HAL",
521 .author = "The Android Open Source Project",
522 .methods = &hal_module_methods,
523 },
524};