Wait for terminated state of the stream in sound_nanager_stop_virtual_stream()
[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_session.h>
40 #include <mm_session_private.h>
41 #include <mm_sound.h>
42 #include <mm_sound_focus.h>
43 #include <mm_sound_private.h>
44 #include "sound_manager_internal.h"
45
46 #define _CHECK_CONDITION(condition,error,msg)     \
47     if(condition) {} else \
48     { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \
49
50 #define SM_INSTANCE_CHECK(handle)   \
51         _CHECK_CONDITION(handle != NULL, SOUND_MANAGER_ERROR_INVALID_PARAMETER,"SOUND_MANAGER_ERROR_INVALID_PARAMETER")
52
53 #define SM_NULL_ARG_CHECK(arg)      \
54         _CHECK_CONDITION(arg != NULL,SOUND_MANAGER_ERROR_INVALID_PARAMETER,"SOUND_MANAGER_ERROR_INVALID_PARAMETER")
55
56 #define SM_STATE_CHECK(handle,expected_state)       \
57         _CHECK_CONDITION(handle->state == expected_state,SOUND_MANAGER_ERROR_INVALID_STATE,"SOUND_MANAGER_ERROR_INVALID_STATE")
58
59 #define SM_RANGE_ARG_CHECK(arg, min, max)      \
60         _CHECK_CONDITION(arg <= max,SOUND_MANAGER_ERROR_INVALID_PARAMETER,"SOUND_MANAGER_ERROR_INVALID_PARAMETER") \
61         _CHECK_CONDITION(arg >= min,SOUND_MANAGER_ERROR_INVALID_PARAMETER,"SOUND_MANAGER_ERROR_INVALID_PARAMETER")
62
63 #define SM_ENTER_CRITICAL_SECTION_WITH_RETURN(x_mutex,x_return) \
64 switch ( pthread_mutex_lock( x_mutex ) ) \
65 { \
66 case EINVAL: \
67         LOGW("try mutex init..\n"); \
68         if( 0 > pthread_mutex_init( x_mutex, NULL) ) { \
69                 return x_return; \
70         } else { \
71                 break; \
72         } \
73         return x_return; \
74 case 0: \
75         break; \
76 default: \
77         LOGE("mutex lock failed\n"); \
78         return x_return; \
79 }
80
81 #define SM_LEAVE_CRITICAL_SECTION(x_mutex) \
82 if( pthread_mutex_unlock( x_mutex ) ) { \
83         LOGE("mutex unlock failed\n"); \
84 }
85
86 #define SM_REF_FOR_STREAM_INFO(x_count, x_return) \
87 { \
88         if (!x_count) { \
89                 /* send signal to other framework to release internal focus */ \
90                 x_return = mm_sound_send_signal(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, 1); \
91         } \
92         if (x_return) \
93                 LOGW("failed to send signal for stream info creation"); \
94         else \
95                 g_stream_info_count++; \
96 } \
97
98 #define SM_UNREF_FOR_STREAM_INFO(x_count, x_return) \
99 { \
100         x_count--; \
101 } \
102
103 #define SM_STRNCPY(dst,src,size,err) \
104 do { \
105         if(src != NULL && dst != NULL && size > 0) { \
106                 strncpy(dst,src,size); \
107                 dst[size-1] = '\0'; \
108         } else if(dst == NULL) { \
109                 LOGE("STRNCPY ERROR: Destination String is NULL\n"); \
110                 err = MM_ERROR_SOUND_INTERNAL; \
111         } else if(size <= 0) { \
112                 LOGE("STRNCPY ERROR: Destination String is NULL\n"); \
113                 err = MM_ERROR_SOUND_INTERNAL; \
114         } else { \
115                 LOGE("STRNCPY ERROR: Destination String is NULL\n"); \
116                 err = MM_ERROR_SOUND_INTERNAL; \
117         } \
118 } while(0)
119
120 #define SOUND_SESSION_TYPE_DEFAULT SOUND_SESSION_TYPE_MEDIA
121 #define SOUND_STREAM_INFO_ARR_MAX 128
122 #define SOUND_STREAM_TYPE_LEN 64
123 #define SOUND_STREAM_DIRECTION_MAX 2
124 #define SOUND_DEVICE_TYPE_LEN 64
125
126 typedef enum _sound_stream_direction {
127         SOUND_STREAM_DIRECTION_OUTPUT = 1,
128         SOUND_STREAM_DIRECTION_INPUT
129 } sound_stream_direction_e;
130
131 /* it should be synchronized with pulseaudio's */
132 typedef enum stream_route_type {
133         STREAM_ROUTE_TYPE_AUTO,     /* the policy of decision device(s) is automatic and it's routing path is particular to one device */
134         STREAM_ROUTE_TYPE_AUTO_ALL, /* the policy of decision device(s) is automatic and it's routing path can be several devices */
135         STREAM_ROUTE_TYPE_MANUAL,   /* the policy of decision device(s) is manual */
136 } stream_route_type;
137 #define AVAIL_DEVICES_MAX 16
138 #define AVAIL_FRAMEWORKS_MAX 16
139 #define ROUTE_OPTIONS_MAX 16
140
141 typedef struct _stream_conf_info_s {
142         int priority;
143         int route_type;
144         gchar *avail_in_devices[AVAIL_DEVICES_MAX];
145         gchar *avail_out_devices[AVAIL_DEVICES_MAX];
146         gchar *avail_frameworks[AVAIL_FRAMEWORKS_MAX];
147 } stream_conf_info_s;
148
149 typedef struct _manual_route_info_s {
150         unsigned int route_in_devices[AVAIL_DEVICES_MAX];
151         unsigned int route_out_devices[AVAIL_DEVICES_MAX];
152 } manual_route_info_s;
153
154 typedef struct _sound_stream_info_s {
155         unsigned int index;
156         char stream_type[SOUND_STREAM_TYPE_LEN];
157         pa_threaded_mainloop *pa_mainloop;
158         pa_context *pa_context;
159         stream_conf_info_s stream_conf_info;
160         sound_stream_focus_mask_e acquired_focus;
161         sound_stream_focus_state_changed_cb user_cb;
162         void *user_data;
163         manual_route_info_s manual_route_info;
164         char *route_options[ROUTE_OPTIONS_MAX];
165 } sound_stream_info_s;
166 sound_stream_info_s *sound_stream_info_arr[SOUND_STREAM_INFO_ARR_MAX];
167
168 typedef enum {
169         _VSTREAM_STATE_READY,
170         _VSTREAM_STATE_RUNNING,
171 } _vstream_state;
172
173 typedef struct _virtual_stream_info_s {
174         _vstream_state state;
175         char stream_type[SOUND_STREAM_TYPE_LEN];
176         pa_threaded_mainloop *pa_mainloop;
177         pa_context *pa_context;
178         pa_stream *pa_stream[SOUND_STREAM_DIRECTION_MAX];
179         pa_proplist *pa_proplist;
180         stream_conf_info_s *stream_conf_info;
181 } virtual_sound_stream_info_s;
182
183 typedef enum {
184         _SESSION_MODE_RINGTONE = 0,                /**< session mode(voip/call) for ringtone */
185         _SESSION_MODE_VOICE_WITH_BUILTIN_RECEIVER, /**< session mode(voip/call) for during call with built-in receiver */
186         _SESSION_MODE_VOICE_WITH_BUILTIN_SPEAKER,  /**< session mode(voip/call) for during call with built-in speaker */
187         _SESSION_MODE_VOICE_WITH_AUDIO_JACK,       /**< session mode(voip/call) for during call with audio jack */
188         _SESSION_MODE_VOICE_WITH_BLUETOOTH,        /**< session mode(voip/call) for during call with bluetooth */
189 } _session_mode_e;
190
191 typedef struct {
192         int is_registered;
193         void *user_data;
194         sound_session_interrupted_cb user_cb;
195 }_session_interrupt_info_s;
196
197 typedef struct {
198         void *user_data;
199         sound_manager_volume_changed_cb user_cb;
200 }_volume_changed_info_s;
201
202 typedef struct {
203         int index;
204         void *user_data;
205         sound_stream_focus_state_watch_cb user_cb;
206 }_focus_watch_info_s;
207
208 typedef struct {
209         void *user_data;
210         sound_device_connected_cb user_cb;
211 }_device_connected_info_s;
212
213 typedef struct {
214         void *user_data;
215         sound_device_information_changed_cb user_cb;
216 }_device_changed_info_s;
217
218 void _focus_state_change_callback (int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data);
219
220 void _focus_watch_callback (int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason_for_change, const char *additional_info, void *user_data);
221
222 int __convert_sound_manager_error_code (const char *func, int code);
223
224 int __find_empty_slot (int *index);
225
226 int __convert_stream_type (sound_stream_type_e enum_type, char *stream_type);
227
228 int __convert_stream_type_for_internal (sound_stream_type_internal_e stream_type_enum, char *stream_type);
229
230 int __convert_stream_type_to_change_reason (const char *stream_type, sound_stream_focus_change_reason_e *change_reason);
231
232 int __convert_device_type (sound_device_type_e device_type_enum, char **device_type);
233
234 int __convert_device_type_to_enum (char *device_type, sound_device_type_e *device_type_enum);
235
236 int __convert_device_io_direction (mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction);
237
238 const char* __convert_api_name (native_api_e api_name);
239
240 int __get_stream_conf_info (const char *stream_type, stream_conf_info_s *info);
241
242 int __set_manual_route_info (unsigned int index, manual_route_info_s *info);
243
244 int __set_route_options (unsigned int index, char **route_options);
245
246 int __convert_sound_type (sound_type_e sound_type, const char **volume_type);
247
248 int __get_volume_max_level (const char *direction, const char *volume_type, unsigned int *max_level);
249
250 void _pa_context_state_cb (pa_context *c, void *userdata);
251
252 void _pa_stream_state_cb (pa_stream *s, void * userdata);
253
254 void _session_interrupt_cb (session_msg_t msg, session_event_t event, void *user_data);
255
256 int __set_session_mode (_session_mode_e mode);
257
258 int __get_session_mode (_session_mode_e *mode);
259
260 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data);
261
262 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h);
263
264 #ifdef __cplusplus
265 }
266 #endif
267
268 #endif /* __TIZEN_MEDIA_SOUND_MANAGER_PRIVATE_H__ */