Add new APIs to set or get preferred built-in device
[platform/core/api/sound-manager.git] / include / sound_manager_private.h
1 /*
2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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 #ifndef __TIZEN_MEDIA_SOUND_MANAGER_PRIVATE_H__
18 #define __TIZEN_MEDIA_SOUND_MANAGER_PRIVATE_H__
19
20 #ifdef __cplusplus
21 extern "C"
22 {
23 #endif
24 #define LOG_TAG "TIZEN_N_SOUND_MANAGER"
25
26 #include <stdio.h>
27 #include <limits.h>
28 #include <string.h>
29 #include <malloc.h>
30 #include <unistd.h>
31 #include <dlog.h>
32 #include <pulse/error.h>
33 #include <pulse/proplist.h>
34 #include <pulse/channelmap.h>
35 #include <pulse/pulseaudio.h>
36
37 #include <gio/gio.h>
38 #include <glib.h>
39 #include <mm_sound.h>
40 #include <mm_sound_focus.h>
41 #include <mm_sound_private.h>
42 #include "sound_manager_internal.h"
43
44 #define _CHECK_CONDITION(condition, error, msg)     \
45 if (condition) { \
46 } else { \
47         LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); \
48         return error; \
49 }; \
50
51 #define SM_INSTANCE_CHECK(handle) \
52 _CHECK_CONDITION(handle != NULL, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
53
54 #define SM_NULL_ARG_CHECK(arg) \
55 _CHECK_CONDITION(!!(arg) != false, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
56
57 #define SM_STATE_CHECK(handle, expected_state) \
58 _CHECK_CONDITION(handle->state == expected_state, SOUND_MANAGER_ERROR_INVALID_STATE, "SOUND_MANAGER_ERROR_INVALID_STATE")
59
60 #define SM_RANGE_ARG_CHECK(arg, min, max) \
61 _CHECK_CONDITION(arg <= max, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER") \
62 _CHECK_CONDITION(arg >= min, SOUND_MANAGER_ERROR_INVALID_PARAMETER, "SOUND_MANAGER_ERROR_INVALID_PARAMETER")
63
64 #define SM_INSTANCE_CHECK_FOR_PRIV(handle) \
65 _CHECK_CONDITION(handle != NULL, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUMENT")
66
67 #define SM_NULL_ARG_CHECK_FOR_PRIV(arg) \
68 _CHECK_CONDITION(!!(arg) != false, MM_ERROR_INVALID_ARGUMENT, "MM_ERROR_INVALID_ARGUMENT")
69
70 #define SM_STATE_CHECK_FOR_PRIV(handle, expected_state) \
71 _CHECK_CONDITION(handle->state == expected_state, MM_ERROR_SOUND_INVALID_STATE, "MM_ERROR_SOUND_INVALID_STATE")
72
73 #define SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(x_mutex, x_mutex_to_unlock, x_return) \
74 switch (pthread_mutex_lock(x_mutex)) { \
75 case EINVAL: \
76         LOGW("try mutex init.."); \
77         if (pthread_mutex_init(x_mutex, NULL)) { \
78                 if (pthread_mutex_unlock(x_mutex_to_unlock)) \
79                         LOGE("mutex unlock failed"); \
80                 return x_return; \
81         } else { \
82                 if (pthread_mutex_lock(x_mutex)) { \
83                         LOGE("mutex lock failed"); \
84                         if (pthread_mutex_unlock(x_mutex_to_unlock)) \
85                                 LOGE("mutex unlock failed"); \
86                         return x_return; \
87                 } \
88                 break; \
89         } \
90         if (pthread_mutex_unlock(x_mutex_to_unlock)) \
91                 LOGE("mutex unlock failed"); \
92         return x_return; \
93 case 0: \
94         break; \
95 default: \
96         LOGE("mutex lock failed"); \
97         if (pthread_mutex_unlock(x_mutex_to_unlock)) \
98                 LOGE("mutex unlock failed"); \
99         return x_return; \
100 }
101
102 #define SM_ENTER_CRITICAL_SECTION_WITH_RETURN(x_mutex, x_return) \
103 switch (pthread_mutex_lock(x_mutex)) { \
104 case EINVAL: \
105         LOGW("try mutex init.."); \
106         if (pthread_mutex_init(x_mutex, NULL)) { \
107                 return x_return; \
108         } else { \
109                 if (pthread_mutex_lock(x_mutex)) { \
110                         LOGE("mutex lock failed"); \
111                         return x_return; \
112                 } \
113                 break; \
114         } \
115         return x_return; \
116 case 0: \
117         break; \
118 default: \
119         LOGE("mutex lock failed"); \
120         return x_return; \
121 }
122
123 #define SM_ENTER_CRITICAL_SECTION(x_mutex) \
124 switch (pthread_mutex_lock(x_mutex)) { \
125 case EINVAL: \
126         LOGW("try mutex init.."); \
127         if (pthread_mutex_init(x_mutex, NULL)) { \
128                 return; \
129         } else { \
130                 if (pthread_mutex_lock(x_mutex)) { \
131                         LOGE("mutex lock failed"); \
132                         return; \
133                 } \
134                 break; \
135         } \
136         return; \
137 case 0: \
138         break; \
139 default: \
140         LOGE("mutex lock failed"); \
141         return; \
142 }
143
144 #define SM_LEAVE_CRITICAL_SECTION(x_mutex) \
145 if (pthread_mutex_unlock(x_mutex)) { \
146         LOGE("mutex unlock failed"); \
147 }
148
149 #define SM_SAFE_FREE(x_val) do { \
150         if (x_val) { \
151                 free(x_val); \
152                 x_val = NULL; \
153         } \
154 } while (0)
155
156 #define SOUND_SESSION_TYPE_DEFAULT SOUND_SESSION_TYPE_MEDIA
157 #define SOUND_STREAM_INFO_ARR_MAX 128
158 #define SOUND_STREAM_TYPE_LEN 64
159 #define SOUND_STREAM_DIRECTION_MAX 2
160 #define SOUND_DEVICE_TYPE_LEN 64
161 #define SOUND_SAMPLE_FORMAT_LEN 12
162 #define SOUND_DUCKING_ARR_MAX 128
163
164 #define DIRECTION_OUT_STR         "out"
165 #define SOUND_TYPE_MASTER_STR     "master"
166
167 typedef enum _sound_stream_direction {
168         SOUND_STREAM_DIRECTION_OUTPUT = 1,
169         SOUND_STREAM_DIRECTION_INPUT
170 } sound_stream_direction_e;
171
172 /* it should be synchronized with pulseaudio's */
173 typedef enum stream_route_type {
174         STREAM_ROUTE_TYPE_AUTO,               /* A stream is routed automatically to a particular device which has the highest priority. */
175         STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED,/* A stream is routed automatically to a particular device which has the latest connection time. */
176         STREAM_ROUTE_TYPE_AUTO_ALL,           /* A stream is routed automatically to several devices simultaneously. */
177         STREAM_ROUTE_TYPE_MANUAL,             /* A stream is routed manually to the device(s) selected by user. */
178         STREAM_ROUTE_TYPE_MANUAL_EXT,         /* A stream is routed manually to the external device(s) selected by user. */
179 } stream_route_type;
180 #define AVAIL_DEVICES_MAX 16
181 #define AVAIL_FRAMEWORKS_MAX 16
182
183 typedef struct _stream_conf_info_s {
184         int priority;
185         int route_type;
186         char *volume_type;
187         char *avail_in_devices[AVAIL_DEVICES_MAX];
188         char *avail_out_devices[AVAIL_DEVICES_MAX];
189         char *avail_frameworks[AVAIL_FRAMEWORKS_MAX];
190 } stream_conf_info_s;
191
192 typedef struct _manual_route_info_s {
193         unsigned int route_in_devices[AVAIL_DEVICES_MAX];
194         unsigned int route_out_devices[AVAIL_DEVICES_MAX];
195         bool is_set;
196 } manual_route_info_s;
197
198 typedef struct _sound_pa_info_s {
199         pa_threaded_mainloop *mainloop;
200         pa_context *context;
201         unsigned int index;
202 } sound_pa_info_s;
203
204 typedef struct _preferred_device_info_s {
205         int in;
206         int out;
207 } preferred_device_info_s;
208
209 typedef struct _sound_stream_info_s {
210         int focus_id;
211         char *stream_type;
212         bool is_focus_unavailable;
213         bool is_requesting;
214         sound_pa_info_s pa_info;
215         stream_conf_info_s stream_conf_info;
216         unsigned int prev_acquired_focus;
217         unsigned int acquired_focus;
218         sound_stream_focus_state_changed_cb user_cb;
219         void *user_data;
220         manual_route_info_s manual_route_info;
221         preferred_device_info_s preferred_device_info;
222         pthread_mutex_t focus_state_mutex;
223         pthread_mutex_t focus_cb_mutex;
224 } sound_stream_info_s;
225
226 typedef struct _sound_stream_ducking_s {
227         char *target_stream;
228         bool is_ducked;
229         unsigned int duration;
230         double ratio;
231         sound_pa_info_s pa_info;
232         sound_stream_ducking_state_changed_cb user_cb;
233         void *user_data;
234 } sound_stream_ducking_s;
235
236 typedef enum {
237         _VSTREAM_STATE_READY,
238         _VSTREAM_STATE_RUNNING,
239 } _vstream_state;
240
241 typedef struct _virtual_stream_info_s {
242         _vstream_state state;
243         char *stream_type;
244         pa_threaded_mainloop *pa_mainloop;
245         pa_context *pa_context;
246         pa_stream *pa_stream[SOUND_STREAM_DIRECTION_MAX];
247         pa_proplist *pa_proplist;
248         sound_stream_info_s *stream_info;
249 } virtual_sound_stream_info_s;
250
251 typedef struct {
252         int id;
253         void *user_data;
254         sound_stream_focus_state_watch_cb user_cb;
255 } _focus_watch_info_s;
256
257 void _voip_focus_state_change_callback(sound_stream_info_h stream_info,
258                                                                         sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state,
259                                                                         sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data);
260
261 void _focus_state_change_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, int option, const char *extra_info, void *user_data);
262
263 void _focus_watch_callback(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, const char *extra_info, void *user_data);
264
265 int _convert_error_from_dbus_error(const char *error_msg);
266
267 int _convert_sound_manager_error_code(const char *func, int code);
268
269 int _convert_stream_type(sound_stream_type_e enum_type, char **stream_type);
270
271 int _convert_stream_type_for_internal(sound_stream_type_internal_e stream_type_enum, char **stream_type);
272
273 void _set_focus_availability(sound_stream_info_s *stream_info);
274
275 int _convert_stream_type_to_change_reason(const char *stream_type, sound_stream_focus_change_reason_e *change_reason);
276
277 int _convert_device_type_enum_to_str(sound_device_type_e device_type, char **device_type_str);
278
279 int _convert_device_type(mm_sound_device_type_e device_type, sound_device_type_e *sound_device_type);
280
281 int _convert_device_type_str_to_enum(const char *device_type_str, sound_device_type_e *device_type);
282
283 int _convert_device_io_direction(mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction);
284
285 const char* _convert_api_name(native_api_e api_name);
286
287 int _return_val_if_not_usb_device(sound_device_h device, int ret_val);
288
289 int _get_stream_conf_info(const char *stream_type, stream_conf_info_s *info);
290
291 int _set_manual_route_info(unsigned int index, manual_route_info_s *info);
292
293 int _set_route_option(unsigned int index, const char *key, int value);
294
295 int _convert_sound_type(sound_type_e sound_type, const char **volume_type);
296
297 int _convert_sound_type_to_enum(const char *sound_type, sound_type_e *sound_type_enum);
298
299 int _get_volume_max_level(const char *direction, const char *volume_type, unsigned int *max_level);
300
301 int _get_volume_level(const char *direction, const char *volume_type, unsigned int *level);
302
303 int _set_volume_level(const char *direction, const char *volume_type, unsigned int level);
304
305 int _get_current_volume_type(const char *direction, char **volume_type);
306
307 int _get_current_media_routing_path(const char *direction, sound_device_type_e *device_type);
308
309 void _update_focus_status(unsigned int index, unsigned int acquired_focus_status);
310
311 int _is_device_running_by_id(int device_id, bool *is_running);
312
313 int _get_supported_sample_formats(int device_id, sound_sample_format_e **formats, unsigned int *num);
314
315 int _set_sample_format(int device_id, sound_sample_format_e format);
316
317 int _get_sample_format(int device_id, sound_sample_format_e *format);
318
319 int _get_supported_sample_rates(int device_id, sound_sample_rate_e **rates, unsigned int *num);
320
321 int _set_sample_rate(int device_id, sound_sample_rate_e rate);
322
323 int _get_sample_rate(int device_id, sound_sample_rate_e *rate);
324
325 int _set_avoid_resampling(int device_id, bool enable);
326
327 int _get_avoid_resampling(int device_id, bool *enabled);
328
329 int _set_media_stream_only(int device_id, bool enable);
330
331 int _get_media_stream_only(int device_id, bool *enabled);
332
333 void _pa_context_state_cb(pa_context *c, void *userdata);
334
335 void _pa_stream_state_cb(pa_stream *s, void * userdata);
336
337 int _make_pa_connection(sound_pa_info_s *pa_info, const char *context_name);
338
339 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data);
340
341 void _destroy_pa_connection(sound_pa_info_s *pa_info);
342
343 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h);
344
345 int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device);
346
347 int _remove_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device);
348
349 int _remove_all_devices_for_stream_routing(sound_stream_info_s *stream_info);
350
351 int _add_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id);
352
353 int _remove_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id);
354
355 int _apply_stream_routing(sound_stream_info_s *stream_info);
356
357 int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream);
358
359 int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
360
361 int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
362
363 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream);
364
365 int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio);
366
367 int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio);
368
369 int _set_acm_master_mode(bool on);
370
371 int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio);
372
373 int _get_ducking_state(uint32_t stream_index, bool *is_ducked);
374
375 int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device);
376
377 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id);
378
379 #ifdef __cplusplus
380 }
381 #endif
382
383 #endif /* __TIZEN_MEDIA_SOUND_MANAGER_PRIVATE_H__ */