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