d36e7eaf14697da1448c215791b1b3fa0f739d7e
[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 #include "include/mm_sound_focus_socket.h"
12
13 struct callback_data {
14         void *user_cb;
15         void *user_data;
16         mm_sound_proxy_userdata_free free_func;
17         uint32_t subs_id;
18 };
19
20 #define CB_DATA_NEW(_cb_data, _func, _userdata, _freefunc) \
21         do { \
22                 _cb_data = (struct callback_data*) g_malloc0(sizeof(struct callback_data)); \
23                 _cb_data->user_cb = _func; \
24                 _cb_data->user_data = _userdata; \
25                 _cb_data->free_func = _freefunc; \
26                 _cb_data->subs_id = 0; \
27         } while (0)
28
29 /* subscribe is true when add callback,
30  * false when remove callback */
31 static int _notify_subscription(audio_event_t event, uint32_t subs_id, gboolean subscribe)
32 {
33         int ret = MM_ERROR_NONE;
34         GVariant *params = NULL;
35         const char *event_name = NULL;
36
37         debug_fenter();
38
39         if ((ret = mm_sound_dbus_get_event_name(event, &event_name) != MM_ERROR_NONE)) {
40                 debug_error("Failed to get event name");
41                 return MM_ERROR_SOUND_INTERNAL;
42         }
43
44         if (!(params = g_variant_new("(sub)", event_name, subs_id, subscribe))) {
45                 debug_error("Construct Param failed");
46                 return MM_ERROR_SOUND_INTERNAL;
47         }
48
49         if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_SUBSCRIBED, params)))
50                 debug_error("dbus send signal for client subscribed failed");
51
52         debug_fleave();
53         return ret;
54 }
55
56 static int _notify_signal_handled(audio_event_t event, uint32_t event_id, uint32_t subs_id, GVariant *signal_params)
57 {
58         int ret = MM_ERROR_NONE;
59         GVariant *params = NULL;
60         const char *event_name = NULL;
61
62         debug_fenter();
63
64         if ((ret = mm_sound_dbus_get_event_name(event, &event_name) != MM_ERROR_NONE)) {
65                 debug_error("Failed to get event name");
66                 return MM_ERROR_SOUND_INTERNAL;
67         }
68
69         if (!(params = g_variant_new("(usuv)", event_id, event_name, subs_id, signal_params))) {
70                 debug_error("Construct Param failed");
71                 return MM_ERROR_SOUND_INTERNAL;
72         }
73
74         if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_CLIENT_HANDLED, params))) {
75                 debug_error("dbus send signal for client handled failed");
76         }
77
78         debug_fleave();
79         return ret;
80 }
81
82 static int parse_device_variant(GVariant *v, int *device_id, const char **device_type, int *direction, int *state,
83                                                                 const char **device_name, int *stream_id, int *stream_num)
84 {
85         const char *v_type;
86         GVariant *array_v;
87         GVariantIter iter, array_iter;
88         int i = 0;
89         int ret = MM_ERROR_NONE;
90
91         if (v == NULL) {
92                 debug_error("Variant NULL");
93                 return MM_ERROR_NONE;
94         }
95
96         v_type = g_variant_get_type_string(v);
97         if (g_variant_type_equal(v_type, "(isiisai)") == FALSE) {
98                 debug_error("device variant type not matching '%s'", v_type);
99                 return MM_ERROR_NONE;
100         }
101
102         g_variant_iter_init(&iter, v);
103         g_variant_iter_next(&iter, "i", device_id);
104         g_variant_iter_next(&iter, "&s", device_type);
105         g_variant_iter_next(&iter, "i", direction);
106         g_variant_iter_next(&iter, "i", state);
107         g_variant_iter_next(&iter, "&s", device_name);
108
109         array_v = g_variant_iter_next_value(&iter);
110         *stream_num = g_variant_iter_init(&array_iter, array_v);
111         if (*stream_num > MAX_STREAM_ON_DEVICE) {
112                 debug_error("too many streams on device %d", *stream_num);
113                 ret = MM_ERROR_SOUND_INTERNAL;
114                 goto finish;
115         }
116
117         while (g_variant_iter_loop(&array_iter, "i", &stream_id[i++])) ;
118 finish:
119         g_variant_unref(array_v);
120
121         return ret;
122 }
123
124 /* This callback unmarshall general-formed paramters to subject specific parameters,
125  * and call proper callback */
126 static void dbus_callback(audio_event_t event, GVariant *params, void *userdata)
127 {
128         struct callback_data *cb_data  = (struct callback_data*) userdata;
129         uint32_t event_id;
130         const char *name = NULL, *device_type = NULL;
131         int device_id, direction, state;
132         const gchar *v_type;
133         GVariantIter iter;
134         GVariant *device_v;
135         int stream_id[MAX_STREAM_ON_DEVICE];
136         int stream_num;
137
138         v_type = g_variant_get_type_string(params);
139
140         if (event == AUDIO_EVENT_VOLUME_CHANGED) {
141                 char *volume_type_str = NULL, *direction = NULL;
142                 unsigned volume_level;
143
144                 g_variant_get(params, "(&s&su)", &direction, &volume_type_str, &volume_level);
145                 ((mm_sound_volume_changed_wrapper_cb)(cb_data->user_cb))(direction, volume_type_str, volume_level, cb_data->user_data);
146         } else if (event == AUDIO_EVENT_DEVICE_CONNECTED) {
147                 gboolean is_connected = FALSE;
148
149                 if (g_variant_type_equal(v_type, "(u(isiisai)b)") == FALSE) {
150                         debug_error("Device connection changed signature not matching : %s", v_type);
151                         return ;
152                 }
153                 g_variant_iter_init(&iter, params);
154                 g_variant_iter_next(&iter, "u", &event_id);
155                 device_v = g_variant_iter_next_value(&iter);
156                 if (parse_device_variant(device_v, &device_id, &device_type, &direction, &state,
157                                                         &name, stream_id, &stream_num) < 0) {
158                         debug_error("Failed to parse device variant");
159                         return ;
160                 }
161                 g_variant_iter_next(&iter, "b", &is_connected);
162
163                 ((mm_sound_device_connected_wrapper_cb)(cb_data->user_cb))(device_id, device_type, direction,
164                         state, name, stream_id, stream_num, is_connected, cb_data->user_data);
165                 _notify_signal_handled(event, event_id, cb_data->subs_id, g_variant_new("(ib)", device_id, is_connected));
166         } else if (event == AUDIO_EVENT_DEVICE_INFO_CHANGED) {
167                 int changed_device_info_type = 0;
168
169                 if (g_variant_type_equal(v_type, "(u(isiisai)i)") == FALSE) {
170                         debug_error("Device information changed signature not matching : %s", v_type);
171                         return ;
172                 }
173
174                 g_variant_iter_init(&iter, params);
175                 g_variant_iter_next(&iter, "u", &event_id);
176                 device_v = g_variant_iter_next_value(&iter);
177                 if (parse_device_variant(device_v, &device_id, &device_type, &direction, &state,
178                                                         &name, stream_id, &stream_num) < 0) {
179                         debug_error("Failed to parse device variant");
180                         return ;
181                 }
182                 g_variant_iter_next(&iter, "i", &changed_device_info_type);
183
184                 ((mm_sound_device_info_changed_wrapper_cb)(cb_data->user_cb))(device_id, device_type, direction,
185                         state, name, stream_id, stream_num, changed_device_info_type, cb_data->user_data);
186         } else if (event == AUDIO_EVENT_DEVICE_STATE_CHANGED) {
187
188                 if (g_variant_type_equal(v_type, "(u(isiisai))") == FALSE) {
189                         debug_error("Device state changed signature not matching : %s", v_type);
190                         return ;
191                 }
192
193                 g_variant_iter_init(&iter, params);
194                 g_variant_iter_next(&iter, "u", &event_id);
195                 device_v = g_variant_iter_next_value(&iter);
196                 if (parse_device_variant(device_v, &device_id, &device_type, &direction, &state,
197                                                         &name, stream_id, &stream_num) < 0) {
198                         debug_error("Failed to parse device variant");
199                         return ;
200                 }
201
202                 ((mm_sound_device_state_changed_wrapper_cb)(cb_data->user_cb))(device_id, device_type, direction,
203                         state, name, stream_id, stream_num, cb_data->user_data);
204         } else if (event == AUDIO_EVENT_FOCUS_CHANGED) {
205         } else if (event == AUDIO_EVENT_FOCUS_WATCH) {
206         } else if (event == AUDIO_EVENT_TEST) {
207                 int test_var = 0;
208                 g_variant_get(params, "(i)", &test_var);
209                 ((mm_sound_test_cb)(cb_data->user_cb))(test_var, cb_data->user_data);
210         } else if (event == AUDIO_EVENT_PLAY_FILE_END) {
211                 int ended_handle = 0;
212                 g_variant_get(params, "(i)", &ended_handle);
213                 ((mm_sound_stop_callback_wrapper_func)(cb_data->user_cb))(ended_handle, cb_data->user_data);
214         }
215 }
216
217 static void simple_callback_data_free_func(void *data)
218 {
219         struct callback_data *cb_data = (struct callback_data*) data;
220
221         if (cb_data) {
222                 if (cb_data->free_func)
223                         cb_data->free_func(cb_data->user_data);
224                 g_free(cb_data);
225         }
226 }
227
228 int mm_sound_proxy_add_test_callback(mm_sound_test_cb func, void *userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
229 {
230         int ret = MM_ERROR_NONE;
231         struct callback_data *cb_data;
232
233         debug_fenter();
234
235         CB_DATA_NEW(cb_data, func, userdata, freefunc);
236
237         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)
238                 debug_error("add test callback failed");
239         else
240                 *subs_id = cb_data->subs_id;
241
242         debug_fleave();
243         return ret;
244 }
245
246 int mm_sound_proxy_remove_test_callback(unsigned subs_id)
247 {
248         int ret = MM_ERROR_NONE;
249         debug_fenter();
250
251         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
252                 debug_error("remove test callback failed");
253
254         debug_fleave();
255         return ret;
256 }
257
258 int mm_sound_proxy_test(int a, int b, int *get)
259 {
260         int ret = MM_ERROR_NONE;
261         int reply = 0;
262         GVariant *params = NULL, *result = NULL;
263
264         debug_fenter();
265
266         params = g_variant_new("(ii)", a, b);
267         if (params) {
268                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_TEST, params, &result)) != MM_ERROR_NONE) {
269                         debug_error("dbus test call failed");
270                         goto cleanup;
271                 }
272         } else {
273                 debug_error("Construct Param for method call failed");
274                 return MM_ERROR_SOUND_INTERNAL;
275         }
276
277         if (result) {
278                 g_variant_get(result, "(i)",  &reply);
279                 debug_log("reply : %d", reply);
280                 *get = reply;
281         } else {
282                 debug_error("reply null");
283         }
284
285 cleanup:
286         if (result)
287                 g_variant_unref(result);
288
289         debug_fleave();
290         return ret;
291 }
292
293 int mm_sound_proxy_is_stream_on_device(int stream_id, int device_id, bool *is_on)
294 {
295         int ret = MM_ERROR_NONE;
296         GVariant *params, *result;
297         gboolean _is_on;
298
299         debug_fenter();
300
301         if (!is_on) {
302                 debug_error("Invalid Parameter, is_on null");
303                 return MM_ERROR_INVALID_ARGUMENT;
304         }
305
306         if ((params = g_variant_new("(ii)", stream_id, device_id)) == NULL) {
307                 debug_error("Construct Param for query is stream on device failed");
308                 return MM_ERROR_SOUND_INTERNAL;
309         }
310
311         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_METHOD_IS_STREAM_ON_DEVICE, params, &result)) != MM_ERROR_NONE) {
312                 debug_error("is stream on device failed");
313                 goto cleanup;
314         }
315
316         if (result) {
317                 g_variant_get(result, "(b)",  &_is_on);
318                 debug_log("is_on : %d", _is_on);
319                 *is_on = (bool)_is_on;
320         } else {
321                 debug_error("reply null");
322                 ret = MM_ERROR_SOUND_INTERNAL;
323         }
324
325 cleanup:
326         if (params)
327                 g_variant_unref(params);
328         if (result)
329                 g_variant_unref(result);
330
331         debug_fleave();
332         return ret;
333 }
334
335 int mm_sound_proxy_get_current_connected_device_list(int device_flags, GList** device_list)
336 {
337         int ret = MM_ERROR_NONE;
338         GVariant *result = NULL, *child = NULL;
339         GVariant *params = NULL;
340         GVariantIter iter;
341         mm_sound_device_t* device_item;
342         const gchar *device_name_tmp = NULL, *device_type_tmp = NULL;
343
344         debug_fenter();
345
346         if (!device_list) {
347                 debug_error("Invalid Parameter, device_list null");
348                 ret = MM_ERROR_INVALID_ARGUMENT;
349                 goto cleanup;
350         }
351
352         params = g_variant_new("(i)", device_flags);
353
354         if (params) {
355                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_METHOD_GET_CONNECTED_DEVICE_LIST, params, &result)) != MM_ERROR_NONE) {
356                         debug_error("Get current connected device list failed");
357                         goto cleanup;
358                 }
359         } else {
360                 debug_error("Construct Param for get current connected device failed");
361                 return MM_ERROR_SOUND_INTERNAL;
362         }
363
364         child = g_variant_get_child_value(result, 0);
365         g_variant_iter_init(&iter, child);
366         while (1) {
367                 device_item = g_malloc0(sizeof(mm_sound_device_t));
368                 if (device_item && g_variant_iter_loop(&iter, "(i&sii&s)",
369                                         &device_item->id, &device_type_tmp, &device_item->io_direction, &device_item->state,
370                                         &device_name_tmp)) {
371                         MMSOUND_STRNCPY(device_item->name, device_name_tmp, MAX_DEVICE_NAME_NUM);
372                         MMSOUND_STRNCPY(device_item->type, device_type_tmp, MAX_DEVICE_TYPE_STR_LEN);
373                         *device_list = g_list_append(*device_list, device_item);
374                         debug_log("Added device id(%d) type(%17s) direction(%d) state(%d) name(%s)",
375                                         device_item->id, device_item->type,device_item->io_direction, device_item->state,
376                                         device_item->name);
377                         device_item->stream_num = -1;
378                 } else {
379                         if (device_item)
380                                 g_free(device_item);
381                         break;
382                 }
383         }
384
385 cleanup:
386         if (result)
387                 g_variant_unref(result);
388
389         debug_fleave();
390         return ret;
391 }
392
393 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)
394 {
395         int ret = MM_ERROR_NONE;
396         struct callback_data *cb_data;
397
398         debug_fenter();
399
400         CB_DATA_NEW(cb_data, func, userdata, freefunc);
401
402         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) {
403                 debug_error("add device connected callback failed");
404                 goto finish;
405         }
406
407         if ((ret = _notify_subscription(AUDIO_EVENT_DEVICE_CONNECTED, cb_data->subs_id, TRUE)) != MM_ERROR_NONE) {
408                 debug_error("failed to notify subscription of device connected event");
409                 goto finish;
410         }
411
412         *subs_id = cb_data->subs_id;
413
414 finish:
415         debug_fleave();
416         return ret;
417 }
418
419 int mm_sound_proxy_remove_device_connected_callback(unsigned subs_id)
420 {
421         int ret = MM_ERROR_NONE;
422         debug_fenter();
423
424         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
425                 debug_error("remove device connected callback failed");
426                 goto finish;
427         }
428
429         if ((ret = _notify_subscription(AUDIO_EVENT_DEVICE_CONNECTED, subs_id, FALSE)) != MM_ERROR_NONE)
430                 debug_error("failed to notify unsubscription of device connected event");
431
432 finish:
433         debug_fleave();
434         return ret;
435 }
436
437 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)
438 {
439         int ret = MM_ERROR_NONE;
440         struct callback_data *cb_data;
441
442         debug_fenter();
443
444         CB_DATA_NEW(cb_data, func, userdata, freefunc);
445
446         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)
447                 debug_error("Add device info changed callback failed");
448         else
449                 *subs_id = cb_data->subs_id;
450
451         debug_fleave();
452         return ret;
453 }
454
455 int mm_sound_proxy_remove_device_info_changed_callback(unsigned subs_id)
456 {
457         int ret = MM_ERROR_NONE;
458         debug_fenter();
459
460         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
461                 debug_error("remove device info changed callback failed");
462
463         debug_fleave();
464         return ret;
465 }
466
467 int mm_sound_proxy_add_device_state_changed_callback(int device_flags, mm_sound_device_state_changed_wrapper_cb func, void* userdata, mm_sound_proxy_userdata_free freefunc, unsigned *subs_id)
468 {
469         int ret = MM_ERROR_NONE;
470         struct callback_data *cb_data;
471
472         debug_fenter();
473
474         CB_DATA_NEW(cb_data, func, userdata, freefunc);
475
476         if ((ret = mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_DEVICE_MANAGER, AUDIO_EVENT_DEVICE_STATE_CHANGED, dbus_callback, cb_data, simple_callback_data_free_func, &cb_data->subs_id)) != MM_ERROR_NONE)
477                 debug_error("Add device state changed callback failed");
478         else
479                 *subs_id = cb_data->subs_id;
480
481         debug_fleave();
482         return ret;
483 }
484
485 int mm_sound_proxy_remove_device_state_changed_callback(unsigned subs_id)
486 {
487         int ret = MM_ERROR_NONE;
488         debug_fenter();
489
490         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
491                 debug_error("remove device state changed callback failed");
492
493         debug_fleave();
494         return ret;
495 }
496
497 int mm_sound_proxy_set_volume_by_type(const char *volume_type, const unsigned volume_level)
498 {
499         int ret = MM_ERROR_NONE;
500         char *reply = NULL, *direction = "out";
501         GVariant *params = NULL, *result = NULL;
502
503         debug_fenter();
504
505         params = g_variant_new("(ssu)", direction, volume_type, volume_level);
506         if (params) {
507                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_SET_VOLUME_LEVEL, params, &result)) != MM_ERROR_NONE) {
508                         debug_error("dbus set volume by type failed");
509                         goto cleanup;
510                 }
511         } else {
512                 debug_error("Construct Param for method call failed");
513                 return MM_ERROR_SOUND_INTERNAL;
514         }
515
516         if (result) {
517                 g_variant_get(result, "(&s)",  &reply);
518                 debug_log("reply : %s", reply);
519                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
520                         ret = MM_ERROR_SOUND_INTERNAL;
521         } else {
522                 debug_error("reply null");
523         }
524
525 cleanup:
526         if (result)
527                 g_variant_unref(result);
528
529         debug_fleave();
530         return ret;
531 }
532
533 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)
534 {
535         int ret = MM_ERROR_NONE;
536         struct callback_data *cb_data;
537
538         debug_fenter();
539
540         CB_DATA_NEW(cb_data, func, userdata, freefunc);
541
542         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)
543                 debug_error("Add Volume changed callback failed");
544         else
545                 *subs_id = cb_data->subs_id;
546
547
548         debug_fleave();
549
550         return ret;
551 }
552
553 int mm_sound_proxy_remove_volume_changed_callback(unsigned subs_id)
554 {
555         int ret = MM_ERROR_NONE;
556         debug_fenter();
557
558         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
559                 debug_error("Remove Volume changed callback failed");
560
561         debug_fleave();
562         return ret;
563 }
564
565 int mm_sound_proxy_set_filter_by_type(const char *stream_type, const char *filter_name, const char *filter_parameters, const char *filter_group)
566 {
567         int ret = MM_ERROR_NONE;
568         char *reply = NULL;
569         GVariant *params = NULL, *result = NULL;
570
571         debug_fenter();
572
573         params = g_variant_new("(ssss)", filter_name, filter_parameters, filter_group, stream_type);
574         if (params) {
575                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_SET_FILTER, params, &result)) != MM_ERROR_NONE) {
576                         debug_error("dbus set filter by type failed");
577                         goto cleanup;
578                 }
579         } else {
580                 debug_error("construct param for method call failed");
581                 return MM_ERROR_SOUND_INTERNAL;
582         }
583
584         if (result) {
585                 g_variant_get(result, "(&s)", &reply);
586                 debug_log("reply : %s", reply);
587                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
588                         ret = MM_ERROR_SOUND_INTERNAL;
589         } else {
590                 debug_error("reply null");
591         }
592
593 cleanup:
594         if (result)
595                 g_variant_unref(result);
596
597         debug_fleave();
598         return ret;
599 }
600
601 int mm_sound_proxy_unset_filter_by_type(const char *stream_type)
602 {
603         int ret = MM_ERROR_NONE;
604         char *reply = NULL;
605         GVariant *params = NULL, *result = NULL;
606
607         debug_fenter();
608
609         params = g_variant_new("(s)", stream_type);
610         if (params) {
611                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_UNSET_FILTER, params, &result)) != MM_ERROR_NONE) {
612                         debug_error("dbus unset filter by type failed");
613                         goto cleanup;
614                 }
615         } else {
616                 debug_error("construct param for method call failed");
617                 return MM_ERROR_SOUND_INTERNAL;
618         }
619
620         if (result) {
621                 g_variant_get(result, "(&s)", &reply);
622                 debug_log("reply : %s", reply);
623                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
624                         ret = MM_ERROR_SOUND_INTERNAL;
625         } else {
626                 debug_error("reply null");
627         }
628
629 cleanup:
630         if (result)
631                 g_variant_unref(result);
632
633         debug_fleave();
634         return ret;
635 }
636
637 int mm_sound_proxy_control_filter_by_type(const char *stream_type, const char *filter_name, const char *filter_controls)
638 {
639         int ret = MM_ERROR_NONE;
640         char *reply = NULL;
641         GVariant *params = NULL, *result = NULL;
642
643         debug_fenter();
644
645         params = g_variant_new("(sss)", filter_name, filter_controls, stream_type);
646         if (params) {
647                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_CONTROL_FILTER, params, &result)) != MM_ERROR_NONE) {
648                         debug_error("dbus control filter by type failed");
649                         goto cleanup;
650                 }
651         } else {
652                 debug_error("construct param for method call failed");
653                 return MM_ERROR_SOUND_INTERNAL;
654         }
655
656         if (result) {
657                 g_variant_get(result, "(&s)", &reply);
658                 debug_log("reply : %s", reply);
659                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
660                         ret = MM_ERROR_SOUND_INTERNAL;
661         } else {
662                 debug_error("reply null");
663         }
664
665 cleanup:
666         if (result)
667                 g_variant_unref(result);
668
669         debug_fleave();
670         return ret;
671 }
672
673 int mm_sound_proxy_play_tone(int tone, int repeat, int volume, int volume_config,
674                            int session_type, int session_options, int client_pid,
675                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
676 {
677         int ret = MM_ERROR_NONE;
678         int handle = 0;
679         GVariant *params = NULL, *result = NULL;
680         gboolean _enable_session = enable_session;
681
682         if (!codechandle) {
683                 debug_error("Param for play is null");
684                 return MM_ERROR_INVALID_ARGUMENT;
685         }
686
687         debug_fenter();
688
689         params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume, volume_config, session_type,
690                                session_options, client_pid , _enable_session, stream_type, stream_index);
691         if (params) {
692                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
693                         debug_error("dbus play tone failed");
694                         goto cleanup;
695                 }
696         } else {
697                 debug_error("Construct Param for method call failed");
698         }
699
700         if (result) {
701                 g_variant_get(result, "(i)",  &handle);
702                 debug_log("handle : %d", handle);
703                 *codechandle = handle;
704         } else {
705                 debug_error("reply null");
706         }
707
708 cleanup:
709         if (result)
710                 g_variant_unref(result);
711
712         debug_fleave();
713         return ret;
714 }
715
716 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)
717 {
718         int ret = MM_ERROR_NONE;
719         int handle = 0;
720         GVariant *params = NULL, *result = NULL;
721
722         debug_fenter();
723
724         if (!codechandle) {
725                 debug_error("Param for play is null");
726                 return MM_ERROR_INVALID_ARGUMENT;
727         }
728
729         params = g_variant_new("(iiiisi)", tone, repeat, volume, client_pid, stream_type, stream_index);
730         if (params) {
731                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
732                         debug_error("dbus play tone failed");
733                         goto cleanup;
734                 }
735         } else {
736                 debug_error("Construct Param for method call failed");
737         }
738
739         if (result) {
740                 g_variant_get(result, "(i)",  &handle);
741                 debug_log("handle : %d", handle);
742                 *codechandle = handle;
743         } else {
744                 debug_error("reply null");
745         }
746
747 cleanup:
748         if (result)
749                 g_variant_unref(result);
750
751         debug_fleave();
752         return ret;
753 }
754
755 int mm_sound_proxy_play_sound(const char* filename, int tone, int repeat, int volume, int volume_config,
756                            int session_type, int session_options, int client_pid, bool enable_session, int *codechandle,
757                            char *stream_type, int stream_index)
758 {
759         int ret = MM_ERROR_NONE;
760         int handle = 0;
761         GVariant *params = NULL, *result = NULL;
762         gboolean _enable_session = enable_session;
763
764         if (!filename || !codechandle) {
765                 debug_error("Param for play is null");
766                 return MM_ERROR_INVALID_ARGUMENT;
767         }
768
769         debug_fenter();
770
771         params = g_variant_new("(siiiiiiibsi)", filename, tone, repeat, volume,
772                       volume_config, session_type, session_options, client_pid, _enable_session, stream_type, stream_index);
773         if (params) {
774                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_FILE_START, params, &result)) != MM_ERROR_NONE) {
775                         debug_error("dbus play file failed");
776                         goto cleanup;
777                 }
778         } else {
779                 debug_error("Construct Param for method call failed");
780         }
781
782         if (result) {
783                 g_variant_get(result, "(i)",  &handle);
784                 debug_log("handle : %d", handle);
785                 *codechandle = handle;
786         } else {
787                 debug_error("reply null");
788         }
789
790 cleanup:
791         if (result)
792                 g_variant_unref(result);
793
794         debug_fleave();
795         return ret;
796 }
797
798 int mm_sound_proxy_play_sound_with_stream_info(const char* filename, int repeat, int volume,
799                                 int client_pid, int *codechandle, char *stream_type, int stream_index)
800 {
801         int ret = MM_ERROR_NONE;
802         int handle = 0;
803         GVariant *params = NULL, *result = NULL;
804
805         if (!filename || !codechandle) {
806                 debug_error("Param for play is null");
807                 return MM_ERROR_INVALID_ARGUMENT;
808         }
809
810         debug_fenter();
811
812         params = g_variant_new("(siiisi)", filename, repeat, volume, client_pid, stream_type, stream_index);
813         if (params) {
814                 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) {
815                         debug_error("dbus play file failed");
816                         goto cleanup;
817                 }
818         } else {
819                 debug_error("Construct Param for method call failed");
820         }
821
822         if (result) {
823                 g_variant_get(result, "(i)",  &handle);
824                 debug_log("handle : %d", handle);
825                 *codechandle = handle;
826         } else {
827                 debug_error("reply null");
828         }
829
830 cleanup:
831         if (result)
832                 g_variant_unref(result);
833
834         debug_fleave();
835         return ret;
836
837
838 }
839
840 int mm_sound_proxy_stop_sound(int handle)
841 {
842         int ret = MM_ERROR_NONE;
843         GVariant *result = NULL;
844
845         debug_fenter();
846
847         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) {
848                 debug_error("dbus stop file playing failed");
849                 goto cleanup;
850         }
851
852 cleanup:
853         if (result)
854                 g_variant_unref(result);
855
856         debug_fleave();
857         return ret;
858 }
859
860 int mm_sound_proxy_clear_focus(int pid)
861 {
862         int ret = MM_ERROR_NONE;
863         GVariant *result = NULL;
864
865         debug_fenter();
866
867         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)
868                 debug_error("dbus clear focus failed");
869
870         if (result)
871                 g_variant_unref(result);
872
873         debug_fleave();
874         return ret;
875 }
876
877 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)
878 {
879         int ret = MM_ERROR_NONE;
880         struct callback_data *cb_data;
881
882         debug_fenter();
883
884         CB_DATA_NEW(cb_data, func, userdata, freefunc);
885
886         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)
887                 debug_error("add play sound end callback failed");
888         else
889                 *subs_id = cb_data->subs_id;
890
891         debug_fleave();
892
893         return ret;
894 }
895
896 int mm_sound_proxy_remove_play_sound_end_callback(unsigned subs_id)
897 {
898         int ret = MM_ERROR_NONE;
899         debug_fenter();
900
901         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE)
902                 debug_error("Remove Play File End callback failed");
903
904         debug_fleave();
905         return ret;
906 }
907
908 int mm_sound_proxy_emergent_exit(int exit_pid)
909 {
910         int ret = MM_ERROR_NONE;
911         GVariant *params = NULL;
912
913         debug_fenter();
914
915         params = g_variant_new("(i)", exit_pid);
916         if (params) {
917                 if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, params)) != MM_ERROR_NONE) {
918                         debug_error("dbus emergent exit failed");
919                         goto cleanup;
920                 }
921         } else {
922                 debug_error("Construct Param for emergent exit signal failed");
923                 ret = MM_ERROR_SOUND_INTERNAL;
924         }
925
926 cleanup:
927
928         debug_fleave();
929         return ret;
930 }
931
932 /*------------------------------------------ FOCUS --------------------------------------------------*/
933 #ifdef USE_FOCUS
934
935 int mm_sound_proxy_get_unique_id(int *id)
936 {
937         int ret = MM_ERROR_NONE;
938         int res = 0;
939         GVariant *result = NULL;
940
941         debug_fenter();
942
943         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_UNIQUE_ID, NULL, &result)) != MM_ERROR_NONE)
944                 debug_error("dbus get unique id failed");
945
946         if (result) {
947                 g_variant_get(result, "(i)", &res);
948                 *id = res;
949                 debug_msg("got unique id(%d)", *id);
950                 g_variant_unref(result);
951         }
952
953         debug_fleave();
954
955         return ret;
956 }
957
958 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)
959 {
960         int ret = MM_ERROR_NONE;
961         GVariant *params = NULL, *result = NULL;
962
963         debug_fenter();
964
965         params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
966         if (params) {
967                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE)
968                         debug_error("dbus register focus failed");
969         } else {
970                 debug_error("Construct Param for method call failed");
971         }
972
973         if (ret != MM_ERROR_NONE)
974                 g_variant_get(result, "(i)",  &ret);
975         if (result)
976                 g_variant_unref(result);
977
978         debug_fleave();
979
980         return ret;
981
982 }
983
984 int mm_sound_proxy_unregister_focus(int instance, int id, bool is_for_session)
985 {
986         int ret = MM_ERROR_NONE;
987         GVariant *params = NULL, *result = NULL;
988
989         debug_fenter();
990
991         params = g_variant_new("(iib)", instance, id, is_for_session);
992         if (params) {
993                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE)
994                         debug_error("dbus unregister focus failed");
995         } else {
996                 debug_error("Construct Param for method call failed");
997         }
998
999         if (ret != MM_ERROR_NONE)
1000                 g_variant_get(result, "(i)",  &ret);
1001         if (result)
1002                 g_variant_unref(result);
1003
1004         debug_fleave();
1005
1006         return ret;
1007 }
1008
1009 int mm_sound_proxy_set_focus_reacquisition(int instance, int id, bool reacquisition, bool is_for_session)
1010 {
1011         int ret = MM_ERROR_NONE;
1012         GVariant *params = NULL, *result = NULL;
1013
1014         debug_fenter();
1015
1016         params = g_variant_new("(iibb)", instance, id, reacquisition, is_for_session);
1017         if (params) {
1018                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_SET_FOCUS_REACQUISITION, params, &result)) != MM_ERROR_NONE)
1019                         debug_error("dbus set focus reacquisition failed");
1020         } else {
1021                 debug_error("Construct Param for method call failed");
1022         }
1023
1024         if (ret != MM_ERROR_NONE)
1025                 g_variant_get(result, "(i)",  &ret);
1026         if (result)
1027                 g_variant_unref(result);
1028
1029         debug_fleave();
1030         return ret;
1031 }
1032
1033 int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info)
1034 {
1035         int ret = MM_ERROR_NONE;
1036         GVariant *params = NULL, *result = NULL;
1037
1038         debug_fenter();
1039
1040         if (!(params = g_variant_new("(i)", focus_type))) {
1041                 debug_error("Construct Param for method call failed");
1042                 return MM_ERROR_SOUND_INTERNAL;
1043         }
1044
1045         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE, params, &result)) == MM_ERROR_NONE) {
1046                 if (result) {
1047                         g_variant_get(result, "(sis)", stream_type, option, ext_info);
1048                         g_variant_unref(result);
1049                 }
1050         } else {
1051                 debug_error("dbus get stream type of acquired focus failed");
1052         }
1053
1054         debug_fleave();
1055         return ret;
1056 }
1057
1058 int mm_sound_proxy_acquire_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session)
1059 {
1060         int ret = MM_ERROR_NONE;
1061         bool is_in_focus_cb_thread = false;
1062
1063         debug_fenter();
1064
1065         mm_sound_client_is_focus_cb_thread(g_thread_self(), &is_in_focus_cb_thread);
1066         if (is_in_focus_cb_thread) {
1067                 if ((ret = mm_sound_focus_socket_acquire(instance, id, type, option, ext_info ? ext_info : "", true, is_for_session)))
1068                         debug_error("failed to mm_sound_focus_socket_acquire(), ret[0x%x]", ret);
1069         } else {
1070                 GVariant *params = NULL, *result = NULL;
1071
1072                 params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
1073                 if (params) {
1074                         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE)
1075                                 debug_error("dbus acquire focus failed");
1076                 } else {
1077                         debug_error("Construct Param for method call failed");
1078                 }
1079
1080                 if (ret != MM_ERROR_NONE)
1081                         g_variant_get(result, "(i)",  &ret);
1082                 if (result)
1083                         g_variant_unref(result);
1084         }
1085
1086         debug_fleave();
1087         return ret;
1088 }
1089
1090 int mm_sound_proxy_release_focus(int instance, int id, mm_sound_focus_type_e type, int option, const char *ext_info, bool is_for_session)
1091 {
1092         int ret = MM_ERROR_NONE;
1093         bool is_in_focus_cb_thread = false;
1094
1095         debug_fenter();
1096
1097         mm_sound_client_is_focus_cb_thread(g_thread_self(), &is_in_focus_cb_thread);
1098         if (is_in_focus_cb_thread) {
1099                 if ((ret = mm_sound_focus_socket_release(instance, id, type, option, ext_info ? ext_info : "", true, is_for_session)))
1100                         debug_error("failed to mm_sound_focus_socket_release(), ret[0x%x]", ret);
1101         } else {
1102                 GVariant *params = NULL, *result = NULL;
1103
1104                 params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
1105                 if (params) {
1106                         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE)
1107                                 debug_error("dbus release focus failed");
1108                 } else {
1109                         debug_error("Construct Param for method call failed");
1110                 }
1111
1112                 if (ret != MM_ERROR_NONE)
1113                         g_variant_get(result, "(i)",  &ret);
1114                 if (result)
1115                         g_variant_unref(result);
1116         }
1117
1118         debug_fleave();
1119         return ret;
1120 }
1121
1122 int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status)
1123 {
1124         int ret = MM_ERROR_NONE;
1125         char *reply = NULL;
1126         GVariant *params = NULL, *result = NULL;
1127
1128         debug_fenter();
1129
1130         params = g_variant_new("(iu)", focus_id, status);
1131         if (params) {
1132                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS, params, &result)) != MM_ERROR_NONE) {
1133                         debug_error("dbus set volume by type failed");
1134                         goto cleanup;
1135                 }
1136         } else {
1137                 debug_error("Construct Param for method call failed");
1138                 return MM_ERROR_SOUND_INTERNAL;
1139         }
1140
1141         if (result) {
1142                 g_variant_get(result, "(&s)",  &reply);
1143                 debug_log("reply : %s", reply);
1144                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
1145                         ret = MM_ERROR_SOUND_INTERNAL;
1146         } else {
1147                 debug_error("reply null");
1148         }
1149
1150 cleanup:
1151         if (result)
1152                 g_variant_unref(result);
1153
1154         debug_fleave();
1155         return ret;
1156 }
1157
1158 int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, bool is_for_session, bool is_for_monitor, mm_sound_focus_changed_watch_cb callback, void* userdata)
1159 {
1160         int ret = MM_ERROR_NONE;
1161         GVariant *params = NULL, *result = NULL;
1162
1163         debug_fenter();
1164
1165         params = g_variant_new("(iiibb)", instance, handle, type, is_for_session, is_for_monitor);
1166         if (params) {
1167                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE)
1168                         debug_error("dbus set watch focus failed");
1169         } else {
1170                 debug_error("Construct Param for method call failed");
1171         }
1172
1173         if (ret != MM_ERROR_NONE)
1174                 g_variant_get(result, "(i)",  &ret);
1175         if (result)
1176                 g_variant_unref(result);
1177         debug_fleave();
1178
1179         return ret;
1180
1181 }
1182
1183 int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session)
1184 {
1185         int ret = MM_ERROR_NONE;
1186         GVariant *params = NULL, *result = NULL;
1187
1188         debug_fenter();
1189
1190         params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
1191         if (params) {
1192                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE)
1193                         debug_error("dbus unset watch focus failed");
1194         } else {
1195                 debug_error("Construct Param for method call failed");
1196         }
1197         if (ret != MM_ERROR_NONE)
1198                 g_variant_get(result, "(i)",  &ret);
1199         if (result)
1200                 g_variant_unref(result);
1201
1202         debug_fleave();
1203
1204         return ret;
1205 }
1206
1207 #endif /* USE_FOCUS */
1208 /*------------------------------------------ FOCUS --------------------------------------------------*/
1209
1210 int mm_sound_proxy_initialize(void)
1211 {
1212         int ret = MM_ERROR_NONE;
1213
1214         debug_fenter();
1215         debug_fleave();
1216
1217         return ret;
1218 }
1219
1220 int mm_sound_proxy_finalize(void)
1221 {
1222         int ret = MM_ERROR_NONE;
1223
1224         debug_fenter();
1225         debug_fleave();
1226
1227         return ret;
1228 }