Merge branch 'tizen_3.0' into tizen
[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_play_tone(int tone, int repeat, int volume, int volume_config,
570                            int session_type, int session_options, int client_pid,
571                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
572 {
573         int ret = MM_ERROR_NONE;
574         int handle = 0;
575         GVariant *params = NULL, *result = NULL;
576         gboolean _enable_session = enable_session;
577
578         if (!codechandle) {
579                 debug_error("Param for play is null");
580                 return MM_ERROR_INVALID_ARGUMENT;
581         }
582
583         debug_fenter();
584
585         params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume, volume_config, session_type,
586                       session_options, client_pid , _enable_session, stream_type, stream_index);
587         if (params) {
588                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
589                         debug_error("dbus play tone failed");
590                         goto cleanup;
591                 }
592         } else {
593                 debug_error("Construct Param for method call failed");
594         }
595
596         if (result) {
597                 g_variant_get(result, "(i)",  &handle);
598                 debug_log("handle : %d", handle);
599                 *codechandle = handle;
600         } else {
601                 debug_error("reply null");
602         }
603
604 cleanup:
605         if (result)
606                 g_variant_unref(result);
607
608         debug_fleave();
609         return ret;
610 }
611
612 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)
613 {
614         int ret = MM_ERROR_NONE;
615         int handle = 0;
616         GVariant *params = NULL, *result = NULL;
617
618         debug_fenter();
619
620         if (!codechandle) {
621                 debug_error("Param for play is null");
622                 return MM_ERROR_INVALID_ARGUMENT;
623         }
624
625         params = g_variant_new("(iiiisi)", tone, repeat, volume, client_pid, stream_type, stream_index);
626         if (params) {
627                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_DTMF_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
628                         debug_error("dbus play tone failed");
629                         goto cleanup;
630                 }
631         } else {
632                 debug_error("Construct Param for method call failed");
633         }
634
635         if (result) {
636                 g_variant_get(result, "(i)",  &handle);
637                 debug_log("handle : %d", handle);
638                 *codechandle = handle;
639         } else {
640                 debug_error("reply null");
641         }
642
643 cleanup:
644         if (result)
645                 g_variant_unref(result);
646
647         debug_fleave();
648         return ret;
649 }
650
651 int mm_sound_proxy_play_sound(const char* filename, int tone, int repeat, int volume, int volume_config,
652                            int session_type, int session_options, int client_pid, bool enable_session, int *codechandle,
653                            char *stream_type, int stream_index)
654 {
655         int ret = MM_ERROR_NONE;
656         int handle = 0;
657         GVariant *params = NULL, *result = NULL;
658         gboolean _enable_session = enable_session;
659
660         if (!filename || !codechandle) {
661                 debug_error("Param for play is null");
662                 return MM_ERROR_INVALID_ARGUMENT;
663         }
664
665         debug_fenter();
666
667         params = g_variant_new("(siiiiiiibsi)", filename, tone, repeat, volume,
668                       volume_config, session_type, session_options, client_pid, _enable_session, stream_type, stream_index);
669         if (params) {
670                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_SOUND_SERVER, AUDIO_METHOD_PLAY_FILE_START, params, &result)) != MM_ERROR_NONE) {
671                         debug_error("dbus play file failed");
672                         goto cleanup;
673                 }
674         } else {
675                 debug_error("Construct Param for method call failed");
676         }
677
678         if (result) {
679                 g_variant_get(result, "(i)",  &handle);
680                 debug_log("handle : %d", handle);
681                 *codechandle = handle;
682         } else {
683                 debug_error("reply null");
684         }
685
686 cleanup:
687         if (result)
688                 g_variant_unref(result);
689
690         debug_fleave();
691         return ret;
692 }
693
694 int mm_sound_proxy_play_sound_with_stream_info(const char* filename, int repeat, int volume,
695                                 int client_pid, int *codechandle, char *stream_type, int stream_index)
696 {
697         int ret = MM_ERROR_NONE;
698         int handle = 0;
699         GVariant *params = NULL, *result = NULL;
700
701         if (!filename || !codechandle) {
702                 debug_error("Param for play is null");
703                 return MM_ERROR_INVALID_ARGUMENT;
704         }
705
706         debug_fenter();
707
708         params = g_variant_new("(siiisi)", filename, repeat, volume, client_pid, stream_type, stream_index);
709         if (params) {
710                 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) {
711                         debug_error("dbus play file failed");
712                         goto cleanup;
713                 }
714         } else {
715                 debug_error("Construct Param for method call failed");
716         }
717
718         if (result) {
719                 g_variant_get(result, "(i)",  &handle);
720                 debug_log("handle : %d", handle);
721                 *codechandle = handle;
722         } else {
723                 debug_error("reply null");
724         }
725
726 cleanup:
727         if (result)
728                 g_variant_unref(result);
729
730         debug_fleave();
731         return ret;
732
733
734 }
735
736 int mm_sound_proxy_stop_sound(int handle)
737 {
738         int ret = MM_ERROR_NONE;
739         GVariant *result = NULL;
740
741         debug_fenter();
742
743         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) {
744                 debug_error("dbus stop file playing failed");
745                 goto cleanup;
746         }
747
748 cleanup:
749         if (result)
750                 g_variant_unref(result);
751
752         debug_fleave();
753         return ret;
754 }
755
756 int mm_sound_proxy_clear_focus(int pid)
757 {
758         int ret = MM_ERROR_NONE;
759         GVariant *result = NULL;
760
761         debug_fenter();
762
763         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) {
764                 debug_error("dbus clear focus failed");
765         }
766
767         if (result)
768                 g_variant_unref(result);
769
770         debug_fleave();
771         return ret;
772 }
773
774 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)
775 {
776         int ret = MM_ERROR_NONE;
777         struct callback_data *cb_data;
778
779         debug_fenter();
780
781         CB_DATA_NEW(cb_data, func, userdata, freefunc);
782
783         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)
784                 debug_error("add play sound end callback failed");
785         else
786                 *subs_id = cb_data->subs_id;
787
788         debug_fleave();
789
790         return ret;
791 }
792
793 int mm_sound_proxy_remove_play_sound_end_callback(unsigned subs_id)
794 {
795         int ret = MM_ERROR_NONE;
796         debug_fenter();
797
798         if ((ret = mm_sound_dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
799                 debug_error("Remove Play File End callback failed");
800         }
801
802         debug_fleave();
803         return ret;
804 }
805
806 int mm_sound_proxy_emergent_exit(int exit_pid)
807 {
808         int ret = MM_ERROR_NONE;
809         GVariant *params = NULL;
810
811         debug_fenter();
812
813         params = g_variant_new("(i)", exit_pid);
814         if (params) {
815                 if ((ret = mm_sound_dbus_emit_signal(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, params)) != MM_ERROR_NONE) {
816                         debug_error("dbus emergent exit failed");
817                         goto cleanup;
818                 }
819         } else {
820                 debug_error("Construct Param for emergent exit signal failed");
821                 ret = MM_ERROR_SOUND_INTERNAL;
822         }
823
824 cleanup:
825
826         debug_fleave();
827         return ret;
828 }
829
830 /*------------------------------------------ FOCUS --------------------------------------------------*/
831 #ifdef USE_FOCUS
832
833 int mm_sound_proxy_get_unique_id(int *id)
834 {
835         int ret = MM_ERROR_NONE;
836         int res = 0;
837         GVariant *result = NULL;
838
839         debug_fenter();
840
841         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_UNIQUE_ID, NULL, &result)) != MM_ERROR_NONE) {
842                 debug_error("dbus get unique id failed");
843         }
844
845         if (result) {
846                 g_variant_get(result, "(i)", &res);
847                 *id = res;
848                 debug_msg("got unique id(%d)", *id);
849                 g_variant_unref(result);
850         }
851
852         debug_fleave();
853
854         return ret;
855 }
856
857 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)
858 {
859         int ret = MM_ERROR_NONE;
860         GVariant *params = NULL, *result = NULL;
861
862         debug_fenter();
863
864         params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
865         if (params) {
866                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
867                         debug_error("dbus register focus failed");
868                 }
869         } else {
870                 debug_error("Construct Param for method call failed");
871         }
872
873         if (ret != MM_ERROR_NONE)
874                 g_variant_get(result, "(i)",  &ret);
875         if (result)
876                 g_variant_unref(result);
877
878         debug_fleave();
879
880         return ret;
881
882 }
883
884 int mm_sound_proxy_unregister_focus(int instance, int id, bool is_for_session)
885 {
886         int ret = MM_ERROR_NONE;
887         GVariant *params = NULL, *result = NULL;
888
889         debug_fenter();
890
891         params = g_variant_new("(iib)", instance, id, is_for_session);
892         if (params) {
893                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
894                         debug_error("dbus unregister focus failed");
895                 }
896         } else {
897                 debug_error("Construct Param for method call failed");
898         }
899
900         if (ret != MM_ERROR_NONE)
901                 g_variant_get(result, "(i)",  &ret);
902         if (result)
903                 g_variant_unref(result);
904
905         debug_fleave();
906
907         return ret;
908 }
909
910 int mm_sound_proxy_set_foucs_reacquisition(int instance, int id, bool reacquisition)
911 {
912         int ret = MM_ERROR_NONE;
913         GVariant *params = NULL, *result = NULL;
914
915         debug_fenter();
916
917         params = g_variant_new("(iib)", instance, id, reacquisition);
918         if (params) {
919                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_SET_FOCUS_REACQUISITION, params, &result)) != MM_ERROR_NONE) {
920                         debug_error("dbus set focus reacquisition failed");
921                 }
922         } else {
923                 debug_error("Construct Param for method call failed");
924         }
925
926         if (ret != MM_ERROR_NONE)
927                 g_variant_get(result, "(i)",  &ret);
928         if (result)
929                 g_variant_unref(result);
930
931         debug_fleave();
932         return ret;
933 }
934
935 int mm_sound_proxy_get_acquired_focus_stream_type(int focus_type, char **stream_type, int *option, char **ext_info)
936 {
937         int ret = MM_ERROR_NONE;
938         GVariant *params = NULL, *result = NULL;
939
940         debug_fenter();
941
942         if (!(params = g_variant_new("(i)", focus_type))) {
943                 debug_error("Construct Param for method call failed");
944                 return MM_ERROR_SOUND_INTERNAL;
945         }
946
947         if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE, params, &result)) == MM_ERROR_NONE) {
948                 if (result) {
949                         g_variant_get(result, "(sis)", stream_type, option, ext_info);
950                         g_variant_unref(result);
951                 }
952         } else {
953                 debug_error("dbus get stream type of acquired focus failed");
954         }
955
956         debug_fleave();
957         return ret;
958 }
959
960 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)
961 {
962         int ret = MM_ERROR_NONE;
963         GVariant *params = NULL, *result = NULL;
964
965         debug_fenter();
966
967         params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
968         if (params) {
969                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE) {
970                         debug_error("dbus acquire focus failed");
971                 }
972         } else {
973                 debug_error("Construct Param for method call failed");
974         }
975
976         if (ret != MM_ERROR_NONE)
977                 g_variant_get(result, "(i)",  &ret);
978         if (result)
979                 g_variant_unref(result);
980
981         debug_fleave();
982         return ret;
983 }
984
985 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)
986 {
987         int ret = MM_ERROR_NONE;
988         GVariant *params = NULL, *result = NULL;
989
990         debug_fenter();
991
992         params = g_variant_new("(iiiisb)", instance, id, type, option, ext_info ? ext_info : "", is_for_session);
993         if (params) {
994                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE) {
995                         debug_error("dbus release focus failed");
996                 }
997         } else {
998                 debug_error("Construct Param for method call failed");
999         }
1000
1001         if (ret != MM_ERROR_NONE)
1002                 g_variant_get(result, "(i)",  &ret);
1003         if (result)
1004                 g_variant_unref(result);
1005
1006         debug_fleave();
1007         return ret;
1008 }
1009
1010 int mm_sound_proxy_update_stream_focus_status(int focus_id, unsigned int status)
1011 {
1012         int ret = MM_ERROR_NONE;
1013         char *reply = NULL;
1014         GVariant *params = NULL, *result = NULL;
1015
1016         debug_fenter();
1017
1018         params = g_variant_new("(iu)", focus_id, status);
1019         if (params) {
1020                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_STREAM_MANAGER, AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS, params, &result)) != MM_ERROR_NONE) {
1021                         debug_error("dbus set volume by type failed");
1022                         goto cleanup;
1023                 }
1024         } else {
1025                 debug_error("Construct Param for method call failed");
1026                 return MM_ERROR_SOUND_INTERNAL;
1027         }
1028
1029         if (result) {
1030                 g_variant_get(result, "(&s)",  &reply);
1031                 debug_log("reply : %s", reply);
1032                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
1033                         ret = MM_ERROR_SOUND_INTERNAL;
1034         } else {
1035                 debug_error("reply null");
1036         }
1037
1038 cleanup:
1039         if (result)
1040                 g_variant_unref(result);
1041
1042         debug_fleave();
1043         return ret;
1044 }
1045
1046 int mm_sound_proxy_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void* userdata)
1047 {
1048         int ret = MM_ERROR_NONE;
1049         GVariant *params = NULL, *result = NULL;
1050
1051         debug_fenter();
1052
1053         params = g_variant_new("(iiib)", instance, handle, type, is_for_session);
1054         if (params) {
1055                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1056                         debug_error("dbus set watch focus failed");
1057                 }
1058         } else {
1059                 debug_error("Construct Param for method call failed");
1060         }
1061
1062         if (ret != MM_ERROR_NONE)
1063                 g_variant_get(result, "(i)",  &ret);
1064         if (result)
1065                 g_variant_unref(result);
1066         debug_fleave();
1067
1068         return ret;
1069
1070 }
1071
1072 int mm_sound_proxy_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session)
1073 {
1074         int ret = MM_ERROR_NONE;
1075         GVariant *params = NULL, *result = NULL;
1076
1077         debug_fenter();
1078
1079         params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
1080         if (params) {
1081                 if ((ret = mm_sound_dbus_method_call_to(AUDIO_PROVIDER_FOCUS_SERVER, AUDIO_METHOD_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1082                         debug_error("dbus unset watch focus failed");
1083                 }
1084         } else {
1085                 debug_error("Construct Param for method call failed");
1086         }
1087         if (ret != MM_ERROR_NONE)
1088                 g_variant_get(result, "(i)",  &ret);
1089         if (result)
1090                 g_variant_unref(result);
1091
1092         debug_fleave();
1093
1094         return ret;
1095 }
1096
1097 #endif /* USE_FOCUS */
1098 /*------------------------------------------ FOCUS --------------------------------------------------*/
1099
1100 int mm_sound_proxy_initialize(void)
1101 {
1102         int ret = MM_ERROR_NONE;
1103
1104         debug_fenter();
1105         debug_fleave();
1106
1107         return ret;
1108 }
1109
1110 int mm_sound_proxy_finalize(void)
1111 {
1112         int ret = MM_ERROR_NONE;
1113
1114         debug_fenter();
1115         debug_fleave();
1116
1117         return ret;
1118 }