Fix memory leak
[platform/core/multimedia/libmm-sound.git] / mm_sound_proxy.c
1 #include <stdint.h>
2 #include <glib.h>
3
4 #include <mm_error.h>
5 #include <mm_debug.h>
6
7 #include "include/mm_sound_proxy.h"
8 #include "include/mm_sound_common.h"
9 #include "include/mm_sound_dbus.h"
10 #include "include/mm_sound_intf.h"
11
12 #ifdef USE_SECURITY
13 #include <security-server.h>
14 #define COOKIE_SIZE 20
15 #endif
16
17
18 struct callback_data {
19         void *user_cb;
20         void *user_data;
21         mm_sound_proxy_userdata_free free_func;
22         uint32_t subs_id;
23 };
24
25 #define CB_DATA_NEW(_cb_data, _func, _userdata, _freefunc) \
26         do { \
27                 _cb_data = (struct callback_data*) g_malloc0(sizeof(struct callback_data)); \
28                 _cb_data->user_cb = _func; \
29                 _cb_data->user_data = _userdata; \
30                 _cb_data->free_func = _freefunc; \
31                 _cb_data->subs_id = 0; \
32         } while (0)
33
34 /* subscribe is true when add callback,
35  * false when remove callback */
36 static int _notify_subscription(audio_event_t event, uint32_t subs_id, gboolean subscribe)
37 {
38         int ret = MM_ERROR_NONE;
39         GVariant *params = NULL;
40         const char *event_name = NULL;
41
42         debug_fenter();
43
44         if ((ret = mm_sound_dbus_get_event_name(event, &event_name) != MM_ERROR_NONE)) {
45                 debug_error("Failed to get event name");
46                 return MM_ERROR_SOUND_INTERNAL;
47         }
48
49         if (!(params = g_variant_new("(sub)", event_name, subs_id, subscribe))) {
50                 debug_error("Construct Param failed");
51                 return MM_ERROR_SOUND_INTERNAL;
52         }
53
54         if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_SUBSCRIBED, params))) {
55                 debug_error("dbus send signal for client subscribed failed");
56         }
57
58         debug_fleave();
59         return ret;
60 }
61
62 static int _notify_signal_handled(audio_event_t event, uint32_t event_id, uint32_t subs_id, GVariant *signal_params)
63 {
64         int ret = MM_ERROR_NONE;
65         GVariant *params = NULL;
66         const char *event_name = NULL;
67
68         debug_fenter();
69
70         if ((ret = mm_sound_dbus_get_event_name(event, &event_name) != MM_ERROR_NONE)) {
71                 debug_error("Failed to get event name");
72                 return MM_ERROR_SOUND_INTERNAL;
73         }
74
75         if (!(params = g_variant_new("(usuv)", event_id, event_name, subs_id, signal_params))) {
76                 debug_error("Construct Param failed");
77                 return MM_ERROR_SOUND_INTERNAL;
78         }
79
80         if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_HANDLED, params))) {
81                 debug_error("dbus send signal for client handled failed");
82         }
83
84         debug_fleave();
85         return ret;
86 }
87
88 /* This callback unmarshall general-formed paramters to subject specific parameters,
89  * and call proper callback */
90 static void dbus_callback(audio_event_t event, GVariant *params, void *userdata)
91 {
92         struct callback_data *cb_data  = (struct callback_data*) userdata;
93         uint32_t event_id;
94
95         if (event == AUDIO_EVENT_VOLUME_CHANGED) {
96                 char *volume_type_str = NULL, *direction = NULL;
97                 unsigned volume_level;
98
99                 g_variant_get(params, "(&s&su)", &direction, &volume_type_str, &volume_level);
100                 ((mm_sound_volume_changed_wrapper_cb)(cb_data->user_cb))(direction, volume_type_str, volume_level, cb_data->user_data);
101         } else if (event == AUDIO_EVENT_DEVICE_CONNECTED) {
102                 const char *name = NULL, *device_type = NULL;
103                 gboolean is_connected = FALSE;
104                 int device_id, io_direction, state;
105
106                 g_variant_get(params, "(u(i&sii&s)b)", &event_id, &device_id, &device_type, &io_direction,
107                                         &state, &name, &is_connected);
108                 ((mm_sound_device_connected_wrapper_cb)(cb_data->user_cb))(device_id, device_type, io_direction, state, name, is_connected, cb_data->user_data);
109                 _notify_signal_handled(event, event_id, cb_data->subs_id, g_variant_new("(ib)", device_id, is_connected));
110         } else if (event == AUDIO_EVENT_DEVICE_INFO_CHANGED) {
111                 const char *name = NULL, *device_type = NULL;
112                 int changed_device_info_type = 0;
113                 int device_id, io_direction, state;
114
115                 g_variant_get(params, "(u(i&sii&s)i)", &event_id, &device_id, &device_type, &io_direction,
116                                         &state, &name, &changed_device_info_type);
117                 ((mm_sound_device_info_changed_wrapper_cb)(cb_data->user_cb))(device_id, device_type, io_direction, state, name, changed_device_info_type, cb_data->user_data);
118         } else if (event == AUDIO_EVENT_FOCUS_CHANGED) {
119         } else if (event == AUDIO_EVENT_FOCUS_WATCH) {
120         } else if (event == AUDIO_EVENT_TEST) {
121                 int test_var = 0;
122                 g_variant_get(params, "(i)", &test_var);
123                 ((mm_sound_test_cb)(cb_data->user_cb))(test_var, cb_data->user_data);
124         } else if (event == AUDIO_EVENT_PLAY_FILE_END) {
125                 int ended_handle = 0;
126                 g_variant_get(params, "(i)", &ended_handle);
127                 ((mm_sound_stop_callback_wrapper_func)(cb_data->user_cb))(ended_handle, cb_data->user_data);
128         }
129 }
130
131 static void simple_callback_data_free_func(void *data)
132 {
133         struct callback_data *cb_data = (struct callback_data*) data;
134
135         if (cb_data) {
136                 if (cb_data->free_func)
137                         cb_data->free_func(cb_data->user_data);
138                 g_free(cb_data);
139         }
140 }
141
142 int mm_sound_proxy_add_test_callback(mm_sound_test_cb func, void *userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
143 {
144         int ret = MM_ERROR_NONE;
145         struct callback_data *cb_data;
146
147         debug_fenter();
148
149         CB_DATA_NEW(cb_data, func, userdata, freefunc);
150
151         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_EVENT_TEST, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE)
152                 debug_error("add test callback failed");
153         else
154                 *subs_id = cb_data->subs_id;
155
156         debug_fleave();
157         return ret;
158 }
159
160 int mm_sound_proxy_remove_test_callback(unsigned subs_id)
161 {
162         int ret = MM_ERROR_NONE;
163         debug_fenter();
164
165         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
166                 debug_error("remove test callback failed");
167         }
168
169         debug_fleave();
170         return ret;
171 }
172
173 int mm_sound_proxy_test(int a, int b, int *get)
174 {
175         int ret = MM_ERROR_NONE;
176         int reply = 0;
177         GVariant *params = NULL, *result = NULL;
178
179         debug_fenter();
180
181         params = g_variant_new("(ii)", a, b);
182         if (params) {
183                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_TEST, params, &result)) != MM_ERROR_NONE) {
184                         debug_error("dbus test call failed");
185                         goto cleanup;
186                 }
187         } else {
188                 debug_error("Construct Param for method call failed");
189                 return MM_ERROR_SOUND_INTERNAL;
190         }
191
192         if (result) {
193                 g_variant_get(result, "(i)",  &reply);
194                 debug_log("reply : %d", reply);
195                 *get = reply;
196         } else {
197                 debug_error("reply null");
198         }
199
200 cleanup:
201         if (result)
202                 g_variant_unref(result);
203
204         debug_fleave();
205         return ret;
206 }
207
208 int mm_sound_proxy_get_current_connected_device_list(int device_flags, GList** device_list)
209 {
210         int ret = MM_ERROR_NONE;
211         GVariant *result = NULL, *child = NULL;
212         GVariant *params = NULL;
213         GVariantIter iter;
214         mm_sound_device_t* device_item;
215         const gchar *device_name_tmp = NULL, *device_type_tmp = NULL;
216
217         debug_fenter();
218
219         if (!device_list) {
220                 debug_error("Invalid Parameter, device_list null");
221                 ret = MM_ERROR_INVALID_ARGUMENT;
222                 goto cleanup;
223         }
224
225         params = g_variant_new("(i)", device_flags);
226
227         if (params) {
228                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_METHOD_GET_CONNECTED_DEVICE_LIST, params, &result)) != MM_ERROR_NONE) {
229                         debug_error("Get current connected device list failed");
230                         goto cleanup;
231                 }
232         } else {
233                 debug_error("Construct Param for get current connected device failed");
234                 return MM_ERROR_SOUND_INTERNAL;
235         }
236
237         child = g_variant_get_child_value(result, 0);
238         g_variant_iter_init(&iter, child);
239         while (1) {
240                 device_item = g_malloc0(sizeof(mm_sound_device_t));
241                 if (device_item && g_variant_iter_loop(&iter, "(i&sii&s)", &device_item->id, &device_type_tmp, &device_item->io_direction, &device_item->state, &device_name_tmp)) {
242                         MMSOUND_STRNCPY(device_item->name, device_name_tmp, MAX_DEVICE_NAME_NUM);
243                         MMSOUND_STRNCPY(device_item->type, device_type_tmp, MAX_DEVICE_TYPE_STR_LEN);
244                         *device_list = g_list_append(*device_list, device_item);
245                         debug_log("Added device id(%d) type(%17s) direction(%d) state(%d) name(%s)", device_item->id, device_item->type,device_item->io_direction, device_item->state, device_item->name);
246                 } else {
247                         if (device_item)
248                                 g_free(device_item);
249                         break;
250                 }
251         }
252
253 cleanup:
254         if (result)
255                 g_variant_unref(result);
256
257         debug_fleave();
258         return ret;
259 }
260
261 int mm_sound_proxy_add_device_connected_callback(int device_flags, mm_sound_device_connected_wrapper_cb func, void *userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
262 {
263         int ret = MM_ERROR_NONE;
264         struct callback_data *cb_data;
265
266         debug_fenter();
267
268         CB_DATA_NEW(cb_data, func, userdata, freefunc);
269
270         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_EVENT_DEVICE_CONNECTED, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE) {
271                 debug_error("add device connected callback failed");
272                 goto finish;
273         }
274
275         if ((ret = _notify_subscription(AUDIO_EVENT_DEVICE_CONNECTED, cb_data->subs_id, TRUE)) != MM_ERROR_NONE) {
276                 debug_error("failed to notify subscription of device connected event");
277                 goto finish;
278         }
279
280         *subs_id = cb_data->subs_id;
281
282 finish:
283         debug_fleave();
284         return ret;
285 }
286
287 int mm_sound_proxy_remove_device_connected_callback(unsigned subs_id)
288 {
289         int ret = MM_ERROR_NONE;
290         debug_fenter();
291
292         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
293                 debug_error("remove device connected callback failed");
294                 goto finish;
295         }
296
297         if ((ret = _notify_subscription(AUDIO_EVENT_DEVICE_CONNECTED, subs_id, FALSE)) != MM_ERROR_NONE)
298                 debug_error("failed to notify unsubscription of device connected event");
299
300 finish:
301         debug_fleave();
302         return ret;
303 }
304
305 int mm_sound_proxy_add_device_info_changed_callback(int device_flags, mm_sound_device_info_changed_wrapper_cb func, void* userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
306 {
307         int ret = MM_ERROR_NONE;
308         struct callback_data *cb_data;
309
310         debug_fenter();
311
312         CB_DATA_NEW(cb_data, func, userdata, freefunc);
313
314         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_EVENT_DEVICE_INFO_CHANGED, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE)
315                 debug_error("Add device info changed callback failed");
316         else
317                 *subs_id = cb_data->subs_id;
318
319         debug_fleave();
320         return ret;
321 }
322
323 int mm_sound_proxy_remove_device_info_changed_callback(unsigned subs_id)
324 {
325         int ret = MM_ERROR_NONE;
326         debug_fenter();
327
328         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
329                 debug_error("remove device info changed callback failed");
330         }
331
332         debug_fleave();
333         return ret;
334 }
335
336 int mm_sound_proxy_set_volume_by_type(const char *volume_type, const unsigned volume_level)
337 {
338         int ret = MM_ERROR_NONE;
339         char *reply = NULL, *direction = "out";
340         GVariant *params = NULL, *result = NULL;
341
342         debug_fenter();
343
344         params = g_variant_new("(ssu)", direction, volume_type, volume_level);
345         if (params) {
346                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_SET_VOLUME_LEVEL, params, &result)) != MM_ERROR_NONE) {
347                         debug_error("dbus set volume by type failed");
348                         goto cleanup;
349                 }
350         } else {
351                 debug_error("Construct Param for method call failed");
352                 return MM_ERROR_SOUND_INTERNAL;
353         }
354
355         if (result) {
356                 g_variant_get(result, "(&s)",  &reply);
357                 debug_log("reply : %s", reply);
358                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
359                         ret = MM_ERROR_SOUND_INTERNAL;
360         } else {
361                 debug_error("reply null");
362         }
363
364 cleanup:
365         if (result)
366                 g_variant_unref(result);
367
368         debug_fleave();
369         return ret;
370 }
371
372 int mm_sound_proxy_add_volume_changed_callback(mm_sound_volume_changed_wrapper_cb func, void* userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
373 {
374         int ret = MM_ERROR_NONE;
375         struct callback_data *cb_data;
376
377         debug_fenter();
378
379         CB_DATA_NEW(cb_data, func, userdata, freefunc);
380
381         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_EVENT_VOLUME_CHANGED, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE)
382                 debug_error("Add Volume changed callback failed");
383         else
384                 *subs_id = cb_data->subs_id;
385
386
387         debug_fleave();
388
389         return ret;
390 }
391
392 int mm_sound_proxy_remove_volume_changed_callback(unsigned subs_id)
393 {
394         int ret = MM_ERROR_NONE;
395         debug_fenter();
396
397         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
398                 debug_error("Remove Volume changed callback failed");
399         }
400
401         debug_fleave();
402         return ret;
403 }
404
405 int mm_sound_proxy_play_tone(int tone, int repeat, int volume, int volume_config,
406                            int session_type, int session_options, int client_pid,
407                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
408 {
409         int ret = MM_ERROR_NONE;
410         int handle = 0;
411         GVariant *params = NULL, *result = NULL;
412         gboolean _enable_session = enable_session;
413
414         if (!codechandle) {
415                 debug_error("Param for play is null");
416                 return MM_ERROR_INVALID_ARGUMENT;
417         }
418
419         debug_fenter();
420
421         params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume,
422                       volume_config, session_type, session_options, client_pid , _enable_session, stream_type, stream_index);
423         if (params) {
424                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
425                         debug_error("dbus play tone failed");
426                         goto cleanup;
427                 }
428         } else {
429                 debug_error("Construct Param for method call failed");
430         }
431
432         if (result) {
433                 g_variant_get(result, "(i)",  &handle);
434                 debug_log("handle : %d", handle);
435                 *codechandle = handle;
436         } else {
437                 debug_error("reply null");
438         }
439
440 cleanup:
441         if (result)
442                 g_variant_unref(result);
443
444         debug_fleave();
445         return ret;
446
447
448 }
449
450 int mm_sound_proxy_play_tone_with_stream_info(int client_pid, int tone, char *stream_type, int stream_index, int volume, int repeat, int *codechandle)
451 {
452         int ret = MM_ERROR_NONE;
453         int handle = 0;
454         GVariant *params = NULL, *result = NULL;
455
456         debug_fenter();
457
458         if (!codechandle) {
459                 debug_error("Param for play is null");
460                 return MM_ERROR_INVALID_ARGUMENT;
461         }
462
463         params = g_variant_new("(iiiisi)", tone, repeat, volume, client_pid, stream_type, stream_index);
464         if (params) {
465                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
466                         debug_error("dbus play tone failed");
467                         goto cleanup;
468                 }
469         } else {
470                 debug_error("Construct Param for method call failed");
471         }
472
473         if (result) {
474                 g_variant_get(result, "(i)",  &handle);
475                 debug_log("handle : %d", handle);
476                 *codechandle = handle;
477         } else {
478                 debug_error("reply null");
479         }
480
481 cleanup:
482         if (result)
483                 g_variant_unref(result);
484
485         debug_fleave();
486         return ret;
487
488
489 }
490
491 int mm_sound_proxy_play_sound(const char* filename, int tone, int repeat, int volume, int volume_config,
492                            int priority, int session_type, int session_options, int client_pid, int handle_route,
493                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
494 {
495         int ret = MM_ERROR_NONE;
496         int handle = 0;
497         GVariant *params = NULL, *result = NULL;
498         gboolean _enable_session = enable_session;
499
500         if (!filename || !codechandle) {
501                 debug_error("Param for play is null");
502                 return MM_ERROR_INVALID_ARGUMENT;
503         }
504
505         debug_fenter();
506
507         params = g_variant_new("(siiiiiiiiibsi)", filename, tone, repeat, volume,
508                       volume_config, priority, session_type, session_options, client_pid, handle_route, _enable_session, stream_type, stream_index);
509         if (params) {
510                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_FILE_START, params, &result)) != MM_ERROR_NONE) {
511                         debug_error("dbus play file failed");
512                         goto cleanup;
513                 }
514         } else {
515                 debug_error("Construct Param for method call failed");
516         }
517
518         if (result) {
519                 g_variant_get(result, "(i)",  &handle);
520                 debug_log("handle : %d", handle);
521                 *codechandle = handle;
522         } else {
523                 debug_error("reply null");
524         }
525
526 cleanup:
527         if (result)
528                 g_variant_unref(result);
529
530         debug_fleave();
531         return ret;
532 }
533
534 int mm_sound_proxy_play_sound_with_stream_info(const char* filename, int repeat, int volume,
535                                 int priority, int client_pid, int handle_route, int *codechandle, char *stream_type, int stream_index)
536 {
537         int ret = MM_ERROR_NONE;
538         int handle = 0;
539         GVariant *params = NULL, *result = NULL;
540
541         if (!filename || !codechandle) {
542                 debug_error("Param for play is null");
543                 return MM_ERROR_INVALID_ARGUMENT;
544         }
545
546         debug_fenter();
547
548         params = g_variant_new("(siiiiisi)", filename, repeat, volume,
549                         priority, client_pid, handle_route, stream_type, stream_index);
550         if (params) {
551                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_FILE_START_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
552                         debug_error("dbus play file failed");
553                         goto cleanup;
554                 }
555         } else {
556                 debug_error("Construct Param for method call failed");
557         }
558
559         if (result) {
560                 g_variant_get(result, "(i)",  &handle);
561                 debug_log("handle : %d", handle);
562                 *codechandle = handle;
563         } else {
564                 debug_error("reply null");
565         }
566
567 cleanup:
568         if (result)
569                 g_variant_unref(result);
570
571         debug_fleave();
572         return ret;
573
574
575 }
576
577
578 int mm_sound_proxy_stop_sound(int handle)
579 {
580         int ret = MM_ERROR_NONE;
581         GVariant *result = NULL;
582
583         debug_fenter();
584
585         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_FILE_STOP, g_variant_new("(i)", handle), &result)) != MM_ERROR_NONE) {
586                 debug_error("dbus stop file playing failed");
587                 goto cleanup;
588         }
589
590 cleanup:
591         if (result)
592                 g_variant_unref(result);
593
594         debug_fleave();
595         return ret;
596 }
597
598 int mm_sound_proxy_clear_focus(int pid)
599 {
600         int ret = MM_ERROR_NONE;
601         GVariant *result = NULL;
602
603         debug_fenter();
604
605         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_CLEAR_FOCUS, g_variant_new("(i)", pid), &result)) != MM_ERROR_NONE) {
606                 debug_error("dbus clear focus failed");
607         }
608
609         if (result)
610                 g_variant_unref(result);
611
612         debug_fleave();
613         return ret;
614 }
615
616 int mm_sound_proxy_add_play_sound_end_callback(mm_sound_stop_callback_wrapper_func func, void* userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
617 {
618         int ret = MM_ERROR_NONE;
619         struct callback_data *cb_data;
620
621         debug_fenter();
622
623         CB_DATA_NEW(cb_data, func, userdata, freefunc);
624
625         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_EVENT_PLAY_FILE_END, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE)
626                 debug_error("add play sound end callback failed");
627         else
628                 *subs_id = cb_data->subs_id;
629
630         debug_fleave();
631
632         return ret;
633 }
634
635 int mm_sound_proxy_remove_play_sound_end_callback(unsigned subs_id)
636 {
637         int ret = MM_ERROR_NONE;
638         debug_fenter();
639
640         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
641                 debug_error("Remove Play File End callback failed");
642         }
643
644         debug_fleave();
645         return ret;
646 }
647
648 int mm_sound_proxy_emergent_exit(int exit_pid)
649 {
650         int ret = MM_ERROR_NONE;
651         GVariant *params = NULL;
652
653         debug_fenter();
654
655         params = g_variant_new("(i)", exit_pid);
656         if (params) {
657                 if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, params)) != MM_ERROR_NONE) {
658                         debug_error("dbus emergent exit failed");
659                         goto cleanup;
660                 }
661         } else {
662                 debug_error("Construct Param for emergent exit signal failed");
663                 ret = MM_ERROR_SOUND_INTERNAL;
664         }
665
666 cleanup:
667
668         debug_fleave();
669         return ret;
670 }
671
672 /*------------------------------------------ FOCUS --------------------------------------------------*/
673 #ifdef USE_FOCUS
674
675 #ifdef SUPPORT_CONTAINER
676 #ifdef USE_SECURITY
677 char* _get_cookie(int cookie_size)
678 {
679         int retval = -1;
680         char* cookie = NULL;
681
682         if (security_server_get_cookie_size() != cookie_size) {
683                 debug_error ("[Security] security_server_get_cookie_size() != COOKIE_SIZE(%d)\n", cookie_size);
684                 return false;
685         }
686
687         cookie = (char*)malloc (cookie_size);
688
689         retval = security_server_request_cookie (cookie, cookie_size);
690         if (retval == SECURITY_SERVER_API_SUCCESS) {
691                 debug_msg ("[Security] security_server_request_cookie() returns [%d]\n", retval);
692         } else {
693                 debug_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
694         }
695
696         return cookie;
697 }
698
699 static GVariant* _get_cookie_variant ()
700 {
701         int i;
702         GVariantBuilder builder;
703         char* cookie = NULL;
704
705         cookie = _get_cookie(COOKIE_SIZE);
706
707         if (cookie == NULL)
708                 return NULL;
709
710         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
711         for (i = 0; i < COOKIE_SIZE; i++)
712                 g_variant_builder_add(&builder, "y", cookie[i]);
713
714         free(cookie);
715         return g_variant_builder_end(&builder);
716 }
717
718 #endif /* USE_SECURITY */
719 #endif /* SUPPORT_CONTAINER */
720
721 int mm_sound_proxy_get_unique_id(int *id)
722 {
723         int ret = MM_ERROR_NONE;
724         int res = 0;
725         GVariant *result = NULL;
726
727         debug_fenter();
728
729         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_UNIQUE_ID, NULL, &result)) != MM_ERROR_NONE) {
730                 debug_error("dbus get unique id failed");
731         }
732
733         if (result) {
734                 g_variant_get(result, "(i)", &res);
735                 *id = res;
736                 debug_msg("got unique id(%d)", *id);
737                 g_variant_unref(result);
738         }
739
740         debug_fleave();
741
742         return ret;
743 }
744
745 int mm_sound_proxy_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, bool is_for_session, void* userdata)
746 {
747         int ret = MM_ERROR_NONE;
748         GVariant *params = NULL, *result = NULL;
749 #ifdef SUPPORT_CONTAINER
750         char container[128];
751 #endif
752
753         debug_fenter();
754
755 #ifdef SUPPORT_CONTAINER
756 #ifdef USE_SECURITY
757         params = g_variant_new("(@ayiisb)", _get_cookie_variant(), instance, id, stream_type, is_for_session);
758 #else /* USE_SECURITY */
759         gethostname(container, sizeof(container));
760         debug_error("container = %s", container);
761         params = g_variant_new("(siisb)", container, instance, id, stream_type, is_for_session);
762 #endif /* USE_SECURITY */
763
764 #else /* SUPPORT_CONTAINER */
765         params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
766
767 #endif /* SUPPORT_CONTAINER */
768
769         if (params) {
770                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
771                         debug_error("dbus register focus failed");
772                 }
773         } else {
774                 debug_error("Construct Param for method call failed");
775         }
776
777         if (ret != MM_ERROR_NONE)
778                 g_variant_get(result, "(i)",  &ret);
779         if (result)
780                 g_variant_unref(result);
781
782         debug_fleave();
783
784         return ret;
785
786 }
787
788 int mm_sound_proxy_unregister_focus(int instance, int id, bool is_for_session)
789 {
790         int ret = MM_ERROR_NONE;
791         GVariant *params = NULL, *result = NULL;
792
793         debug_fenter();
794
795         params = g_variant_new("(iib)", instance, id, is_for_session);
796         if (params) {
797                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
798                         debug_error("dbus unregister focus failed");
799                 }
800         } else {
801                 debug_error("Construct Param for method call failed");
802         }
803
804         if (ret != MM_ERROR_NONE)
805                 g_variant_get(result, "(i)",  &ret);
806         if (result)
807                 g_variant_unref(result);
808
809         debug_fleave();
810
811         return ret;
812 }
813
814 int mm_sound_proxy_set_foucs_reacquisition(int instance, int id, bool reacquisition)
815 {
816         int ret = MM_ERROR_NONE;
817         GVariant *params = NULL, *result = NULL;
818
819         debug_fenter();
820
821         params = g_variant_new("(iib)", instance, id, reacquisition);
822         if (params) {
823                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_SET_FOCUS_REACQUISITION, params, &result)) != MM_ERROR_NONE) {
824                         debug_error("dbus set focus reacquisition failed");
825                 }
826         } else {
827                 debug_error("Construct Param for method call failed");
828         }
829
830         if (ret != MM_ERROR_NONE)
831                 g_variant_get(result, "(i)",  &ret);
832         if (result)
833                 g_variant_unref(result);
834
835         debug_fleave();
836         return ret;
837 }
838
839 int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_type, char **additional_info)
840 {
841         int ret = MM_ERROR_NONE;
842         GVariant *params = NULL, *result = NULL;
843
844         debug_fenter();
845
846         if (!(params = g_variant_new("(i)", focus_type))) {
847                 debug_error("Construct Param for method call failed");
848                 return MM_ERROR_SOUND_INTERNAL;
849         }
850
851         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE, params, &result)) == MM_ERROR_NONE) {
852                 if (result) {
853                         g_variant_get(result, "(ss)", stream_type, additional_info);
854                         g_variant_unref(result);
855                 }
856         } else {
857                 debug_error("dbus get stream type of acquired focus failed");
858         }
859
860         debug_fleave();
861         return ret;
862 }
863
864 int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
865 {
866         int ret = MM_ERROR_NONE;
867         GVariant *params = NULL, *result = NULL;
868
869         debug_fenter();
870
871         params = g_variant_new("(iiisb)", instance, id, type, option ? option : "", is_for_session);
872         if (params) {
873                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE) {
874                         debug_error("dbus acquire focus failed");
875                 }
876         } else {
877                 debug_error("Construct Param for method call failed");
878         }
879
880         if (ret != MM_ERROR_NONE)
881                 g_variant_get(result, "(i)",  &ret);
882         if (result)
883                 g_variant_unref(result);
884
885         debug_fleave();
886         return ret;
887 }
888
889 int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
890 {
891         int ret = MM_ERROR_NONE;
892         GVariant *params = NULL, *result = NULL;
893
894         debug_fenter();
895
896         params = g_variant_new("(iiisb)", instance, id, type, option ? option : "", is_for_session);
897         if (params) {
898                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE) {
899                         debug_error("dbus release focus failed");
900                 }
901         } else {
902                 debug_error("Construct Param for method call failed");
903         }
904
905         if (ret != MM_ERROR_NONE)
906                 g_variant_get(result, "(i)",  &ret);
907         if (result)
908                 g_variant_unref(result);
909
910         debug_fleave();
911         return ret;
912 }
913
914 int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void* userdata)
915 {
916         int ret = MM_ERROR_NONE;
917         GVariant *params = NULL, *result = NULL;
918 #ifdef SUPPORT_CONTAINER
919         char container[128];
920 #endif
921
922         debug_fenter();
923 #ifdef SUPPORT_CONTAINER
924 #ifdef USE_SECURITY
925         params = g_variant_new("(@ayiiib)", _get_cookie_variant(), instance, handle, type, is_for_session);
926 #else /* USE_SECURITY */
927         gethostname(container, sizeof(container));
928         debug_error("container = %s", container);
929         params = g_variant_new("(siiib)", container, instance, handle, type, is_for_session);
930 #endif /* USE_SECURITY */
931
932 #else /* SUPPORT_CONTAINER */
933         params = g_variant_new("(iiib)", instance, handle, type, is_for_session);
934 #endif /* SUPPORT_CONTAINER */
935
936         if (params) {
937                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
938                         debug_error("dbus set watch focus failed");
939                 }
940         } else {
941                 debug_error("Construct Param for method call failed");
942         }
943
944         if (ret != MM_ERROR_NONE)
945                 g_variant_get(result, "(i)",  &ret);
946         if (result)
947                 g_variant_unref(result);
948         debug_fleave();
949
950         return ret;
951
952 }
953
954 int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session)
955 {
956         int ret = MM_ERROR_NONE;
957         GVariant *params = NULL, *result = NULL;
958
959         debug_fenter();
960
961         params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
962         if (params) {
963                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
964                         debug_error("dbus unset watch focus failed");
965                 }
966         } else {
967                 debug_error("Construct Param for method call failed");
968         }
969         if (ret != MM_ERROR_NONE)
970                 g_variant_get(result, "(i)",  &ret);
971         if (result)
972                 g_variant_unref(result);
973
974         debug_fleave();
975
976         return ret;
977 }
978
979 #endif /* USE_FOCUS */
980 /*------------------------------------------ FOCUS --------------------------------------------------*/
981
982 int mm_sound_proxy_initialize(void)
983 {
984         int ret = MM_ERROR_NONE;
985
986         debug_fenter();
987         debug_fleave();
988
989         return ret;
990 }
991
992 int mm_sound_proxy_finalize(void)
993 {
994         int ret = MM_ERROR_NONE;
995
996         debug_fenter();
997         debug_fleave();
998
999         return ret;
1000 }