Remove useless parameters(route_info, priority) regarding audio path routing since...
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_mgr_ipc_dbus.c
1
2 #include <string.h>
3
4 #include <mm_error.h>
5 #include <mm_debug.h>
6
7 #include <gio/gio.h>
8
9 #include "include/mm_sound_mgr_ipc_dbus.h"
10 #include "include/mm_sound_mgr_ipc.h"
11 #include "../include/mm_sound_dbus.h"
12
13
14 #define BUS_NAME_SOUND_SERVER "org.tizen.SoundServer"
15 #define OBJECT_SOUND_SERVER "/org/tizen/SoundServer1"
16 #define INTERFACE_SOUND_SERVER "org.tizen.SoundServer1"
17
18 /* workaround for AF volume gain tuning */
19 #define PROC_DBUS_OBJECT        "/Org/Tizen/ResourceD/Process"
20 #define PROC_DBUS_INTERFACE     "org.tizen.resourced.process"
21 #define PROC_DBUS_METHOD        "ProcExclude"
22
23 /* Introspection data for the service we are exporting */
24 static const gchar introspection_xml[] =
25   "<node>"
26   "  <interface name='org.tizen.SoundServer1'>"
27   "    <method name='MethodTest1'>"
28   "      <arg type='i' name='num1' direction='in'/>"
29   "      <arg type='i' name='num2' direction='in'/>"
30   "      <arg type='i' name='multiple' direction='out'/>"
31   "    </method>"
32   "    <method name='GetBTA2DPStatus'>"
33   "      <arg type='b' name='is_bt_on' direction='out'/>"
34   "      <arg type='s' name='bt_name' direction='out'/>"
35   "    </method>"
36   "    <method name='PlayFileStart'>"
37   "      <arg type='s' name='filename' direction='in'/>"
38   "      <arg type='i' name='tone' direction='in'/>"
39   "      <arg type='i' name='repeat' direction='in'/>"
40   "      <arg type='i' name='volume' direction='in'/>"
41   "      <arg type='i' name='vol_config' direction='in'/>"
42   "      <arg type='i' name='session_type' direction='in'/>"
43   "      <arg type='i' name='session_option' direction='in'/>"
44   "      <arg type='i' name='client_pid' direction='in'/>"
45   "      <arg type='b' name='enable_session' direction='in'/>"
46   "      <arg type='s' name='stream_type' direction='in'/>"
47   "      <arg type='i' name='stream_index' direction='in'/>"
48   "      <arg type='i' name='handle' direction='out'/>"
49   "    </method>"
50   "        <method name='PlayFileStartWithStreamInfo'>"
51   "          <arg type='s' name='filename' direction='in'/>"
52   "          <arg type='i' name='repeat' direction='in'/>"
53   "          <arg type='i' name='volume' direction='in'/>"
54   "          <arg type='i' name='client_pid' direction='in'/>"
55   "          <arg type='s' name='stream_type' direction='in'/>"
56   "          <arg type='i' name='stream_index' direction='in'/>"
57   "          <arg type='i' name='handle' direction='out'/>"
58   "        </method>"
59   "    <method name='PlayFileStop'>"
60   "      <arg type='i' name='handle' direction='in'/>"
61   "    </method>"
62 #ifdef FOCUS_INTEGRATION
63   "    <method name='ClearFocus'>"
64   "      <arg type='i' name='pid' direction='in'/>"
65   "    </method>"
66 #endif
67   "    <method name='PlayDTMF'>"
68   "      <arg type='i' name='tone' direction='in'/>"
69   "      <arg type='i' name='repeat' direction='in'/>"
70   "      <arg type='i' name='volume' direction='in'/>"
71   "      <arg type='i' name='vol_config' direction='in'/>"
72   "      <arg type='i' name='session_type' direction='in'/>"
73   "      <arg type='i' name='session_option' direction='in'/>"
74   "      <arg type='i' name='client_pid' direction='in'/>"
75   "      <arg type='b' name='enable_session' direction='in'/>"
76   "          <arg type='s' name='stream_type' direction='in'/>"
77   "          <arg type='i' name='stream_index' direction='in'/>"
78   "      <arg type='i' name='handle' direction='out'/>"
79   "    </method>"
80   "        <method name='PlayDTMFWithStreamInfo'>"
81   "          <arg type='i' name='tone' direction='in'/>"
82   "          <arg type='i' name='repeat' direction='in'/>"
83   "          <arg type='i' name='volume' direction='in'/>"
84   "          <arg type='i' name='client_pid' direction='in'/>"
85   "          <arg type='s' name='stream_type' direction='in'/>"
86   "          <arg type='i' name='stream_index' direction='in'/>"
87   "          <arg type='i' name='handle' direction='out'/>"
88   "        </method>"
89   "    <method name='GetConnectedDeviceList'>"
90   "      <arg type='i' name='device_mask' direction='in'/>"
91   "      <arg type='a(iiiis)' name='device_list' direction='out'/>"
92   "    </method>"
93   "  </interface>"
94   "</node>";
95 static GDBusConnection* conn_g;
96
97 static void handle_method_play_file_start(GDBusMethodInvocation* invocation);
98 static void handle_method_play_file_start_with_stream_info(GDBusMethodInvocation* invocation);
99 static void handle_method_play_file_stop(GDBusMethodInvocation* invocation);
100 static void handle_method_play_dtmf(GDBusMethodInvocation* invocation);
101 static void handle_method_play_dtmf_with_stream_info(GDBusMethodInvocation* invocation);
102 #ifdef FOCUS_INTEGRATION
103 static void handle_method_clear_focus(GDBusMethodInvocation* invocation);
104 #endif
105 static void handle_method_test(GDBusMethodInvocation* invocation);
106 static void handle_method_get_connected_device_list(GDBusMethodInvocation* invocation);
107
108 /* Currently , Just using method's name and handler */
109 /* TODO : generate introspection xml automatically, with these value include argument and reply */
110 /* TODO : argument check with these information */
111 /* TODO : divide object and interface with features (ex. play, path, device) */
112 static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
113         [AUDIO_METHOD_TEST] = {
114                 .info = {
115                         .name = "MethodTest1",
116                 },
117                 .handler = handle_method_test
118         },
119         [AUDIO_METHOD_PLAY_FILE_START] = {
120                 .info = {
121                         .name = "PlayFileStart",
122                 },
123                 .handler = handle_method_play_file_start
124         },
125         [AUDIO_METHOD_PLAY_FILE_START_WITH_STREAM_INFO] = {
126                 .info = {
127                         .name = "PlayFileStartWithStreamInfo",
128                 },
129                 .handler = handle_method_play_file_start_with_stream_info
130         },
131         [AUDIO_METHOD_PLAY_FILE_STOP] = {
132                 .info = {
133                         .name = "PlayFileStop",
134                 },
135                 .handler = handle_method_play_file_stop
136         },
137 #ifdef FOCUS_INTEGRATION
138         [AUDIO_METHOD_CLEAR_FOCUS] = {
139                 .info = {
140                         .name = "ClearFocus",
141                 },
142                 .handler = handle_method_clear_focus
143         },
144 #endif
145         [AUDIO_METHOD_PLAY_DTMF] = {
146                 .info = {
147                         .name = "PlayDTMF",
148                 },
149                 .handler = handle_method_play_dtmf
150         },
151         [AUDIO_METHOD_PLAY_DTMF_WITH_STREAM_INFO] = {
152                 .info = {
153                         .name = "PlayDTMFWithStreamInfo",
154                 },
155                 .handler = handle_method_play_dtmf_with_stream_info
156         },
157         [AUDIO_METHOD_GET_CONNECTED_DEVICE_LIST] = {
158                 .info = {
159                         .name = "GetConnectedDeviceList",
160                 },
161                 .handler = handle_method_get_connected_device_list
162         },
163 };
164
165 static GDBusNodeInfo *introspection_data = NULL;
166 guint sound_server_owner_id ;
167
168 /*
169         For pass error code with 'g_dbus_method_invocation_return_error'
170         We have to use some glib features like GError, GQuark
171 */
172 /* Only For error types which is currently being used in server-side */
173 static const GDBusErrorEntry mm_sound_error_entries[] =
174 {
175         {MM_ERROR_OUT_OF_MEMORY, "org.tizen.multimedia.OutOfMemory"},
176         {MM_ERROR_OUT_OF_STORAGE, "org.tizen.multimedia.OutOfStorage"},
177         {MM_ERROR_INVALID_ARGUMENT, "org.tizen.multimedia.InvalidArgument"},
178         {MM_ERROR_POLICY_INTERNAL, "org.tizen.multimedia.PolicyInternal"},
179         {MM_ERROR_NOT_SUPPORT_API, "org.tizen.multimedia.NotSupportAPI"},
180         {MM_ERROR_POLICY_BLOCKED, "org.tizen.multimedia.PolicyBlocked"},
181         {MM_ERROR_END_OF_FILE, "org.tizen.multimedia.EndOfFile"},
182         {MM_ERROR_COMMON_OUT_OF_RANGE, "org.tizen.multimedia.common.OutOfRange"},
183         {MM_ERROR_COMMON_UNKNOWN, "org.tizen.multimedia.common.Unknown"},
184         {MM_ERROR_COMMON_NO_FREE_SPACE, "org.tizen.multimedia.common.NoFreeSpace"},
185         {MM_ERROR_SOUND_INTERNAL, "org.tizen.multimedia.audio.Internal"},
186         {MM_ERROR_SOUND_INVALID_STATE, "org.tizen.multimedia.audio.InvalidState"},
187         {MM_ERROR_SOUND_NO_FREE_SPACE, "org.tizen.multimedia.audio.NoFreeSpace"},
188         {MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE, "org.tizen.multimedia.audio.UnsupportedMediaType"},
189         {MM_ERROR_SOUND_INVALID_POINTER, "org.tizen.multimedia.audio.InvalidPointer"},
190         {MM_ERROR_SOUND_INVALID_FILE, "org.tizen.multimedia.audio.InvalidFile"},
191         {MM_ERROR_SOUND_FILE_NOT_FOUND, "org.tizen.multimedia.audio.FileNotFound"},
192         {MM_ERROR_SOUND_NO_DATA, "org.tizen.multimedia.audio.NoData"},
193         {MM_ERROR_SOUND_INVALID_PATH, "org.tizen.multimedia.audio.InvalidPath"},
194 };
195
196 static const char* _convert_error_code(int err_code)
197 {
198         int i = 0;
199
200         for (i = 0; i < G_N_ELEMENTS(mm_sound_error_entries); i++) {
201                 if (err_code == mm_sound_error_entries[i].error_code) {
202                         return mm_sound_error_entries[i].dbus_error_name;
203                 }
204         }
205
206         return "org.tizen.multimedia.common.Unknown";
207 }
208
209 static int mm_sound_mgr_ipc_dbus_send_signal(audio_event_t event, GVariant *parameter)
210 {
211         if(mm_sound_dbus_emit_signal(AUDIO_PROVIDER_SOUND_SERVER, event, parameter) != MM_ERROR_NONE) {
212                 debug_error("Sound Server Emit signal failed");
213                 return MM_ERROR_SOUND_INTERNAL;
214         }
215         return MM_ERROR_NONE;
216 }
217
218 static int _get_sender_pid(GDBusMethodInvocation* invocation)
219 {
220         GVariant* value;
221         guint pid = 0;
222         const gchar* sender;
223         GDBusConnection * connection = NULL;
224         GError* err = NULL;
225
226         connection = g_dbus_method_invocation_get_connection(invocation);
227         sender = g_dbus_method_invocation_get_sender(invocation);
228
229         debug_error("connection = %p, sender = %s", connection, sender);
230
231         value = g_dbus_connection_call_sync(connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
232                                                                                 "org.freedesktop.DBus", "GetConnectionUnixProcessID",
233                                                                                 g_variant_new("(s)", sender, NULL), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
234         if (value) {
235                 g_variant_get(value, "(u)", &pid);
236                 debug_msg("Sender PID = [%d]", pid);
237                 g_variant_unref(value);
238         } else {
239                 debug_error("err code = %d, err msg = %s", err->code, err->message);
240         }
241         return pid;
242 }
243
244 static void _method_call_return_value(GDBusMethodInvocation *invocation, GVariant *params)
245 {
246         const char *method_name;
247         method_name = g_dbus_method_invocation_get_method_name(invocation);
248         debug_msg("Method Call '%s' success", method_name);
249         g_dbus_method_invocation_return_value(invocation, params);
250 }
251 static void _method_call_return_error(GDBusMethodInvocation *invocation, int ret)
252 {
253         const char *err_name, *method_name;
254         err_name = _convert_error_code(ret);
255         method_name = g_dbus_method_invocation_get_method_name(invocation);
256         debug_error("Method Call '%s' failed, err '%s(%X)'", method_name, err_name, ret);
257         g_dbus_method_invocation_return_dbus_error(invocation, err_name, "failed");
258 }
259
260 static void handle_method_test(GDBusMethodInvocation* invocation)
261 {
262         int ret = MM_ERROR_NONE;
263         int val = 0, val2 = 0;
264         GVariant *params = NULL;
265
266         debug_fenter();
267
268         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
269                 debug_error("Parameter for Method is NULL");
270                 ret = MM_ERROR_SOUND_INTERNAL;
271                 goto send_reply;
272         }
273
274         g_variant_get(params, "(ii)", &val, &val2);
275         debug_log("Got value : %d , %d", val, val2);
276
277         if ((ret = mm_sound_mgr_ipc_dbus_send_signal(AUDIO_EVENT_TEST, g_variant_new("(i)", val+val2))) != MM_ERROR_NONE) {
278                 debug_error("signal send error : %X", ret);
279         } else {
280                 debug_error("signal send success");
281         }
282
283 send_reply:
284         if (ret == MM_ERROR_NONE) {
285                 _method_call_return_value(invocation, g_variant_new("(i)", val * val2));
286         } else {
287                 ret = MM_ERROR_INVALID_ARGUMENT;
288                 _method_call_return_error(invocation,  ret);
289         }
290
291         debug_fleave();
292 }
293
294 static void handle_method_play_file_start(GDBusMethodInvocation* invocation)
295 {
296         gchar* filename = NULL;
297         gchar *stream_type = NULL;
298         gint32 ret = MM_ERROR_NONE, slotid = 0;
299         gint32 tone = 0, repeat = 0, volume = 0, vol_config = 0;
300         gint32 session_type = 0, session_option = 0, pid = 0, stream_index = 0;
301         gboolean enable_session = 0;
302         GVariant *params = NULL;
303
304         debug_fenter();
305
306         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
307                 debug_error("Parameter for Method is NULL");
308                 ret = MM_ERROR_SOUND_INTERNAL;
309                 goto send_reply;
310         }
311
312         g_variant_get(params, "(siiiiiiibsi)", &filename, &tone, &repeat, &volume,
313                       &vol_config, &session_type, &session_option, &pid, &enable_session, &stream_type, &stream_index);
314         if (!filename) {
315             debug_error("filename null");
316             ret = MM_ERROR_SOUND_INTERNAL;
317             goto send_reply;
318         }
319         ret = _MMSoundMgrIpcPlayFile(filename, tone, repeat, volume, vol_config,
320                                 session_type, session_option, _get_sender_pid(invocation), enable_session, &slotid, stream_type, stream_index);
321
322
323 send_reply:
324         if (ret == MM_ERROR_NONE) {
325                 _method_call_return_value(invocation, g_variant_new("(i)", slotid));
326         } else {
327                 _method_call_return_error(invocation, ret);
328         }
329
330         g_free(filename);
331         g_free(stream_type);
332
333         debug_fleave();
334 }
335
336 static void handle_method_play_file_start_with_stream_info(GDBusMethodInvocation* invocation)
337 {
338         gchar* filename = NULL;
339         gchar *stream_type = NULL;
340         gint32 ret = MM_ERROR_NONE, slotid = 0;
341         gint32 repeat = 0, volume = 0, pid = 0, stream_index = 0;
342         GVariant *params = NULL;
343
344         debug_fenter();
345
346         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
347                 debug_error("Parameter for Method is NULL");
348                 ret = MM_ERROR_SOUND_INTERNAL;
349                 goto send_reply;
350         }
351
352         g_variant_get(params, "(siiisi)", &filename, &repeat, &volume, &pid, &stream_type, &stream_index);
353         if (!filename) {
354             debug_error("filename null");
355             ret = MM_ERROR_SOUND_INTERNAL;
356             goto send_reply;
357         }
358         ret = _MMSoundMgrIpcPlayFileWithStreamInfo(filename, repeat, volume, _get_sender_pid(invocation),
359                     &slotid, stream_type, stream_index);
360
361 send_reply:
362         if (ret == MM_ERROR_NONE) {
363                 _method_call_return_value(invocation, g_variant_new("(i)", slotid));
364         } else {
365                 _method_call_return_error(invocation, ret);
366         }
367
368         g_free(filename);
369         g_free(stream_type);
370
371         debug_fleave();
372 }
373
374 static void handle_method_play_dtmf(GDBusMethodInvocation* invocation)
375 {
376         int ret = MM_ERROR_NONE, slotid = 0;
377         int tone = 0, repeat = 0, volume = 0, vol_config = 0, session_type = 0, session_option = 0, pid = 0, stream_index = 0;
378         gchar* stream_type = NULL;
379         gboolean enable_session = 0;
380         GVariant *params = NULL;
381
382         debug_fenter();
383
384         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
385                 debug_error("Parameter for Method is NULL");
386                 ret = MM_ERROR_SOUND_INTERNAL;
387                 goto send_reply;
388         }
389
390         g_variant_get(params, "(iiiiiiibsi)", &tone, &repeat, &volume,
391                       &vol_config, &session_type, &session_option, &pid, &enable_session, &stream_type, &stream_index);
392         debug_error("volume - %d", volume);
393         ret = _MMSoundMgrIpcPlayDTMF(tone, repeat, volume, vol_config,
394                                      session_type, session_option, _get_sender_pid(invocation), enable_session, &slotid, stream_type, stream_index);
395
396 send_reply:
397         if (ret == MM_ERROR_NONE) {
398                 _method_call_return_value(invocation, g_variant_new("(i)", slotid));
399         } else {
400                 _method_call_return_error(invocation, ret);
401         }
402
403         g_free(stream_type);
404
405         debug_fleave();
406 }
407
408 static void handle_method_play_dtmf_with_stream_info(GDBusMethodInvocation* invocation)
409 {
410         int ret = MM_ERROR_NONE, slotid = 0;
411         int tone = 0, repeat = 0, volume = 0, pid = 0, stream_index = 0;
412         char* stream_type = NULL;
413         GVariant *params = NULL;
414
415         debug_fenter();
416
417         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
418                 debug_error("Parameter for Method is NULL");
419                 ret = MM_ERROR_SOUND_INTERNAL;
420                 goto send_reply;
421         }
422
423         g_variant_get(params, "(iiiisi)", &tone, &repeat, &volume, &pid, &stream_type, &stream_index);
424         ret = _MMSoundMgrIpcPlayDTMFWithStreamInfo(tone, repeat, volume, _get_sender_pid(invocation), &slotid, stream_type, stream_index);
425
426 send_reply:
427         if (ret == MM_ERROR_NONE) {
428                 _method_call_return_value(invocation, g_variant_new("(i)", slotid));
429         } else {
430                 _method_call_return_error(invocation, ret);
431         }
432
433         debug_fleave();
434 }
435
436 static void handle_method_play_file_stop(GDBusMethodInvocation* invocation)
437 {
438         int ret = MM_ERROR_NONE;
439         int handle = 0;
440         GVariant *params = NULL;
441
442         debug_fenter();
443
444         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
445                 debug_error("Parameter for Method is NULL");
446                 ret = MM_ERROR_SOUND_INTERNAL;
447                 goto send_reply;
448         }
449
450         g_variant_get(params, "(i)", &handle);
451         ret = _MMSoundMgrIpcStop(handle);
452
453 send_reply:
454         if (ret == MM_ERROR_NONE) {
455                 _method_call_return_value(invocation, g_variant_new("()"));
456         } else {
457                 _method_call_return_error(invocation, ret);
458         }
459
460         debug_fleave();
461 }
462
463 #ifdef FOCUS_INTEGRATION
464 static void handle_method_clear_focus(GDBusMethodInvocation* invocation)
465 {
466         int ret = MM_ERROR_NONE;
467         int pid = 0;
468         GVariant *params = NULL;
469
470         debug_fenter();
471
472         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
473                 debug_error("Parameter for Method is NULL");
474                 ret = MM_ERROR_SOUND_INTERNAL;
475                 goto send_reply;
476         }
477
478         g_variant_get(params, "(i)", &pid);
479         ret = _MMSoundMgrIpcClearFocus(pid);
480
481 send_reply:
482         if (ret == MM_ERROR_NONE) {
483                 _method_call_return_value(invocation, g_variant_new("()"));
484         } else {
485                 _method_call_return_error(invocation, ret);
486         }
487
488         debug_fleave();
489 }
490 #endif
491
492 static void handle_method_get_connected_device_list(GDBusMethodInvocation* invocation)
493 {
494         int ret = MM_ERROR_NONE;
495         GVariant *params = NULL;
496         GVariantBuilder reply_builder;
497         int mask_flags = 0;
498         int devices_num = 0, device_idx = 0;
499         mm_sound_device_t *device_list = NULL, *device_entry = NULL;
500
501         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
502                 debug_error("Parameter for Method is NULL");
503                 ret = MM_ERROR_SOUND_INTERNAL;
504                 goto send_reply;
505         }
506
507         g_variant_get(params, "(i)", &mask_flags);
508         debug_log("Get device list with device_flag %X", mask_flags);
509         if ((ret = __mm_sound_mgr_ipc_get_current_connected_device_list(mask_flags, &device_list, &devices_num))==MM_ERROR_NONE) {
510                 g_variant_builder_init(&reply_builder, G_VARIANT_TYPE("(a(iiiis))"));
511                 g_variant_builder_open(&reply_builder, G_VARIANT_TYPE("a(iiiis)"));
512                 for (device_idx = 0; device_idx < devices_num; device_idx++) {
513                         device_entry = &device_list[device_idx];
514 //                      debug_log("device(%d): id(%d), type(%d), io(%d), state(%d), name(%s) ", device_idx, device_entry->id, device_entry->type, device_entry->io_direction, device_entry->state, device_entry->name);
515                         g_variant_builder_add(&reply_builder, "(iiiis)", device_entry->id, device_entry->type, device_entry->io_direction, device_entry->state, device_entry->name);
516                 }
517                 g_variant_builder_close(&reply_builder);
518         }
519
520 send_reply:
521         if (ret == MM_ERROR_NONE) {
522                 _method_call_return_value(invocation, g_variant_builder_end(&reply_builder));
523                 debug_log("Reply Sent");
524         } else {
525                 _method_call_return_error(invocation, ret);
526         }
527 }
528
529 static void handle_method_call(GDBusConnection *connection,
530                                                         const gchar *sender,
531                                                         const gchar *object_path,
532                                                         const gchar *interface_name,
533                                                         const gchar *method_name,
534                                                         GVariant *parameters,
535                                                         GDBusMethodInvocation *invocation,
536                                                         gpointer userdata)
537 {
538         int method_idx = 0;
539
540         if (!parameters) {
541                 debug_error("Parameter Null");
542                 return;
543         }
544         debug_log("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
545
546         for (method_idx = 0; method_idx < AUDIO_METHOD_MAX; method_idx++) {
547                 if (!g_strcmp0(method_name, methods[method_idx].info.name)) {
548                         methods[method_idx].handler(invocation);
549                 }
550         }
551 }
552
553
554 static GVariant* handle_get_property(GDBusConnection *connection,
555                                                                         const gchar *sender,
556                                                                         const gchar *object_path,
557                                                                         const gchar *interface_name,
558                                                                         const gchar *property_name,
559                                                                         GError **error,
560                                                                         gpointer userdata)
561 {
562         debug_log("Get Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
563         return NULL;
564 }
565
566 static gboolean handle_set_property(GDBusConnection *connection,
567                                                                         const gchar *sender,
568                                                                         const gchar *object_path,
569                                                                         const gchar *interface_name,
570                                                                         const gchar *property_name,
571                                                                         GVariant *value,
572                                                                         GError **error,
573                                                                         gpointer userdata)
574 {
575         debug_log("Set Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
576         return TRUE;
577 }
578
579 static const GDBusInterfaceVTable interface_vtable =
580 {
581         handle_method_call,
582         handle_get_property,
583         handle_set_property
584 };
585
586 static void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
587 {
588         guint reg_id;
589         debug_log("Bus Acquired (%s)", name);
590
591         conn_g = connection;
592         reg_id = g_dbus_connection_register_object(connection,
593                                           OBJECT_SOUND_SERVER,
594                                           introspection_data->interfaces[0],
595                                           &interface_vtable,
596                                           NULL,
597                                           NULL,
598                                           NULL);
599         if (!reg_id) {
600                 debug_error("Register object(%s) failed", OBJECT_SOUND_SERVER);
601                 return ;
602         }
603
604 }
605
606 static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
607 {
608         debug_log("Name Acquired (%s)", name);
609 }
610
611 static void on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
612 {
613         debug_log("Name Lost (%s)", name);
614 }
615
616 static int _mm_sound_mgr_dbus_own_name(GBusType bus_type, const char* wellknown_name, guint* owner_id)
617 {
618         guint oid;
619
620         debug_log("Own name (%s) for sound-server", wellknown_name);
621
622         oid = g_bus_own_name(bus_type, wellknown_name, G_BUS_NAME_OWNER_FLAGS_NONE,
623                         on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL);
624         if (oid <= 0) {
625                 debug_error("Dbus own name failed");
626                 return MM_ERROR_SOUND_INTERNAL;
627         } else {
628                 *owner_id = oid;
629         }
630
631         debug_log("OwnerID (%d) for sound-server", *owner_id);
632
633         return MM_ERROR_NONE;
634 }
635
636 static void _mm_sound_mgr_dbus_unown_name(guint oid)
637 {
638         debug_log("Unown name for Sound-Server [%d]", oid);
639         if (oid > 0) {
640                 g_bus_unown_name(oid);
641         }
642 }
643
644 int __mm_sound_mgr_ipc_dbus_notify_device_connected(mm_sound_device_t *device, gboolean is_connected)
645 {
646         int ret = MM_ERROR_NONE;
647         GVariantBuilder builder;
648         GVariant* param = NULL;
649
650         debug_log("Send device connected signal");
651
652         g_variant_builder_init(&builder, G_VARIANT_TYPE("((iiiis)b)"));
653         g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
654         g_variant_builder_add(&builder, "(iiiis)", device->id, device->type, device->io_direction, device->state, device->name);
655         g_variant_builder_close(&builder);
656         g_variant_builder_add(&builder, "b", is_connected);
657         param = g_variant_builder_end(&builder);
658         if (param) {
659                 if ((ret = mm_sound_mgr_ipc_dbus_send_signal(AUDIO_EVENT_DEVICE_CONNECTED, param))!= MM_ERROR_NONE) {
660                         debug_error("Send device connected signal failed");
661                 }
662         } else {
663                 debug_error("Build variant for dbus param failed");
664         }
665
666         return ret;
667 }
668
669 int __mm_sound_mgr_ipc_dbus_notify_device_info_changed(mm_sound_device_t *device, int changed_device_info_type)
670 {
671         int ret = MM_ERROR_NONE;
672         GVariantBuilder builder;
673         GVariant* param = NULL;
674
675         debug_log("Send device info changed signal");
676
677         g_variant_builder_init(&builder, G_VARIANT_TYPE("((iiiis)i)"));
678         g_variant_builder_open(&builder, G_VARIANT_TYPE_TUPLE);
679         g_variant_builder_add(&builder, "(iiiis)", device->id, device->type, device->io_direction, device->state, device->name);
680         g_variant_builder_close(&builder);
681         g_variant_builder_add(&builder, "i", changed_device_info_type);
682         param = g_variant_builder_end(&builder);
683         if (param) {
684                 if ((ret = mm_sound_mgr_ipc_dbus_send_signal(AUDIO_EVENT_DEVICE_INFO_CHANGED, param)) != MM_ERROR_NONE) {
685                         debug_error("Send device info changed signal failed");
686                 }
687         } else {
688                 debug_error("Build variant for dbus param failed");
689         }
690
691         return ret;
692 }
693
694 int __mm_sound_mgr_ipc_dbus_notify_volume_changed(unsigned int vol_type, unsigned int value)
695 {
696         int ret = MM_ERROR_NONE;
697         GVariant* param = NULL;
698
699         debug_log("Send Signal volume changed signal");
700
701         param = g_variant_new("(uu)", vol_type, value);
702         if (param) {
703                 if ((ret = mm_sound_mgr_ipc_dbus_send_signal(AUDIO_EVENT_VOLUME_CHANGED, param)) != MM_ERROR_NONE) {
704                         debug_error("Send device connected signal failed");
705                 }
706         } else {
707                 debug_error("Build variant for dbus param failed");
708         }
709
710         return ret;
711 }
712
713 int __mm_sound_mgr_ipc_dbus_notify_play_file_end(int handle)
714 {
715         int ret = MM_ERROR_NONE;
716         GVariant* param = NULL;
717
718         debug_log("Send play file ended signal");
719
720         param = g_variant_new("(i)", handle);
721         if (param) {
722                 if ((ret = mm_sound_mgr_ipc_dbus_send_signal(AUDIO_EVENT_PLAY_FILE_END, param)) != MM_ERROR_NONE) {
723                         debug_error("Send play file end for '%d' failed", handle);
724                 }
725         } else {
726                 debug_error("Build variant for dbus param failed");
727         }
728
729         return ret;
730 }
731
732 int __mm_sound_mgr_ipc_dbus_notify_active_device_changed(int device_in, int device_out)
733 {
734         return MM_ERROR_SOUND_INTERNAL;
735 }
736
737 int __mm_sound_mgr_ipc_dbus_notify_available_device_changed(int device_in, int device_out, int available)
738 {
739         return MM_ERROR_SOUND_INTERNAL;
740 }
741
742 #define PA_BUS_NAME                                    "org.pulseaudio.Server"
743 #define PA_STREAM_MANAGER_OBJECT_PATH                  "/org/pulseaudio/StreamManager"
744 #define PA_STREAM_MANAGER_INTERFACE                    "org.pulseaudio.StreamManager"
745 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST  "GetStreamList"
746 int __mm_sound_mgr_ipc_dbus_get_stream_list(stream_list_t* stream_list)
747 {
748         int ret = MM_ERROR_NONE;
749         GVariant *result = NULL;
750         GVariant *child = NULL;
751         GDBusConnection *conn = NULL;
752         GError *err = NULL;
753         int i = 0;
754
755         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
756         if (!conn && err) {
757                 LOGE("g_bus_get_sync() error (%s)", err->message);
758                 g_error_free(err);
759                 ret = MM_ERROR_SOUND_INTERNAL;
760                 return ret;
761         }
762         result = g_dbus_connection_call_sync(conn,
763                                                         PA_BUS_NAME,
764                                                         PA_STREAM_MANAGER_OBJECT_PATH,
765                                                         PA_STREAM_MANAGER_INTERFACE,
766                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST,
767                                                         NULL,
768                                                         G_VARIANT_TYPE("(vv)"),
769                                                         G_DBUS_CALL_FLAGS_NONE,
770                                                         2000,
771                                                         NULL,
772                                                         &err);
773         if (!result && err) {
774                 debug_error("g_dbus_connection_call_sync() error (%s)", err->message);
775                 ret = MM_ERROR_SOUND_INTERNAL;
776         } else {
777                 GVariantIter iter;
778                 GVariant *item = NULL;
779                 child = g_variant_get_child_value(result, 0);
780                 item = g_variant_get_variant(child);
781                 gchar *name;
782                 i = 0;
783                 g_variant_iter_init(&iter, item);
784                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "&s", &name)) {
785                         debug_log("name : %s", name);
786                         stream_list->stream_types[i++] = strdup(name);
787                 }
788                 g_variant_unref(item);
789                 g_variant_unref(child);
790
791                 child = g_variant_get_child_value(result, 1);
792                 item = g_variant_get_variant(child);
793                 gint32 priority;
794                 i = 0;
795                 g_variant_iter_init(&iter, item);
796                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "i", &priority)) {
797                         debug_log("priority : %d", priority);
798                         stream_list->priorities[i++] = priority;
799                 }
800                 g_variant_unref(item);
801                 g_variant_unref(child);
802
803                 g_variant_unref(result);
804         }
805         g_object_unref(conn);
806
807         return ret;
808 }
809
810 int MMSoundMgrDbusInit(void)
811 {
812         debug_enter();
813
814         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
815         if (!introspection_data) {
816                 debug_error("g_dbus_node_info_new_for_xml() failed...");
817                 return MM_ERROR_SOUND_INTERNAL;
818         }
819
820         if (_mm_sound_mgr_dbus_own_name(G_BUS_TYPE_SYSTEM, BUS_NAME_SOUND_SERVER, &sound_server_owner_id) != MM_ERROR_NONE) {
821                 debug_error("dbus own name for sound-server error\n");
822                 return MM_ERROR_SOUND_INTERNAL;
823         }
824
825         debug_leave();
826
827         return MM_ERROR_NONE;
828 }
829
830 void MMSoundMgrDbusFini(void)
831 {
832         debug_enter("\n");
833
834         _mm_sound_mgr_dbus_unown_name(sound_server_owner_id);
835         g_dbus_node_info_unref(introspection_data);
836
837         debug_leave("\n");
838 }
839
840
841