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