blob: 6c0c39796058cd1bbd652764909502b08f9c9514 [file] [log] [blame]
Tim Yaoe8c0d4a2019-11-27 14:47:35 -08001#include <thread>
2#include <mutex>
3#include <cstdlib>
4
5#include <hardware/hardware.h>
6#include <hardware/audio.h>
7#include <pthread.h>
8#include <system/audio.h>
9#include <cutils/log.h>
10
11#include <grpc/grpc.h>
12#include <grpcpp/channel.h>
13#include <grpcpp/client_context.h>
14#include <grpcpp/create_channel.h>
15#include <grpcpp/security/credentials.h>
16
17#include "audio_if_client.h"
18#include "audio_client.h"
19
20//#define TRACE_ENTRY() printf("[Client:%s] enter\n", __func__)
21#define TRACE_ENTRY()
22
23static AudioClient *client;
24static int inited = 0;
25static std::mutex client_mutex;
26
27static uint32_t stream_get_sample_rate(const struct audio_stream *stream)
28{
29 TRACE_ENTRY();
30 return client->stream_get_sample_rate(stream);
31}
32
33static size_t stream_get_buffer_size(const struct audio_stream *stream)
34{
35 TRACE_ENTRY();
36 return client->stream_get_buffer_size(stream);
37}
38
39static audio_channel_mask_t stream_get_channels(const struct audio_stream *stream)
40{
41 TRACE_ENTRY();
42 return client->stream_get_channels(stream);
43}
44
45static audio_format_t stream_get_format(const struct audio_stream *stream)
46{
47 TRACE_ENTRY();
48 return client->stream_get_format(stream);
49}
50
51static int stream_standby(struct audio_stream *stream)
52{
53 TRACE_ENTRY();
54 return client->stream_standby(stream);
55}
56
57static int stream_dump(const struct audio_stream *stream, int fd)
58{
59 TRACE_ENTRY();
60 return client->stream_dump(stream, fd);
61}
62
63static audio_devices_t stream_get_device(const struct audio_stream *stream)
64{
65 TRACE_ENTRY();
66 return client->stream_get_device(stream);
67}
68
69static int stream_set_parameters(struct audio_stream *stream, const char *kv_pairs)
70{
71 TRACE_ENTRY();
72 return client->stream_set_parameters(stream, kv_pairs);
73}
74
75static char * stream_get_parameters(const struct audio_stream *stream,
76 const char *keys)
77{
78 TRACE_ENTRY();
79 return client->stream_get_parameters(stream, keys);
80}
81
82static int stream_in_set_gain(struct audio_stream_in *stream, float gain)
83{
84 TRACE_ENTRY();
85 return client->stream_in_set_gain(stream, gain);
86}
87
88static ssize_t stream_in_read(struct audio_stream_in *stream, void* buffer,
89 size_t bytes)
90{
91 TRACE_ENTRY();
92 return client->stream_in_read(stream, buffer, bytes);
93}
94
95static uint32_t stream_in_get_input_frames_lost(struct audio_stream_in *stream)
96{
97 TRACE_ENTRY();
98 return client->stream_in_get_input_frames_lost(stream);
99}
100
101static int stream_in_get_capture_position(const struct audio_stream_in *stream,
102 int64_t *frames, int64_t *time)
103{
104 TRACE_ENTRY();
105 return client->stream_in_get_capture_position(stream, frames, time);
106}
107
108static uint32_t stream_out_get_latency(const struct audio_stream_out *stream)
109{
110 TRACE_ENTRY();
111 return client->stream_out_get_latency(stream);
112}
113
114static int stream_out_set_volume(struct audio_stream_out *stream, float left, float right)
115{
116 TRACE_ENTRY();
117 return client->stream_out_set_volume(stream, left, right);
118}
119
120static ssize_t stream_out_write(struct audio_stream_out *stream, const void* buffer,
121 size_t bytes)
122{
123 TRACE_ENTRY();
124 return client->stream_out_write(stream, buffer, bytes);
125}
126
127static int stream_out_get_render_position(const struct audio_stream_out *stream,
128 uint32_t *dsp_frames)
129{
130 TRACE_ENTRY();
131 return client->stream_out_get_render_position(stream, dsp_frames);
132}
133
134static int stream_out_get_next_write_timestamp(const struct audio_stream_out *stream,
135 int64_t *timestamp)
136{
137 TRACE_ENTRY();
138 return client->stream_out_get_next_write_timestamp(stream, timestamp);
139}
140
141static int stream_out_pause(struct audio_stream_out* stream)
142{
143 TRACE_ENTRY();
144 return client->stream_out_pause(stream);
145}
146
147static int stream_out_resume(struct audio_stream_out* stream)
148{
149 TRACE_ENTRY();
150 return client->stream_out_resume(stream);
151}
152
153static int stream_out_flush(struct audio_stream_out* stream)
154{
155 TRACE_ENTRY();
156 return client->stream_out_flush(stream);
157}
158
159static int stream_out_get_presentation_position(const struct audio_stream_out *stream,
160 uint64_t *frames, struct timespec *timestamp)
161{
162 TRACE_ENTRY();
163 return client->stream_out_get_presentation_position(stream, frames, timestamp);
164}
165
166struct audio_stream_in stream_in_template = {
167 .common = {
168 .get_sample_rate = stream_get_sample_rate,
169 .set_sample_rate = NULL,
170 .get_buffer_size = stream_get_buffer_size,
171 .get_channels = stream_get_channels,
172 .get_format = stream_get_format,
173 .set_format = NULL,
174 .standby = stream_standby,
175 .dump = stream_dump,
176 .get_device = stream_get_device,
177 .set_device = NULL,
178 .set_parameters = stream_set_parameters,
179 .get_parameters = stream_get_parameters,
180 .add_audio_effect = NULL,
181 .remove_audio_effect = NULL
182 },
183 .set_gain = stream_in_set_gain,
184 .read = stream_in_read,
185 .get_input_frames_lost = stream_in_get_input_frames_lost,
186 .get_capture_position = stream_in_get_capture_position,
187 .start = NULL,
188 .stop = NULL,
189 .create_mmap_buffer = NULL,
190 .get_mmap_position = NULL,
191 .get_active_microphones = NULL,
192 .update_sink_metadata = NULL
193};
194
195struct audio_stream_out stream_out_template = {
196 .common = {
197 .get_sample_rate = stream_get_sample_rate,
198 .set_sample_rate = NULL,
199 .get_buffer_size = stream_get_buffer_size,
200 .get_channels = stream_get_channels,
201 .get_format = stream_get_format,
202 .set_format = NULL,
203 .standby = stream_standby,
204 .dump = stream_dump,
205 .get_device = stream_get_device,
206 .set_device = NULL,
207 .set_parameters = stream_set_parameters,
208 .get_parameters = stream_get_parameters,
209 .add_audio_effect = NULL,
210 .remove_audio_effect = NULL
211 },
212 .get_latency = stream_out_get_latency,
213 .set_volume = stream_out_set_volume,
214 .write = stream_out_write,
215 .get_render_position = stream_out_get_render_position,
216 .get_next_write_timestamp = stream_out_get_next_write_timestamp,
217 .set_callback = NULL,
218 .pause = stream_out_pause,
219 .resume = stream_out_resume,
220 .drain = NULL,
221 .flush = stream_out_flush,
222 .get_presentation_position = stream_out_get_presentation_position,
223 .start = NULL,
224 .stop = NULL,
225 .create_mmap_buffer = NULL,
226 .get_mmap_position = NULL,
227 .update_source_metadata = NULL
228};
229
230static int Device_common_close(struct hw_device_t* device)
231{
232 // Server side audio hal device is constructed with
233 // server's life span. Skip Device_common_close for client
234 // The method is only needed when server really wants to exit.
235 // return client->Device_common_close(device);
236 return 0;
237}
238
239static int Device_init_check(const struct audio_hw_device *dev)
240{
241 TRACE_ENTRY();
242 return client->Device_init_check(dev);
243}
244
245static int Device_set_voice_volume(struct audio_hw_device *dev, float volume)
246{
247 TRACE_ENTRY();
248 return client->Device_set_voice_volume(dev, volume);
249}
250
251static int Device_set_master_volume(struct audio_hw_device *dev, float volume)
252{
253 TRACE_ENTRY();
254 return client->Device_set_master_volume(dev, volume);
255}
256
257static int Device_get_master_volume(struct audio_hw_device *dev, float *volume)
258{
259 TRACE_ENTRY();
260 return client->Device_get_master_volume(dev, volume);
261}
262
263static int Device_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
264{
265 TRACE_ENTRY();
266 return client->Device_set_mode(dev, mode);
267}
268
269static int Device_set_mic_mute(struct audio_hw_device *dev, bool state)
270{
271 TRACE_ENTRY();
272 return client->Device_set_mic_mute(dev, state);
273}
274
275static int Device_get_mic_mute(const struct audio_hw_device *dev, bool *state)
276{
277 TRACE_ENTRY();
278 return client->Device_get_mic_mute(dev, state);
279}
280
281static int Device_set_parameters(struct audio_hw_device *dev, const char *kv_pairs)
282{
283 TRACE_ENTRY();
284 return client->Device_set_parameters(dev, kv_pairs);
285}
286
287static char * Device_get_parameters(const struct audio_hw_device *dev,
288 const char *keys)
289{
290 TRACE_ENTRY();
291 return client->Device_get_parameters(dev, keys);
292}
293
294static size_t Device_get_input_buffer_size(const struct audio_hw_device *dev,
295 const struct audio_config *config)
296{
297 TRACE_ENTRY();
298 return client->Device_get_input_buffer_size(dev, config);
299}
300
301static int Device_open_output_stream(struct audio_hw_device *dev,
302 audio_io_handle_t handle,
303 audio_devices_t devices,
304 audio_output_flags_t flags,
305 struct audio_config *config,
306 struct audio_stream_out **stream_out,
307 const char *address)
308{
309 TRACE_ENTRY();
310
311 int r;
312 audio_stream_out_client_t *stream_out_client = (audio_stream_out_client_t *)calloc(1, sizeof(audio_stream_out_client_t));
313 if (!stream_out_client) return -ENOMEM;
314
315 r = client->Device_open_output_stream(dev, handle, devices, flags, config, stream_out_client, address);
316 if (r) {
317 free(stream_out);
318 return r;
319 }
320
321 stream_out_client->stream_out = stream_out_template;
322 *stream_out = &(stream_out_client->stream_out);
323 return r;
324}
325
326static void Device_close_output_stream(struct audio_hw_device *dev,
327 struct audio_stream_out* stream_out)
328{
329 TRACE_ENTRY();
330
331 client->Device_close_output_stream(dev, stream_out);
332 free(audio_stream_out_to_client(stream_out));
333}
334
335static int Device_open_input_stream(struct audio_hw_device *dev,
336 audio_io_handle_t handle,
337 audio_devices_t devices,
338 struct audio_config *config,
339 struct audio_stream_in **stream_in,
340 audio_input_flags_t flags,
341 const char *address,
342 audio_source_t source)
343{
344 TRACE_ENTRY();
345
346 int r;
347 audio_stream_in_client_t *stream_in_client = (audio_stream_in_client_t *)calloc(1, sizeof(audio_stream_in_client_t));
348 if (!stream_in_client) return -ENOMEM;
349
350 r = client->Device_open_input_stream(dev, handle, devices, config, stream_in_client, flags, address, source);
351 if (r) {
352 free(stream_in_client);
353 return r;
354 }
355
356 stream_in_client->stream_in = stream_in_template;
357 *stream_in = &(stream_in_client->stream_in);
358 return r;
359}
360
361static void Device_close_input_stream(struct audio_hw_device *dev,
362 struct audio_stream_in *stream_in)
363{
364 TRACE_ENTRY();
365
366 client->Device_close_input_stream(dev, stream_in);
367 free(audio_stream_in_to_client(stream_in));
368}
369
370static int Device_dump(const struct audio_hw_device *dev, int fd)
371{
372 TRACE_ENTRY();
373
374 return client->Device_dump(dev, fd);
375}
376
377static int Device_set_master_mute(struct audio_hw_device *dev, bool mute)
378{
379 TRACE_ENTRY();
380
381 return client->Device_set_master_mute(dev, mute);
382}
383
384static int Device_get_master_mute(struct audio_hw_device *dev, bool *mute)
385{
386 TRACE_ENTRY();
387
388 return client->Device_get_master_mute(dev, mute);
389}
390
391static int Device_create_audio_patch(struct audio_hw_device *dev,
392 unsigned int num_sources,
393 const struct audio_port_config *sources,
394 unsigned int num_sinks,
395 const struct audio_port_config *sinks,
396 audio_patch_handle_t *handle)
397{
398 TRACE_ENTRY();
399
400 return client->Device_create_audio_patch(dev, num_sources, sources, num_sinks, sinks, handle);
401}
402
403static int Device_release_audio_patch(struct audio_hw_device *dev,
404 audio_patch_handle_t handle)
405{
406 TRACE_ENTRY();
407
408 return client->Device_release_audio_patch(dev, handle);
409}
410
411static int Device_set_audio_port_config(struct audio_hw_device *dev,
412 const struct audio_port_config *config)
413{
414 TRACE_ENTRY();
415
416 return client->Device_set_audio_port_config(dev, config);
417}
418
419static struct hw_module_t hw_module = {
420 .tag = HARDWARE_MODULE_TAG,
421 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
422 .hal_api_version = HARDWARE_HAL_API_VERSION,
423 .id = AUDIO_HARDWARE_MODULE_ID,
424 .name = "aml audio HW HAL",
425 .author = "amlogic, Corp.",
426};
427
428static audio_hw_device_t device = {
429 .common = {
430 .tag = HARDWARE_DEVICE_TAG,
431 .version = AUDIO_DEVICE_API_VERSION_3_0,
432 .module = &hw_module,
433 .reserved = {0},
434 .close = Device_common_close,
435 },
436 .get_supported_devices = NULL,
437 .init_check = Device_init_check,
438 .set_voice_volume = Device_set_voice_volume,
439 .set_master_volume = Device_set_master_volume,
440 .get_master_volume = Device_get_master_volume,
441 .set_mode = Device_set_mode,
442 .set_mic_mute = Device_set_mic_mute,
443 .get_mic_mute = Device_get_mic_mute,
444 .set_parameters = Device_set_parameters,
445 .get_parameters = Device_get_parameters,
446 .get_input_buffer_size = Device_get_input_buffer_size,
447 .open_output_stream = Device_open_output_stream,
448 .close_output_stream = Device_close_output_stream,
449 .open_input_stream = Device_open_input_stream,
450 .close_input_stream = Device_close_input_stream,
451 .get_microphones = NULL,
452 .dump = Device_dump,
453 .set_master_mute = Device_set_master_mute,
454 .get_master_mute = Device_get_master_mute,
455 .create_audio_patch = Device_create_audio_patch,
456 .release_audio_patch = Device_release_audio_patch,
457 .get_audio_port = NULL,
458 .set_audio_port_config = Device_set_audio_port_config,
459};
460
461extern "C" {
462
463int audio_hw_load_interface(audio_hw_device_t **dev)
464{
465 TRACE_ENTRY();
466 printf("PID = %d, inited = %d\n", ::getpid(), inited);
467
Tim Yao1b84e362020-08-24 12:51:36 -0700468 const char *url = std::getenv("AUDIO_SERVER_SOCKET");
469
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800470 std::lock_guard<std::mutex> lock(client_mutex);
471
472 if (inited++ > 0) {
473 *dev = &device;
474 return 0;
475 }
476
477 client = new AudioClient(
Tim Yao1b84e362020-08-24 12:51:36 -0700478 grpc::CreateChannel((url) ? url : "unix:///opt/audio_socket",
Tim Yaoe8c0d4a2019-11-27 14:47:35 -0800479 grpc::InsecureChannelCredentials()));
480
481 *dev = &device;
482 inited = 1;
483
484 return 0;
485}
486
487void audio_hw_unload_interface(audio_hw_device_t *dev)
488{
489 TRACE_ENTRY();
490
491 std::lock_guard<std::mutex> lock(client_mutex);
492
493 if (--inited == 0) {
494 delete client;
495 client = nullptr;
496 }
497}
498
499}