d636e382ee1c96ca2a47c8c227abaa90617de04d
[framework/api/sound-manager.git] / src / sound_manager.c
1 /*
2 * Copyright (c) 2011 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
18 #define LOG_TAG "TIZEN_N_SOUND_MANGER"
19
20 #include <sound_manager.h>
21 #include <mm_sound.h>
22 #include <mm_sound_private.h>
23 #include <stdio.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <malloc.h>
27 #include <unistd.h>
28 #include <dlog.h>
29 #include <mm_session.h>
30 #include <mm_session_private.h>
31
32 #define MAX_VOLUME_TYPE 5
33
34 typedef struct {
35         void *user_data;
36         sound_manager_volume_changed_cb user_cb;
37 }_changed_volume_info_s;
38
39 typedef struct {
40         int is_registered;
41         void *user_data;
42         sound_session_notify_cb user_cb;
43         void *interrupted_user_data;
44         sound_interrupted_cb interrupted_cb;
45 }_session_notify_info_s;
46
47 typedef struct {
48         void *user_data;
49         sound_available_route_changed_cb user_cb;
50 }_changed_available_route_info_s;
51
52 typedef struct {
53         void *user_data;
54         sound_active_device_changed_cb user_cb;
55 }_changed_active_device_info_s;
56
57 static _changed_volume_info_s g_volume_changed_cb_table;
58 static _session_notify_info_s g_session_notify_cb_table = {0, NULL, NULL, NULL, NULL};
59
60 static void __volume_changed_cb(void *user_data)
61 {
62         sound_type_e type = (sound_type_e)user_data;
63
64         int new_volume;
65         sound_manager_get_volume(type, &new_volume);
66         if(g_volume_changed_cb_table.user_cb)
67                 (g_volume_changed_cb_table.user_cb)(type, new_volume, g_volume_changed_cb_table.user_data);
68 }
69
70 static void __session_notify_cb(session_msg_t msg, session_event_t event, void *user_data){
71         if(g_session_notify_cb_table.user_cb){
72                 g_session_notify_cb_table.user_cb(msg, g_session_notify_cb_table.user_data);
73         }
74         if( g_session_notify_cb_table.interrupted_cb ){
75                 sound_interrupted_code_e e = SOUND_INTERRUPTED_COMPLETED;
76                 if( msg == MM_SESSION_MSG_RESUME )
77                         e = SOUND_INTERRUPTED_COMPLETED;
78                 else{
79                         switch(event){
80                                 case MM_SESSION_EVENT_OTHER_APP :
81                                         e = SOUND_INTERRUPTED_BY_OTHER_APP;
82                                         break;
83                                 case MM_SESSION_EVENT_CALL :
84                                         e = SOUND_INTERRUPTED_BY_CALL;
85                                         break;
86                                 case MM_SESSION_EVENT_ALARM :
87                                         e = SOUND_INTERRUPTED_BY_ALARM;
88                                         break;
89                                 case MM_SESSION_EVENT_EARJACK_UNPLUG:
90                                         e = SOUND_INTERRUPTED_BY_EARJACK_UNPLUG;
91                                         break;
92                                 case MM_SESSION_EVENT_RESOURCE_CONFLICT:
93                                         e = SOUND_INTERRUPTED_BY_RESOURCE_CONFLICT;
94                                         break;
95                                 default :
96                                         e = SOUND_INTERRUPTED_BY_OTHER_APP;
97                                         break;
98                         }
99                 }
100                 g_session_notify_cb_table.interrupted_cb(e, g_session_notify_cb_table.interrupted_user_data);
101         }
102 }
103
104 static int __convert_sound_manager_error_code(const char *func, int code){
105         int ret = SOUND_MANAGER_ERROR_NONE;
106         char *errorstr = NULL;
107
108         switch(code)
109         {
110                 case SOUND_MANAGER_ERROR_INVALID_PARAMETER:
111                         ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
112                         errorstr = "INVALID_PARAMETER";
113                         break;
114                 case MM_ERROR_NONE:
115                         ret = SOUND_MANAGER_ERROR_NONE;
116                         errorstr = "ERROR_NONE";
117                         break;
118                 case MM_ERROR_INVALID_ARGUMENT:
119                 case MM_ERROR_SOUND_INVALID_POINTER:
120                         ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
121                         errorstr = "INVALID_PARAMETER";
122                         break;
123                 case MM_ERROR_SOUND_INTERNAL:
124                         ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
125                         errorstr = "INVALID_OPERATION"  ;
126                         break;
127                 case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
128                 case MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY:
129                         ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
130                         errorstr = "NO_PLAYING_SOUND"   ;
131                         break;
132         }
133         LOGE("[%s] %s(0x%08x) : core frameworks error code(0x%08x)",func, errorstr, ret, code);
134         return ret;
135 }
136
137 int sound_manager_get_max_volume(sound_type_e type, int *max)
138 {
139         int volume;
140         if(max == NULL)
141                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
142
143         if(type > MAX_VOLUME_TYPE || type < 0)
144                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
145         int ret = mm_sound_volume_get_step(type, &volume);
146
147         if(ret == 0)
148                 *max = volume -1;       // actual volume step can be max step - 1
149
150         return __convert_sound_manager_error_code(__func__, ret);
151 }
152
153 int sound_manager_set_volume(sound_type_e type, int volume)
154 {
155         if(type > MAX_VOLUME_TYPE || type < 0)
156                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
157         if(volume < 0)
158                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
159
160         int ret = mm_sound_volume_set_value(type, volume);
161         
162         return __convert_sound_manager_error_code(__func__, ret);
163 }
164
165 int sound_manager_get_volume(sound_type_e type, int *volume)
166 {
167         unsigned int uvolume;
168         if(type > MAX_VOLUME_TYPE || type < 0)
169                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
170         if(volume == NULL)
171                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
172         int ret = mm_sound_volume_get_value(type, &uvolume);
173
174         if(ret == 0)
175                 *volume = uvolume;
176
177         return __convert_sound_manager_error_code(__func__, ret);
178 }
179
180 int sound_manager_get_current_sound_type(sound_type_e *type)
181 {
182         if(type == NULL)
183                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
184         int ret;
185         ret = mm_sound_volume_get_current_playing_type((volume_type_t *)type);
186         
187         return __convert_sound_manager_error_code(__func__, ret);
188 }
189
190 int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void* user_data)
191 {
192         if(callback == NULL)
193                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
194         int i;
195         g_volume_changed_cb_table.user_cb = callback;
196         g_volume_changed_cb_table.user_data = user_data;
197         for(i = 0 ; i <= MAX_VOLUME_TYPE ; i++)
198         {
199                 mm_sound_volume_add_callback(i , __volume_changed_cb ,(void*) i);
200         }
201         return 0;
202 }
203
204 void sound_manager_unset_volume_changed_cb(void)
205 {
206         int i;
207         for(i = 0 ; i <= MAX_VOLUME_TYPE ; i++)
208         {
209                 mm_sound_volume_remove_callback(i);
210         }
211         g_volume_changed_cb_table.user_cb = NULL;
212         g_volume_changed_cb_table.user_data = NULL;     
213 }
214
215 int sound_manager_get_a2dp_status(bool *connected , char** bt_name){
216         int ret = mm_sound_route_get_a2dp_status((int*)connected , bt_name);
217
218         return __convert_sound_manager_error_code(__func__, ret);
219 }
220
221 int sound_manager_set_session_type(sound_session_type_e type){
222         int ret = 0;
223         if(type < 0 || type >  SOUND_SESSION_TYPE_EXCLUSIVE)
224                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
225
226         if(g_session_notify_cb_table.is_registered){
227                 mm_session_finish();
228                 g_session_notify_cb_table.is_registered = 0;
229         }
230
231         ret = mm_session_init_ex(type , __session_notify_cb, NULL);
232         if(ret == 0){
233                 g_session_notify_cb_table.is_registered = 1;
234         }
235         return __convert_sound_manager_error_code(__func__, ret);
236 }
237
238 int sound_manager_set_session_notify_cb(sound_session_notify_cb callback , void *user_data){
239         int ret =0 ;
240         if(callback == NULL)
241                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
242
243
244         if(g_session_notify_cb_table.is_registered ==0){
245                 ret = mm_session_init_ex(SOUND_SESSION_TYPE_SHARE /*default*/ , __session_notify_cb, NULL);
246                 if(ret != 0)
247                         return __convert_sound_manager_error_code(__func__, ret);
248                 g_session_notify_cb_table.is_registered = 1;
249         }
250
251         g_session_notify_cb_table.user_cb = callback;
252         g_session_notify_cb_table.user_data  = user_data;
253         return SOUND_MANAGER_ERROR_NONE;
254 }
255
256 void sound_manager_unset_session_notify_cb(void){
257         g_session_notify_cb_table.user_cb = NULL;
258         g_session_notify_cb_table.user_data  = NULL;
259 }
260
261 int sound_manager_set_interrupted_cb(sound_interrupted_cb callback, void *user_data){
262         int ret =0 ;
263         if(callback == NULL)
264                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
265
266         if(g_session_notify_cb_table.is_registered ==0){
267                 ret = mm_session_init_ex(SOUND_SESSION_TYPE_SHARE /*default*/ , __session_notify_cb, NULL);
268                 if(ret != 0)
269                         return __convert_sound_manager_error_code(__func__, ret);
270                 g_session_notify_cb_table.is_registered = 1;
271         }
272
273         g_session_notify_cb_table.interrupted_cb= callback;
274         g_session_notify_cb_table.interrupted_user_data = user_data;
275         return SOUND_MANAGER_ERROR_NONE;
276 }
277
278 void sound_manager_unset_interrupted_cb(void){
279         g_session_notify_cb_table.interrupted_cb= NULL;
280         g_session_notify_cb_table.interrupted_user_data = NULL;
281 }
282
283
284 int sound_manager_set_volume_key_type(volume_key_type_e type){
285         if(type < VOLUME_KEY_TYPE_NONE || type > VOLUME_KEY_TYPE_CALL)
286                 return __convert_sound_manager_error_code(__func__, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
287         int ret;
288         if(type == VOLUME_KEY_TYPE_NONE)
289                 ret = mm_sound_volume_primary_type_clear();
290         else
291                 ret = mm_sound_volume_primary_type_set(type);
292
293         return __convert_sound_manager_error_code(__func__, ret);
294 }
295
296 int sound_manager_foreach_available_route (sound_available_route_cb callback, void *user_data)
297 {
298         int ret;
299         ret = mm_sound_foreach_available_route_cb((mm_sound_available_route_cb)callback, user_data);
300
301         return __convert_sound_manager_error_code(__func__, ret);
302 }
303
304 int sound_manager_set_active_route (sound_route_e route)
305 {
306         int ret;
307         ret = mm_sound_set_active_route(route);
308
309         return __convert_sound_manager_error_code(__func__, ret);
310 }
311
312 int sound_manager_get_active_device (sound_device_in_e *in, sound_device_out_e *out)
313 {
314         int ret;
315         ret = mm_sound_get_active_device((mm_sound_device_in *)in, (mm_sound_device_out *)out);
316
317         return __convert_sound_manager_error_code(__func__, ret);
318 }
319
320 bool sound_manager_is_route_available (sound_route_e route)
321 {
322         bool is_available;
323         mm_sound_is_route_available(route, &is_available);
324
325         return is_available;
326 }
327
328 int sound_manager_set_available_route_changed_cb (sound_available_route_changed_cb callback, void *user_data)
329 {
330         int ret;
331         ret = mm_sound_add_available_route_changed_callback((mm_sound_available_route_changed_cb)callback, user_data);
332
333         return __convert_sound_manager_error_code(__func__, ret);
334 }
335
336 void sound_manager_unset_available_route_changed_cb (void)
337 {
338         mm_sound_remove_available_route_changed_callback();
339 }
340
341 int sound_manager_set_active_device_changed_cb (sound_active_device_changed_cb callback, void *user_data)
342 {
343         int ret;
344         ret = mm_sound_add_active_device_changed_callback((mm_sound_active_device_changed_cb)callback, user_data);
345
346         return __convert_sound_manager_error_code(__func__, ret);
347 }
348
349 void sound_manager_unset_active_device_changed_cb (void)
350 {
351         mm_sound_remove_active_device_changed_callback();
352 }
353
354 struct sound_call_session_s
355 {
356         int unused;
357 };
358
359 int sound_manager_call_session_create(sound_call_session_type_e type, sound_call_session_h *session)
360 {
361         int ret = SOUND_MANAGER_ERROR_NONE;
362         sound_call_session_h handle = NULL;
363
364         if(type < SOUND_SESSION_TYPE_CALL || type > SOUND_SESSION_TYPE_VOIP || session == NULL) {
365                 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
366                 goto ERROR;
367         }
368
369     handle = malloc(sizeof(struct sound_call_session_s));
370
371         if(!handle) {
372                 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
373                 goto ERROR;
374         }
375
376     memset(handle, 0, sizeof(struct sound_call_session_s));
377
378         switch(type) {
379         case SOUND_SESSION_TYPE_CALL:
380                 ret = mm_session_init(MM_SESSION_TYPE_CALL);
381                 break;
382         case SOUND_SESSION_TYPE_VOIP:
383                 ret = mm_session_init(MM_SESSION_TYPE_VIDEOCALL);
384                 break;
385         }
386
387         if(ret != MM_ERROR_NONE)
388                 goto ERROR;
389
390         *session = handle;
391
392         return SOUND_MANAGER_ERROR_NONE;
393
394 ERROR:
395         if(handle)
396                 free(handle);
397
398         return __convert_sound_manager_error_code(__func__, ret);
399 }
400
401 int sound_manager_call_session_set_mode(sound_call_session_h session, sound_call_session_mode_e mode)
402 {
403         int ret = SOUND_MANAGER_ERROR_NONE;
404
405         if(mode < SOUND_CALL_SESSION_MODE_VOICE || mode > SOUND_CALL_SESSION_MODE_MEDIA || session == NULL) {
406                 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
407                 goto ERROR;
408         }
409
410         ret = mm_session_set_subsession ((mm_subsession_t)mode);
411
412         if(ret != MM_ERROR_NONE)
413                 goto ERROR;
414
415         return SOUND_MANAGER_ERROR_NONE;
416
417 ERROR:
418         return __convert_sound_manager_error_code(__func__, ret);
419 }
420
421 int  sound_manager_call_session_get_mode(sound_call_session_h session, sound_call_session_mode_e *mode)
422 {
423         int ret = SOUND_MANAGER_ERROR_NONE;
424
425         if(mode == NULL || session == NULL) {
426                 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
427                 goto ERROR;
428         }
429
430         ret = mm_session_get_subsession ((mm_subsession_t *)mode);
431
432         if(ret != MM_ERROR_NONE)
433                 goto ERROR;
434
435         return SOUND_MANAGER_ERROR_NONE;
436
437 ERROR:
438         return __convert_sound_manager_error_code(__func__, ret);
439 }
440
441 int sound_manager_call_session_destroy(sound_call_session_h session)
442 {
443         int ret = SOUND_MANAGER_ERROR_NONE;
444         sound_call_session_h *handle = (sound_call_session_h *)session;
445
446         if(session == NULL) {
447                 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
448                 goto ERROR;
449         }
450
451         ret = mm_session_finish();
452
453         if(ret != MM_ERROR_NONE)
454                 goto ERROR;
455
456         if(handle)
457                 free(handle);
458
459         return SOUND_MANAGER_ERROR_NONE;
460
461 ERROR:
462         return __convert_sound_manager_error_code(__func__, ret);
463 }
464