OSDN Git Service

android: Fix error check from pthread_create
[android-x86/external-bluetooth-bluez.git] / android / hal-audio.c
1 /*
2  * Copyright (C) 2013 Intel Corporation
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
18 #include <errno.h>
19 #include <pthread.h>
20 #include <poll.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <unistd.h>
27
28 #include <hardware/audio.h>
29 #include <hardware/hardware.h>
30
31 #include "audio-msg.h"
32 #include "hal-log.h"
33
34 static int audio_sk = -1;
35 static bool close_thread = false;
36
37 static pthread_t ipc_th = 0;
38 static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
39
40 struct a2dp_audio_dev {
41         struct audio_hw_device dev;
42         struct audio_stream_out *out;
43 };
44
45 static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
46                                                                 size_t bytes)
47 {
48         DBG("");
49         return -ENOSYS;
50 }
51
52 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
53 {
54         DBG("");
55         return -ENOSYS;
56 }
57
58 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
59 {
60         DBG("");
61         return -ENOSYS;
62 }
63
64 static size_t out_get_buffer_size(const struct audio_stream *stream)
65 {
66         DBG("");
67         return -ENOSYS;
68 }
69
70 static uint32_t out_get_channels(const struct audio_stream *stream)
71 {
72         DBG("");
73         return -ENOSYS;
74 }
75
76 static audio_format_t out_get_format(const struct audio_stream *stream)
77 {
78         DBG("");
79         return -ENOSYS;
80 }
81
82 static int out_set_format(struct audio_stream *stream, audio_format_t format)
83 {
84         DBG("");
85         return -ENOSYS;
86 }
87
88 static int out_standby(struct audio_stream *stream)
89 {
90         DBG("");
91         return -ENOSYS;
92 }
93
94 static int out_dump(const struct audio_stream *stream, int fd)
95 {
96         DBG("");
97         return -ENOSYS;
98 }
99
100 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
101 {
102         DBG("");
103         return -ENOSYS;
104 }
105
106 static char *out_get_parameters(const struct audio_stream *stream,
107                                                         const char *keys)
108 {
109         DBG("");
110         return strdup("");
111 }
112
113 static uint32_t out_get_latency(const struct audio_stream_out *stream)
114 {
115         DBG("");
116         return -ENOSYS;
117 }
118
119 static int out_set_volume(struct audio_stream_out *stream, float left,
120                                                                 float right)
121 {
122         DBG("");
123         /* volume controlled in audioflinger mixer (digital) */
124         return -ENOSYS;
125 }
126
127 static int out_get_render_position(const struct audio_stream_out *stream,
128                                                         uint32_t *dsp_frames)
129 {
130         DBG("");
131         return -ENOSYS;
132 }
133
134 static int out_add_audio_effect(const struct audio_stream *stream,
135                                                         effect_handle_t effect)
136 {
137         DBG("");
138         return -ENOSYS;
139 }
140
141 static int out_remove_audio_effect(const struct audio_stream *stream,
142                                                         effect_handle_t effect)
143 {
144         DBG("");
145         return -ENOSYS;
146 }
147
148 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
149 {
150         DBG("");
151         return -ENOSYS;
152 }
153
154 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
155 {
156         DBG("");
157         return -ENOSYS;
158 }
159
160 static size_t in_get_buffer_size(const struct audio_stream *stream)
161 {
162         DBG("");
163         return -ENOSYS;
164 }
165
166 static uint32_t in_get_channels(const struct audio_stream *stream)
167 {
168         DBG("");
169         return -ENOSYS;
170 }
171
172 static audio_format_t in_get_format(const struct audio_stream *stream)
173 {
174         DBG("");
175         return -ENOSYS;
176 }
177
178 static int in_set_format(struct audio_stream *stream, audio_format_t format)
179 {
180         DBG("");
181         return -ENOSYS;
182 }
183
184 static int in_standby(struct audio_stream *stream)
185 {
186         DBG("");
187         return -ENOSYS;
188 }
189
190 static int in_dump(const struct audio_stream *stream, int fd)
191 {
192         DBG("");
193         return -ENOSYS;
194 }
195
196 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
197 {
198         DBG("");
199         return -ENOSYS;
200 }
201
202 static char *in_get_parameters(const struct audio_stream *stream,
203                                                         const char *keys)
204 {
205         DBG("");
206         return strdup("");
207 }
208
209 static int in_set_gain(struct audio_stream_in *stream, float gain)
210 {
211         DBG("");
212         return -ENOSYS;
213 }
214
215 static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
216                                                                 size_t bytes)
217 {
218         DBG("");
219         return -ENOSYS;
220 }
221
222 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
223 {
224         DBG("");
225         return -ENOSYS;
226 }
227
228 static int in_add_audio_effect(const struct audio_stream *stream,
229                                                         effect_handle_t effect)
230 {
231         DBG("");
232         return -ENOSYS;
233 }
234
235 static int in_remove_audio_effect(const struct audio_stream *stream,
236                                                         effect_handle_t effect)
237 {
238         DBG("");
239         return -ENOSYS;
240 }
241
242 static int audio_open_output_stream(struct audio_hw_device *dev,
243                                         audio_io_handle_t handle,
244                                         audio_devices_t devices,
245                                         audio_output_flags_t flags,
246                                         struct audio_config *config,
247                                         struct audio_stream_out **stream_out)
248
249 {
250         struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev;
251         struct audio_stream_out *out;
252
253         out = calloc(1, sizeof(struct audio_stream_out));
254         if (!out)
255                 return -ENOMEM;
256
257         DBG("");
258
259         out->common.get_sample_rate = out_get_sample_rate;
260         out->common.set_sample_rate = out_set_sample_rate;
261         out->common.get_buffer_size = out_get_buffer_size;
262         out->common.get_channels = out_get_channels;
263         out->common.get_format = out_get_format;
264         out->common.set_format = out_set_format;
265         out->common.standby = out_standby;
266         out->common.dump = out_dump;
267         out->common.set_parameters = out_set_parameters;
268         out->common.get_parameters = out_get_parameters;
269         out->common.add_audio_effect = out_add_audio_effect;
270         out->common.remove_audio_effect = out_remove_audio_effect;
271         out->get_latency = out_get_latency;
272         out->set_volume = out_set_volume;
273         out->write = out_write;
274         out->get_render_position = out_get_render_position;
275
276         *stream_out = out;
277         a2dp_dev->out = out;
278
279         return 0;
280 }
281
282 static void audio_close_output_stream(struct audio_hw_device *dev,
283                                         struct audio_stream_out *stream)
284 {
285         struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev;
286
287         DBG("");
288
289         free(stream);
290         a2dp_dev->out = NULL;
291 }
292
293 static int audio_set_parameters(struct audio_hw_device *dev,
294                                                         const char *kvpairs)
295 {
296         DBG("");
297         return -ENOSYS;
298 }
299
300 static char *audio_get_parameters(const struct audio_hw_device *dev,
301                                                         const char *keys)
302 {
303         DBG("");
304         return strdup("");
305 }
306
307 static int audio_init_check(const struct audio_hw_device *dev)
308 {
309         DBG("");
310         return -ENOSYS;
311 }
312
313 static int audio_set_voice_volume(struct audio_hw_device *dev, float volume)
314 {
315         DBG("");
316         return -ENOSYS;
317 }
318
319 static int audio_set_master_volume(struct audio_hw_device *dev, float volume)
320 {
321         DBG("");
322         return -ENOSYS;
323 }
324
325 static int audio_set_mode(struct audio_hw_device *dev, int mode)
326 {
327         DBG("");
328         return -ENOSYS;
329 }
330
331 static int audio_set_mic_mute(struct audio_hw_device *dev, bool state)
332 {
333         DBG("");
334         return -ENOSYS;
335 }
336
337 static int audio_get_mic_mute(const struct audio_hw_device *dev, bool *state)
338 {
339         DBG("");
340         return -ENOSYS;
341 }
342
343 static size_t audio_get_input_buffer_size(const struct audio_hw_device *dev,
344                                         const struct audio_config *config)
345 {
346         DBG("");
347         return -ENOSYS;
348 }
349
350 static int audio_open_input_stream(struct audio_hw_device *dev,
351                                         audio_io_handle_t handle,
352                                         audio_devices_t devices,
353                                         struct audio_config *config,
354                                         struct audio_stream_in **stream_in)
355 {
356         struct audio_stream_in *in;
357
358         DBG("");
359
360         in = calloc(1, sizeof(struct audio_stream_in));
361         if (!in)
362                 return -ENOMEM;
363
364         in->common.get_sample_rate = in_get_sample_rate;
365         in->common.set_sample_rate = in_set_sample_rate;
366         in->common.get_buffer_size = in_get_buffer_size;
367         in->common.get_channels = in_get_channels;
368         in->common.get_format = in_get_format;
369         in->common.set_format = in_set_format;
370         in->common.standby = in_standby;
371         in->common.dump = in_dump;
372         in->common.set_parameters = in_set_parameters;
373         in->common.get_parameters = in_get_parameters;
374         in->common.add_audio_effect = in_add_audio_effect;
375         in->common.remove_audio_effect = in_remove_audio_effect;
376         in->set_gain = in_set_gain;
377         in->read = in_read;
378         in->get_input_frames_lost = in_get_input_frames_lost;
379
380         *stream_in = in;
381
382         return 0;
383 }
384
385 static void audio_close_input_stream(struct audio_hw_device *dev,
386                                         struct audio_stream_in *stream_in)
387 {
388         DBG("");
389         free(stream_in);
390 }
391
392 static int audio_dump(const audio_hw_device_t *device, int fd)
393 {
394         DBG("");
395         return -ENOSYS;
396 }
397
398 static int audio_close(hw_device_t *device)
399 {
400         struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *)device;
401
402         DBG("");
403
404         pthread_mutex_lock(&close_mutex);
405         shutdown(audio_sk, SHUT_RDWR);
406         close_thread = true;
407         pthread_mutex_unlock(&close_mutex);
408
409         pthread_join(ipc_th, NULL);
410
411         free(a2dp_dev);
412         return 0;
413 }
414
415 static bool create_audio_ipc(void)
416 {
417         struct sockaddr_un addr;
418         int err;
419         int sk;
420
421         DBG("");
422
423         sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
424         if (sk < 0) {
425                 err = errno;
426                 error("audio: Failed to create socket: %d (%s)", err,
427                                                                 strerror(err));
428                 return false;
429         }
430
431         memset(&addr, 0, sizeof(addr));
432         addr.sun_family = AF_UNIX;
433
434         memcpy(addr.sun_path, BLUEZ_AUDIO_SK_PATH,
435                                         sizeof(BLUEZ_AUDIO_SK_PATH));
436
437         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
438                 err = errno;
439                 error("audio: Failed to bind socket: %d (%s)", err,
440                                                                 strerror(err));
441                 goto failed;
442         }
443
444         if (listen(sk, 1) < 0) {
445                 err = errno;
446                 error("audio: Failed to listen on the socket: %d (%s)", err,
447                                                                 strerror(err));
448                 goto failed;
449         }
450
451         audio_sk = accept(sk, NULL, NULL);
452         if (audio_sk < 0) {
453                 err = errno;
454                 error("audio: Failed to accept socket: %d (%s)", err, strerror(err));
455                 goto failed;
456         }
457
458         close(sk);
459         return true;
460
461 failed:
462         close(sk);
463         return false;
464 }
465
466 static void *ipc_handler(void *data)
467 {
468         bool done = false;
469         struct pollfd pfd;
470
471         DBG("");
472
473         while (!done) {
474                 if(!create_audio_ipc()) {
475                         error("audio: Failed to create listening socket");
476                         sleep(1);
477                         continue;
478                 }
479
480                 DBG("Audio IPC: Connected");
481
482                 /* TODO: Register ENDPOINT here */
483
484                 memset(&pfd, 0, sizeof(pfd));
485                 pfd.fd = audio_sk;
486                 pfd.events = POLLHUP | POLLERR | POLLNVAL;
487
488                 /* Check if socket is still alive. Empty while loop.*/
489                 while (poll(&pfd, 1, -1) < 0 && errno == EINTR);
490
491                 if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
492                         info("Audio HAL: Socket closed");
493                         audio_sk = -1;
494                 }
495
496                 /*Check if audio_dev is closed */
497                 pthread_mutex_lock(&close_mutex);
498                 done = close_thread;
499                 close_thread = false;
500                 pthread_mutex_unlock(&close_mutex);
501         }
502
503         info("Closing bluetooth_watcher thread");
504         return NULL;
505 }
506
507 static int audio_open(const hw_module_t *module, const char *name,
508                                                         hw_device_t **device)
509 {
510         struct a2dp_audio_dev *a2dp_dev;
511         int err;
512
513         DBG("");
514
515         if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) {
516                 error("audio: interface %s not matching [%s]", name,
517                                                 AUDIO_HARDWARE_INTERFACE);
518                 return -EINVAL;
519         }
520
521         a2dp_dev = calloc(1, sizeof(struct a2dp_audio_dev));
522         if (!a2dp_dev)
523                 return -ENOMEM;
524
525         a2dp_dev->dev.common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
526         a2dp_dev->dev.common.module = (struct hw_module_t *) module;
527         a2dp_dev->dev.common.close = audio_close;
528
529         a2dp_dev->dev.init_check = audio_init_check;
530         a2dp_dev->dev.set_voice_volume = audio_set_voice_volume;
531         a2dp_dev->dev.set_master_volume = audio_set_master_volume;
532         a2dp_dev->dev.set_mode = audio_set_mode;
533         a2dp_dev->dev.set_mic_mute = audio_set_mic_mute;
534         a2dp_dev->dev.get_mic_mute = audio_get_mic_mute;
535         a2dp_dev->dev.set_parameters = audio_set_parameters;
536         a2dp_dev->dev.get_parameters = audio_get_parameters;
537         a2dp_dev->dev.get_input_buffer_size = audio_get_input_buffer_size;
538         a2dp_dev->dev.open_output_stream = audio_open_output_stream;
539         a2dp_dev->dev.close_output_stream = audio_close_output_stream;
540         a2dp_dev->dev.open_input_stream = audio_open_input_stream;
541         a2dp_dev->dev.close_input_stream = audio_close_input_stream;
542         a2dp_dev->dev.dump = audio_dump;
543
544         /* Note that &a2dp_dev->dev.common is the same pointer as a2dp_dev.
545          * This results from the structure of following structs:a2dp_audio_dev,
546          * audio_hw_device. We will rely on this later in the code.*/
547         *device = &a2dp_dev->dev.common;
548
549         err = pthread_create(&ipc_th, NULL, ipc_handler, NULL);
550         if (err) {
551                 ipc_th = 0;
552                 error("audio: Failed to start Audio IPC thread: %d (%s)",
553                                                         err, strerror(err));
554                 return (-err);
555         }
556
557         return 0;
558 }
559
560 static struct hw_module_methods_t hal_module_methods = {
561         .open = audio_open,
562 };
563
564 struct audio_module HAL_MODULE_INFO_SYM = {
565         .common = {
566         .tag = HARDWARE_MODULE_TAG,
567         .version_major = 1,
568         .version_minor = 0,
569         .id = AUDIO_HARDWARE_MODULE_ID,
570         .name = "A2DP Bluez HW HAL",
571         .author = "Intel Corporation",
572         .methods = &hal_module_methods,
573         },
574 };