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