Move out dbus unrelated logic code from client_dbus.c
[platform/core/multimedia/libmm-sound.git] / mm_sound_client_dbus.c
1 #include <gio/gio.h>
2 #include <glib.h>
3 #include <poll.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <signal.h>
9
10 #include <mm_error.h>
11 #include <mm_debug.h>
12
13 #include "include/mm_sound_client_dbus.h"
14 #include "include/mm_sound_device.h"
15 #include "include/mm_sound_msg.h"
16 #include "include/mm_sound_common.h"
17
18 #ifdef USE_SECURITY
19 #include <security-server.h>
20 #define COOKIE_SIZE 20
21 #endif
22
23
24 #define BUS_NAME_PULSEAUDIO "org.pulseaudio.Server"
25 #define OBJECT_PULSE_MODULE_POLICY "/org/pulseaudio/policy1"
26 #define INTERFACE_PULSE_MODULE_POLICY "org.PulseAudio.Ext.Policy1"
27 #define OBJECT_PULSE_MODULE_DEVICE_MANAGER "/org/pulseaudio/DeviceManager"
28 #define INTERFACE_PULSE_MODULE_DEVICE_MANAGER "org.pulseaudio.DeviceManager"
29 #define OBJECT_PULSE_MODULE_STREAM_MANAGER "/org/pulseaudio/StreamManager"
30 #define INTERFACE_PULSE_MODULE_STREAM_MANAGER "org.pulseaudio.StreamManager"
31
32 #define BUS_NAME_SOUND_SERVER "org.tizen.SoundServer"
33 #define OBJECT_SOUND_SERVER "/org/tizen/SoundServer1"
34 #define INTERFACE_SOUND_SERVER "org.tizen.SoundServer1"
35
36 #define BUS_NAME_FOCUS_SERVER "org.tizen.FocusServer"
37 #define OBJECT_FOCUS_SERVER "/org/tizen/FocusServer1"
38 #define INTERFACE_FOCUS_SERVER "org.tizen.FocusServer1"
39
40 #define INTERFACE_DBUS                  "org.freedesktop.DBus.Properties"
41 #define SIGNAL_PROP_CHANGED "PropertiesChanged"
42 #define METHOD_GET                      "Get"
43 #define METHOD_SET                      "Set"
44 #define DBUS_NAME_MAX                   32
45 #define DBUS_SIGNATURE_MAX              32
46 #define ERR_MSG_MAX                     100
47
48 #define CODEC_HANDLE_MAX 256
49 enum {
50         DBUS_TO_SOUND_SERVER,
51         DBUS_TO_PULSE_MODULE_DEVICE_MANAGER,
52         DBUS_TO_PULSE_MODULE_STREAM_MANAGER,
53         DBUS_TO_PULSE_MODULE_POLICY,
54         DBUS_TO_FOCUS_SERVER,
55 };
56
57 struct user_callback {
58         int sig_type;
59         void *cb;
60         void *userdata;
61         int mask;
62 };
63
64 guint g_dbus_prop_subs_ids[PULSEAUDIO_PROP_MAX];
65
66 const struct mm_sound_dbus_method_info g_methods[METHOD_CALL_MAX] = {
67         [METHOD_CALL_TEST] = {
68                 .name = "MethodTest1",
69         },
70         [METHOD_CALL_PLAY_FILE_START] = {
71                 .name = "PlayFileStart",
72         },
73         [METHOD_CALL_PLAY_FILE_START_WITH_STREAM_INFO] = {
74                 .name = "PlayFileStartWithStreamInfo",
75         },
76         [METHOD_CALL_PLAY_FILE_STOP] = {
77                 .name = "PlayFileStop",
78         },
79         [METHOD_CALL_PLAY_DTMF] = {
80                 .name = "PlayDTMF",
81         },
82         [METHOD_CALL_PLAY_DTMF_WITH_STREAM_INFO] = {
83                 .name = "PlayDTMFWithStreamInfo",
84         },
85         [METHOD_CALL_CLEAR_FOCUS] = {
86                 .name = "ClearFocus",
87         },
88         [METHOD_CALL_GET_BT_A2DP_STATUS] = {
89                 .name = "GetBTA2DPStatus",
90         },
91         [METHOD_CALL_SET_PATH_FOR_ACTIVE_DEVICE] = {
92                 .name = "SetPathForActiveDevice",
93         },
94         [METHOD_CALL_GET_AUDIO_PATH] = {
95                 .name = "GetAudioPath",
96         },
97         [METHOD_CALL_SET_VOLUME_LEVEL] = {
98                 .name = "SetVolumeLevel",
99         },
100         [METHOD_CALL_GET_CONNECTED_DEVICE_LIST] = {
101                 .name = "GetConnectedDeviceList",
102         },
103         [METHOD_CALL_REGISTER_FOCUS] = {
104                 .name = "RegisterFocus",
105         },
106         [METHOD_CALL_UNREGISTER_FOCUS] = {
107                 .name = "UnregisterFocus",
108         },
109         [METHOD_CALL_ACQUIRE_FOCUS] = {
110                 .name = "AcquireFocus",
111         },
112         [METHOD_CALL_RELEASE_FOCUS] = {
113                 .name = "ReleaseFocus",
114         },
115         [METHOD_CALL_WATCH_FOCUS] = {
116                 .name = "WatchFocus",
117         },
118         [METHOD_CALL_UNWATCH_FOCUS] = {
119                 .name = "UnwatchFocus",
120         },
121         [METHOD_CALL_EMERGENT_EXIT_FOCUS] = {
122                 .name = "EmergentExitFocus",
123         },
124 };
125
126 const struct mm_sound_dbus_signal_info g_signals[SIGNAL_MAX] = {
127     [SIGNAL_TEST] = {
128                 .name = "SignalTest1",
129         },
130         [SIGNAL_PLAY_FILE_END] = {
131                 .name = "PlayFileEnd",
132         },
133         [SIGNAL_VOLUME_CHANGED] = {
134                 .name = "VolumeChanged",
135         },
136         [SIGNAL_DEVICE_CONNECTED] = {
137                 .name = "DeviceConnected",
138         },
139         [SIGNAL_DEVICE_INFO_CHANGED] = {
140                 .name = "DeviceInfoChanged",
141         },
142         [SIGNAL_FOCUS_CHANGED] = {
143                 .name = "FocusChanged",
144         },
145         [SIGNAL_FOCUS_WATCH] = {
146                 .name = "FocusWatch",
147         }
148 };
149
150 const struct pulseaudio_dbus_property_info g_pulseaudio_properties[PULSEAUDIO_PROP_MAX] = {
151         [PULSEAUDIO_PROP_AUDIO_BALANCE] = {
152                 .name = "AudioBalance",
153         },
154         [PULSEAUDIO_PROP_MONO_AUDIO] = {
155                 .name = "MonoAudio",
156         },
157         [PULSEAUDIO_PROP_MUTE_ALL] = {
158                 .name = "MuteAll",
159         },
160 };
161
162 /*
163 static const GDBusErrorEntry mm_sound_client_error_entries[] =
164 {
165         {MM_ERROR_SOUND_INTERNAL, "org.tizen.mm.sound.Error.Internal"},
166         {MM_ERROR_INVALID_ARGUMENT, "org.tizen.mm.sound.Error.InvalidArgument"},
167 };
168 */
169
170
171 /* Only For error types which is currently being used in server-side */
172 static const GDBusErrorEntry mm_sound_error_entries[] =
173 {
174         {MM_ERROR_OUT_OF_MEMORY, "org.tizen.multimedia.OutOfMemory"},
175         {MM_ERROR_OUT_OF_STORAGE, "org.tizen.multimedia.OutOfStorage"},
176         {MM_ERROR_INVALID_ARGUMENT, "org.tizen.multimedia.InvalidArgument"},
177         {MM_ERROR_POLICY_INTERNAL, "org.tizen.multimedia.PolicyInternal"},
178         {MM_ERROR_NOT_SUPPORT_API, "org.tizen.multimedia.NotSupportAPI"},
179         {MM_ERROR_POLICY_BLOCKED, "org.tizen.multimedia.PolicyBlocked"},
180         {MM_ERROR_END_OF_FILE, "org.tizen.multimedia.EndOfFile"},
181         {MM_ERROR_COMMON_OUT_OF_RANGE, "org.tizen.multimedia.common.OutOfRange"},
182         {MM_ERROR_COMMON_UNKNOWN, "org.tizen.multimedia.common.Unknown"},
183         {MM_ERROR_COMMON_NO_FREE_SPACE, "org.tizen.multimedia.common.NoFreeSpace"},
184         {MM_ERROR_SOUND_INTERNAL, "org.tizen.multimedia.audio.Internal"},
185         {MM_ERROR_SOUND_INVALID_STATE, "org.tizen.multimedia.audio.InvalidState"},
186         {MM_ERROR_SOUND_NO_FREE_SPACE, "org.tizen.multimedia.audio.NoFreeSpace"},
187         {MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE, "org.tizen.multimedia.audio.UnsupportedMediaType"},
188         {MM_ERROR_SOUND_INVALID_POINTER, "org.tizen.multimedia.audio.InvalidPointer"},
189         {MM_ERROR_SOUND_INVALID_FILE, "org.tizen.multimedia.audio.InvalidFile"},
190         {MM_ERROR_SOUND_FILE_NOT_FOUND, "org.tizen.multimedia.audio.FileNotFound"},
191         {MM_ERROR_SOUND_NO_DATA, "org.tizen.multimedia.audio.NoData"},
192         {MM_ERROR_SOUND_INVALID_PATH, "org.tizen.multimedia.audio.InvalidPath"},
193 };
194
195
196 /******************************************************************************************
197                 Wrapper Functions of GDbus
198 ******************************************************************************************/
199
200
201 static int _parse_error_msg(char *full_err_msg, char **err_name, char **err_msg)
202 {
203         char *save_p, *domain, *_err_name, *_err_msg;
204
205         if (!(domain = strtok_r(full_err_msg, ":", &save_p))) {
206                 debug_error("get domain failed");
207                 return -1;
208         }
209         if (!(_err_name = strtok_r(NULL, ":", &save_p))) {
210                 debug_error("get err name failed");
211                 return -1;
212         }
213         if (!(_err_msg = strtok_r(NULL, ":", &save_p))) {
214                 debug_error("get err msg failed");
215                 return -1;
216         }
217
218         *err_name = _err_name;
219         *err_msg = _err_msg;
220
221         return 0;
222 }
223
224 static int _convert_error_name(const char *err_name)
225 {
226         int i = 0;
227
228         for (i = 0; i < G_N_ELEMENTS(mm_sound_error_entries); i++) {
229                 if (!strcmp(mm_sound_error_entries[i].dbus_error_name, err_name)) {
230                         return mm_sound_error_entries[i].error_code;
231                 }
232         }
233
234         return MM_ERROR_COMMON_UNKNOWN;
235 }
236
237 static int _dbus_method_call(GDBusConnection* conn, const char* bus_name, const char* object, const char* intf,
238                                                         const char* method, GVariant* args, GVariant** result)
239 {
240         int ret = MM_ERROR_NONE;
241         GError *err = NULL;
242         GVariant* dbus_reply = NULL;
243
244         if (!conn || !object || !intf || !method) {
245                 debug_error("Invalid Argument");
246                 if (!conn)
247                         debug_error("conn null");
248                 else if (!object)
249                         debug_error("object null");
250                 else if (!intf)
251                         debug_error("intf null");
252                 else if (!method)
253                         debug_error("method null");
254                 return MM_ERROR_INVALID_ARGUMENT;
255         }
256
257         debug_log("Dbus call with obj'%s' intf'%s' method'%s'", object, intf, method);
258
259         dbus_reply = g_dbus_connection_call_sync(conn, bus_name, object , intf, \
260                              method, args ,\
261                              NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err );
262         if (dbus_reply && !err) {
263                 debug_log("Method Call '%s.%s' Success", intf, method);
264                 *result = dbus_reply;
265         } else {
266                 char *err_name = NULL, *err_msg = NULL;
267                 debug_log("Method Call '%s.%s' Failed, %s", intf, method, err->message);
268
269                 if (_parse_error_msg(err->message,  &err_name, &err_msg) < 0) {
270                         debug_error("failed to parse error message");
271                         g_error_free(err);
272                         return MM_ERROR_SOUND_INTERNAL;
273                 }
274                 ret = _convert_error_name(err_name);
275                 g_error_free(err);
276         }
277
278         return ret;
279 }
280
281 static int _dbus_set_property(GDBusConnection* conn, const char* bus_name, const char* object, const char* intf,
282                                                         const char* prop, GVariant* args, GVariant** result)
283 {
284         int ret = MM_ERROR_NONE;
285
286         if (!conn || !object || !intf || !prop) {
287                 debug_error("Invalid Argument");
288                 return MM_ERROR_INVALID_ARGUMENT;
289         }
290
291         debug_log("Dbus set property with obj'%s' intf'%s' prop'%s'", object, intf, prop);
292
293         if ((ret = _dbus_method_call(conn, bus_name, object, INTERFACE_DBUS, METHOD_SET,
294                                                                 g_variant_new("(ssv)", intf, prop, args), result)) != MM_ERROR_NONE) {
295                 debug_error("Dbus call for set property failed");
296         }
297
298         return ret;
299 }
300
301 static int _dbus_get_property(GDBusConnection *conn, const char* bus_name, const char* object_name,
302                                                         const char* intf_name, const char* prop, GVariant** result)
303 {
304         int ret = MM_ERROR_NONE;
305
306         if (!conn || !object_name || !intf_name || !prop) {
307                 debug_error("Invalid Argument");
308                 return MM_ERROR_INVALID_ARGUMENT;
309         }
310
311         debug_log("Dbus get property with obj'%s' intf'%s' prop'%s'", object_name, intf_name, prop);
312
313         if ((ret = _dbus_method_call(conn,
314                                        bus_name, object_name, INTERFACE_DBUS, METHOD_GET,
315                                        g_variant_new("(ss)", intf_name, prop), result)) != MM_ERROR_NONE) {
316                 debug_error("Dbus call for get property failed");
317         }
318
319         return ret;
320 }
321
322 static int _dbus_subscribe_signal(GDBusConnection *conn, const char* object_name, const char* intf_name,
323                                         const char* signal_name, GDBusSignalCallback signal_cb, guint *subscribe_id, void* userdata)
324 {
325         guint subs_id = 0;
326
327         if (!conn || !object_name || !intf_name || !signal_name || !signal_cb) {
328                 debug_error("Invalid Argument");
329                 return MM_ERROR_INVALID_ARGUMENT;
330         }
331
332         debug_log("Dbus subscirbe signal with Obj'%s' Intf'%s' sig'%s'", object_name, intf_name, signal_name);
333
334         subs_id = g_dbus_connection_signal_subscribe(conn, NULL, intf_name, signal_name, object_name, \
335                          NULL , G_DBUS_SIGNAL_FLAGS_NONE , signal_cb, userdata, NULL );
336
337         if (!subs_id) {
338                 debug_error ("g_dbus_connection_signal_subscribe() failed ");
339                 return MM_ERROR_SOUND_INTERNAL;
340         } else {
341                 if (subscribe_id)
342                         *subscribe_id = subs_id;
343         }
344
345         return MM_ERROR_NONE;
346 }
347
348 static void _dbus_unsubscribe_signal(GDBusConnection *conn, guint subs_id)
349 {
350         if (!conn || !subs_id) {
351                 debug_error("Invalid Argument");
352         }
353
354         g_dbus_connection_signal_unsubscribe(conn, subs_id);
355 }
356
357 static GDBusConnection* _dbus_get_connection(GBusType bustype)
358 {
359         static GDBusConnection *conn_system = NULL;
360         static GDBusConnection *conn_session = NULL;
361
362         if (bustype == G_BUS_TYPE_SYSTEM) {
363                 if (conn_system) {
364                         debug_log("Already connected to system bus");
365                 } else {
366                         debug_log("Get new connection on system bus");
367                         conn_system = g_bus_get_sync(bustype, NULL, NULL);
368                 }
369                 return conn_system;
370         } else if (bustype == G_BUS_TYPE_SESSION) {
371                 if (conn_session) {
372                         debug_log("Already connected to session bus");
373                 } else {
374                         debug_log("Get new connection on session bus");
375                         conn_session = g_bus_get_sync(bustype, NULL, NULL);
376                 }
377                 return conn_session;
378         } else {
379                 debug_error("Invalid bus type");
380                 return NULL;
381         }
382
383 }
384
385 static void _dbus_disconnect(GDBusConnection* conn)
386 {
387         debug_fenter ();
388         g_object_unref(conn);
389         debug_fleave ();
390 }
391
392 /******************************************************************************************
393                 Simple Functions For Communicate with Sound-Server
394 ******************************************************************************************/
395
396 static int _dbus_method_call_to(int dbus_to, int method_type, GVariant *args, GVariant **result)
397 {
398         int ret = MM_ERROR_NONE;
399         GDBusConnection *conn = NULL;
400         const char *bus_name, *object, *interface;
401
402         if (method_type < 0 || method_type > METHOD_CALL_MAX) {
403                 debug_error("Invalid method type");
404                 return MM_ERROR_INVALID_ARGUMENT;
405         }
406
407         if (dbus_to == DBUS_TO_SOUND_SERVER) {
408                 bus_name = BUS_NAME_SOUND_SERVER;
409                 object = OBJECT_SOUND_SERVER;
410                 interface = INTERFACE_SOUND_SERVER;
411         } else if (dbus_to == DBUS_TO_PULSE_MODULE_DEVICE_MANAGER) {
412                 bus_name = BUS_NAME_PULSEAUDIO;
413         object = OBJECT_PULSE_MODULE_DEVICE_MANAGER;
414         interface = INTERFACE_PULSE_MODULE_DEVICE_MANAGER;
415         } else if (dbus_to == DBUS_TO_PULSE_MODULE_STREAM_MANAGER) {
416                 bus_name = BUS_NAME_PULSEAUDIO;
417                 object = OBJECT_PULSE_MODULE_STREAM_MANAGER;
418                 interface = INTERFACE_PULSE_MODULE_STREAM_MANAGER;
419         } else if (dbus_to == DBUS_TO_PULSE_MODULE_POLICY) {
420                 bus_name = BUS_NAME_PULSEAUDIO;
421         object = OBJECT_PULSE_MODULE_POLICY;
422         interface = INTERFACE_PULSE_MODULE_POLICY;
423         } else if (dbus_to == DBUS_TO_FOCUS_SERVER) {
424                 bus_name = BUS_NAME_FOCUS_SERVER;
425         object = OBJECT_FOCUS_SERVER;
426         interface = INTERFACE_FOCUS_SERVER;
427         } else {
428                 debug_error("Invalid case, dbus_to %d", dbus_to);
429                 return MM_ERROR_SOUND_INTERNAL;
430         }
431
432         if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
433                 if((ret = _dbus_method_call(conn, bus_name,
434                                               object,
435                                               interface,
436                                               g_methods[method_type].name,
437                                               args, result)) != MM_ERROR_NONE) {
438                         debug_error("Dbus Call on Client Error");
439                         return ret;
440                 }
441         } else {
442                 debug_error("Get Dbus Connection Error");
443                 return MM_ERROR_SOUND_INTERNAL;
444         }
445
446         return MM_ERROR_NONE;
447 }
448
449 static void _dbus_signal_callback (GDBusConnection  *connection,
450                                      const gchar      *sender_name,
451                                      const gchar      *object_path,
452                                      const gchar      *interface_name,
453                                      const gchar      *signal_name,
454                                      GVariant         *params,
455                                      gpointer          user_data)
456 {
457         struct user_callback* user_cb = (struct user_callback*) user_data;
458
459         if (!user_cb || !user_cb->cb) {
460                 debug_error("User callback data Null");
461                 return;
462         }
463
464         if (user_cb->sig_type < 0 || user_cb->sig_type >= SIGNAL_MAX) {
465                 debug_error("Wrong Signal Type");
466                 return;
467         }
468
469         if (!params) {
470                 debug_error("Parameter Null");
471                 return;
472         }
473
474         debug_log("Signal(%s.%s) Received , Let's call Wrapper-Callback", interface_name, signal_name);
475
476         if (user_cb->sig_type == SIGNAL_VOLUME_CHANGED) {
477                 char *volume_type_str = NULL, *direction = NULL;
478                 unsigned int volume_level;
479
480                 g_variant_get(params, "(&s&su)", &direction, &volume_type_str, &volume_level);
481                 ((mm_sound_volume_changed_wrapper_cb)(user_cb->cb))(direction, volume_type_str, volume_level, user_cb->userdata);
482         } else if (user_cb->sig_type == SIGNAL_DEVICE_CONNECTED) {
483                 const char *name = NULL, *device_type = NULL;
484                 gboolean is_connected = FALSE;
485                 int device_id, io_direction, state;
486
487                 g_variant_get(params, "((i&sii&s)b)", &device_id, &device_type, &io_direction,
488                                         &state, &name, &is_connected);
489                 ((mm_sound_device_connected_wrapper_cb)(user_cb->cb))(device_id, device_type, io_direction, state, name, is_connected, user_cb->userdata);
490         } else if (user_cb->sig_type == SIGNAL_DEVICE_INFO_CHANGED) {
491                 const char *name = NULL, *device_type = NULL;
492                 int changed_device_info_type = 0;
493                 int device_id, io_direction, state;
494
495                 g_variant_get(params, "((i&sii&s)i)", &device_id, &device_type, &io_direction,
496                                         &state, &name, &changed_device_info_type);
497                 ((mm_sound_device_info_changed_wrapper_cb)(user_cb->cb))(device_id, device_type, io_direction, state, name, changed_device_info_type, user_cb->userdata);
498         } else if (user_cb->sig_type == SIGNAL_FOCUS_CHANGED) {
499         } else if (user_cb->sig_type == SIGNAL_FOCUS_WATCH) {
500         } else if (user_cb->sig_type == SIGNAL_TEST) {
501                 int test_var = 0;
502                 g_variant_get(params, "(i)", &test_var);
503                 ((mm_sound_test_cb)(user_cb->cb))(test_var, user_cb->userdata);
504         } else if (user_cb->sig_type == SIGNAL_PLAY_FILE_END) {
505                 int ended_handle = 0;
506                 g_variant_get(params, "(i)", &ended_handle);
507                 ((mm_sound_stop_callback_wrapper_func)(user_cb->cb))(ended_handle, user_cb->userdata);
508         }
509 }
510
511 static int _dbus_signal_subscribe_to(int dbus_to, sound_server_signal_t signaltype, void *cb, void *userdata, int mask, unsigned int *subs_id)
512 {
513         GDBusConnection *conn = NULL;
514         guint _subs_id = 0;
515         struct user_callback *user_cb  = NULL;
516         const char *object, *interface;
517
518         if (!cb) {
519                 debug_error("Callback data Null");
520                 return MM_ERROR_INVALID_ARGUMENT;
521         }
522
523         if (signaltype < 0 || signaltype >= SIGNAL_MAX) {
524                 debug_error("Wrong Signal Type");
525                 return MM_ERROR_INVALID_ARGUMENT;
526         }
527
528         if (!(user_cb = g_malloc0(sizeof(struct user_callback)))) {
529                 debug_error("Allocate Memory for User CB data Failed");
530                 return MM_ERROR_SOUND_INTERNAL;
531         }
532
533         user_cb->sig_type = signaltype;
534         user_cb->cb = cb;
535         user_cb->userdata = userdata;
536         user_cb->mask = mask;
537
538
539         if (dbus_to == DBUS_TO_SOUND_SERVER) {
540                 object = OBJECT_SOUND_SERVER;
541                 interface = INTERFACE_SOUND_SERVER;
542         } else if (dbus_to == DBUS_TO_PULSE_MODULE_DEVICE_MANAGER) {
543                 object = OBJECT_PULSE_MODULE_DEVICE_MANAGER;
544                 interface = INTERFACE_PULSE_MODULE_DEVICE_MANAGER;
545         } else if (dbus_to == DBUS_TO_PULSE_MODULE_STREAM_MANAGER) {
546                 object = OBJECT_PULSE_MODULE_STREAM_MANAGER;
547                 interface = INTERFACE_PULSE_MODULE_STREAM_MANAGER;
548         } else if (dbus_to == DBUS_TO_PULSE_MODULE_POLICY) {
549                 object = OBJECT_PULSE_MODULE_POLICY;
550                 interface = INTERFACE_PULSE_MODULE_POLICY;
551         } else {
552                 debug_error("Invalid case, dbus_to %d", dbus_to);
553                 return MM_ERROR_SOUND_INTERNAL;
554         }
555
556
557         if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
558                 if(_dbus_subscribe_signal(conn, object, interface, g_signals[signaltype].name,
559                                                                 _dbus_signal_callback, &_subs_id, user_cb) != MM_ERROR_NONE) {
560                         debug_error("Dbus Subscribe on Client Error");
561                         return MM_ERROR_SOUND_INTERNAL;
562                 } else {
563                         if (subs_id)
564                                 *subs_id = (unsigned int)_subs_id;
565                 }
566         } else {
567                 debug_error("Get Dbus Connection Error");
568                 return MM_ERROR_SOUND_INTERNAL;
569         }
570         return MM_ERROR_NONE;
571 }
572
573 static int _dbus_signal_unsubscribe(unsigned int subs_id)
574 {
575         GDBusConnection *conn = NULL;
576
577         if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
578                 _dbus_unsubscribe_signal(conn, (guint) subs_id);
579         } else {
580                 debug_error("Get Dbus Connection Error");
581                 return MM_ERROR_SOUND_INTERNAL;
582         }
583
584         return MM_ERROR_NONE;
585 }
586
587 static int _pulseaudio_dbus_set_property(pulseaudio_property_t property, GVariant* args, GVariant **result)
588 {
589         int ret = MM_ERROR_NONE;
590         GDBusConnection *conn = NULL;
591
592         if (property < 0 || property > PULSEAUDIO_PROP_MAX) {
593                 debug_error("Invalid property [%d]", property);
594                 return MM_ERROR_INVALID_ARGUMENT;
595         }
596
597         if (args == NULL) {
598                 debug_error("Invalid args");
599                 return MM_ERROR_INVALID_ARGUMENT;
600         }
601
602         if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
603                 if((ret = _dbus_set_property(conn, BUS_NAME_PULSEAUDIO, OBJECT_PULSE_MODULE_POLICY, INTERFACE_PULSE_MODULE_POLICY,
604                                                                         g_pulseaudio_properties[property].name, args, result)) != MM_ERROR_NONE) {
605                         debug_error("Dbus Call on Client Error");
606                         return ret;
607                 }
608         } else {
609                 debug_error("Get Dbus Connection Error");
610                 return MM_ERROR_SOUND_INTERNAL;
611         }
612
613         return MM_ERROR_NONE;
614 }
615
616 static int _pulseaudio_dbus_get_property(pulseaudio_property_t property, GVariant **result)
617 {
618         int ret = MM_ERROR_NONE;
619         GDBusConnection *conn = NULL;
620
621         if (property < 0 || property > PULSEAUDIO_PROP_MAX) {
622                 debug_error("Invalid property [%d]", property);
623                 return MM_ERROR_INVALID_ARGUMENT;
624         }
625
626         if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
627                 if((ret = _dbus_get_property(conn, BUS_NAME_PULSEAUDIO, OBJECT_PULSE_MODULE_POLICY, INTERFACE_PULSE_MODULE_POLICY,
628                                                                         g_pulseaudio_properties[property].name, result)) != MM_ERROR_NONE) {
629                         debug_error("Dbus Call on Client Error");
630                         return ret;
631                 }
632         } else {
633                 debug_error("Get Dbus Connection Error");
634                 return MM_ERROR_SOUND_INTERNAL;
635         }
636
637         return MM_ERROR_NONE;
638 }
639
640 /******************************************************************************************
641                 Implementation of each dbus client code (Construct Params,..)
642 ******************************************************************************************/
643
644 int mm_sound_client_dbus_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id)
645 {
646         int ret = MM_ERROR_NONE;
647
648         debug_fenter();
649
650         if ((ret = _dbus_signal_subscribe_to(DBUS_TO_SOUND_SERVER, SIGNAL_TEST, func, user_data, 0, subs_id)) != MM_ERROR_NONE) {
651                 debug_error("add test callback failed");
652         }
653
654         debug_fleave();
655         return ret;
656 }
657
658 int mm_sound_client_dbus_remove_test_callback(unsigned int subs_id)
659 {
660         int ret = MM_ERROR_NONE;
661         debug_fenter();
662
663         if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
664                 debug_error("remove test callback failed");
665         }
666
667         debug_fleave();
668         return ret;
669 }
670
671 int mm_sound_client_dbus_test(int a, int b, int *get)
672 {
673         int ret = MM_ERROR_NONE;
674         int reply = 0;
675         GVariant *params = NULL, *result = NULL;
676
677         debug_fenter();
678
679         params = g_variant_new("(ii)", a, b);
680         if (params) {
681                 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_TEST, params, &result)) != MM_ERROR_NONE) {
682                         debug_error("dbus test call failed");
683                         goto cleanup;
684                 }
685         } else {
686                 debug_error("Construct Param for method call failed");
687                 return MM_ERROR_SOUND_INTERNAL;
688         }
689
690         if (result) {
691                 g_variant_get(result, "(i)",  &reply);
692                 debug_log("reply : %d", reply);
693                 *get = reply;
694         } else {
695                 debug_error("reply null");
696         }
697
698 cleanup:
699         if (result)
700                 g_variant_unref(result);
701
702         debug_fleave();
703         return ret;
704 }
705
706 int mm_sound_client_dbus_get_current_connected_device_list(int device_flags, GList** device_list)
707 {
708         int ret = MM_ERROR_NONE;
709         GVariant *result = NULL, *child = NULL;
710         GVariant *params;
711         GVariantIter iter;
712         mm_sound_device_t* device_item;
713         const gchar *device_name_tmp = NULL, *device_type_tmp = NULL;
714
715         debug_fenter();
716
717         if (!device_list) {
718                 debug_error("Invalid Parameter, device_list null");
719                 ret = MM_ERROR_INVALID_ARGUMENT;
720                 goto cleanup;
721         }
722
723         params = g_variant_new("(i)", device_flags);
724
725         if (params) {
726                 if ((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, METHOD_CALL_GET_CONNECTED_DEVICE_LIST, params, &result)) != MM_ERROR_NONE) {
727                         debug_error("Get current connected device list failed");
728                         goto cleanup;
729                 }
730         } else {
731                 debug_error("Construct Param for get current connected device failed");
732                 return MM_ERROR_SOUND_INTERNAL;
733         }
734
735         child = g_variant_get_child_value(result, 0);
736         g_variant_iter_init(&iter, child);
737         while (1) {
738                 device_item = g_malloc0(sizeof(mm_sound_device_t));
739                 if (device_item && g_variant_iter_loop(&iter, "(i&sii&s)", &device_item->id, &device_type_tmp, &device_item->io_direction, &device_item->state, &device_name_tmp)) {
740                         MMSOUND_STRNCPY(device_item->name, device_name_tmp, MAX_DEVICE_NAME_NUM);
741                         MMSOUND_STRNCPY(device_item->type, device_type_tmp, MAX_DEVICE_TYPE_STR_LEN);
742                         *device_list = g_list_append(*device_list, device_item);
743                         debug_log("Added device id(%d) type(%17s) direction(%d) state(%d) name(%s)", device_item->id, device_item->type,device_item->io_direction, device_item->state, device_item->name);
744                 } else {
745                         if (device_item)
746                                 g_free(device_item);
747                         break;
748                 }
749         }
750
751 cleanup:
752         if (result)
753                 g_variant_unref(result);
754
755         debug_fleave();
756         return ret;
757 }
758
759 int mm_sound_client_dbus_add_device_connected_callback(int device_flags, mm_sound_device_connected_wrapper_cb func, void* user_data, unsigned int *subs_id)
760 {
761         int ret = MM_ERROR_NONE;
762
763         debug_fenter();
764
765         if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, SIGNAL_DEVICE_CONNECTED, func, user_data, device_flags, subs_id)) != MM_ERROR_NONE) {
766                 debug_error("add device connected callback failed");
767         }
768
769         debug_fleave();
770         return ret;
771 }
772
773 int mm_sound_client_dbus_remove_device_connected_callback(unsigned int subs_id)
774 {
775         int ret = MM_ERROR_NONE;
776         debug_fenter();
777
778         if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
779                 debug_error("remove device connected callback failed");
780         }
781
782         debug_fleave();
783         return ret;
784 }
785
786 int mm_sound_client_dbus_add_device_info_changed_callback(int device_flags, mm_sound_device_info_changed_wrapper_cb func, void* user_data, unsigned int *subs_id)
787 {
788         int ret = MM_ERROR_NONE;
789         debug_fenter();
790
791         if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, SIGNAL_DEVICE_INFO_CHANGED, func, user_data, device_flags, subs_id)) != MM_ERROR_NONE) {
792                 debug_error("Add device info changed callback failed");
793         }
794
795         debug_fleave();
796         return ret;
797 }
798
799 int mm_sound_client_dbus_remove_device_info_changed_callback(unsigned int subs_id)
800 {
801         int ret = MM_ERROR_NONE;
802         debug_fenter();
803
804         if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
805                 debug_error("remove device info changed callback failed");
806         }
807
808         debug_fleave();
809         return ret;
810 }
811
812 int mm_sound_client_dbus_is_bt_a2dp_on (bool *connected, char** bt_name)
813 {
814         int ret = MM_ERROR_NONE;
815         GVariant* result = NULL;
816         gboolean _connected;
817         gchar* _bt_name = NULL;
818
819         debug_fenter();
820
821         if((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, METHOD_CALL_GET_BT_A2DP_STATUS, NULL, &result)) != MM_ERROR_NONE) {
822                 goto cleanup;
823         }
824         g_variant_get(result, "(bs)", &_connected, &_bt_name);
825
826         *connected = _connected;
827         *bt_name = (_connected)? _bt_name : NULL;
828
829 cleanup:
830         if (result)
831                 g_variant_unref(result);
832
833         debug_fleave();
834         return ret;
835 }
836
837 int mm_sound_client_dbus_set_volume_by_type(const char *volume_type, const unsigned int volume_level)
838 {
839         int ret = MM_ERROR_NONE;
840         char *reply = NULL, *direction = "out";
841         GVariant *params = NULL, *result = NULL;
842
843         debug_fenter();
844
845         params = g_variant_new("(ssu)", direction, volume_type, volume_level);
846         if (params) {
847                 if ((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_STREAM_MANAGER, METHOD_CALL_SET_VOLUME_LEVEL, params, &result)) != MM_ERROR_NONE) {
848                         debug_error("dbus test call failed");
849                         goto cleanup;
850                 }
851         } else {
852                 debug_error("Construct Param for method call failed");
853                 return MM_ERROR_SOUND_INTERNAL;
854         }
855
856         if (result) {
857                 g_variant_get(result, "(&s)",  &reply);
858                 debug_log("reply : %s", reply);
859                 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
860                         ret = MM_ERROR_SOUND_INTERNAL;
861         } else {
862                 debug_error("reply null");
863         }
864
865 cleanup:
866         if (result)
867                 g_variant_unref(result);
868
869         debug_fleave();
870         return ret;
871 }
872
873 int mm_sound_client_dbus_add_volume_changed_callback(mm_sound_volume_changed_wrapper_cb func, void* user_data, unsigned int *subs_id)
874 {
875         int ret = MM_ERROR_NONE;
876
877         debug_fenter();
878
879         if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_STREAM_MANAGER, SIGNAL_VOLUME_CHANGED, func, user_data, 0, subs_id)) != MM_ERROR_NONE) {
880                 debug_error("Add Volume changed callback failed");
881         }
882
883         debug_fleave();
884
885         return ret;
886 }
887
888 int mm_sound_client_dbus_remove_volume_changed_callback(unsigned int subs_id)
889 {
890         int ret = MM_ERROR_NONE;
891         debug_fenter();
892
893         if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
894                 debug_error("Remove Volume changed callback failed");
895         }
896
897         debug_fleave();
898         return ret;
899 }
900
901 int mm_sound_client_dbus_get_audio_path(mm_sound_device_in *device_in, mm_sound_device_out *device_out)
902 {
903         int ret = MM_ERROR_NONE;
904         GVariant *result = NULL;
905
906         debug_fenter();
907
908         if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_GET_AUDIO_PATH, NULL, &result)) != MM_ERROR_NONE) {
909                 debug_error("add device connected callback failed");
910                 goto cleanup;
911         }
912
913         g_variant_get(result, "(ii)", device_in, device_out );
914
915 cleanup:
916         if (result)
917                 g_variant_unref(result);
918
919         debug_fleave();
920         return ret;
921 }
922
923 int mm_sound_client_dbus_play_tone(int tone, int repeat, int volume, int volume_config,
924                            int session_type, int session_options, int client_pid,
925                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
926 {
927         int ret = MM_ERROR_NONE;
928         int handle = 0;
929         GVariant* params = NULL, *result = NULL;
930         gboolean _enable_session = enable_session;
931
932         if (!codechandle) {
933                 debug_error("Param for play is null");
934                 return MM_ERROR_INVALID_ARGUMENT;
935         }
936
937         debug_fenter();
938
939         params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume,
940                       volume_config, session_type, session_options, client_pid , _enable_session, stream_type, stream_index);
941         if (params) {
942                 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
943                         debug_error("dbus play tone failed");
944                         goto cleanup;
945                 }
946         } else {
947                 debug_error("Construct Param for method call failed");
948         }
949
950         if (result) {
951                 g_variant_get(result, "(i)",  &handle);
952                 debug_log("handle : %d", handle);
953                 *codechandle = handle;
954         } else {
955                 debug_error("reply null");
956         }
957
958 cleanup:
959         if (result)
960                 g_variant_unref(result);
961
962         debug_fleave();
963         return ret;
964
965
966 }
967
968 int mm_sound_client_dbus_play_tone_with_stream_info(int client_pid, int tone, char *stream_type, int stream_index, int volume, int repeat, int *codechandle)
969 {
970         int ret = MM_ERROR_NONE;
971         int handle = 0;
972         GVariant* params = NULL, *result = NULL;
973
974         debug_fenter();
975
976         if (!codechandle) {
977                 debug_error("Param for play is null");
978                 return MM_ERROR_INVALID_ARGUMENT;
979         }
980
981         params = g_variant_new("(iiiisi)", tone, repeat, volume, client_pid, stream_type, stream_index);
982         if (params) {
983                 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_DTMF_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
984                         debug_error("dbus play tone failed");
985                         goto cleanup;
986                 }
987         } else {
988                 debug_error("Construct Param for method call failed");
989         }
990
991         if (result) {
992                 g_variant_get(result, "(i)",  &handle);
993                 debug_log("handle : %d", handle);
994                 *codechandle = handle;
995         } else {
996                 debug_error("reply null");
997         }
998
999 cleanup:
1000         if (result)
1001                 g_variant_unref(result);
1002
1003         debug_fleave();
1004         return ret;
1005
1006
1007 }
1008
1009 int mm_sound_client_dbus_play_sound(const char* filename, int tone, int repeat, int volume, int volume_config,
1010                            int priority, int session_type, int session_options, int client_pid, int handle_route,
1011                            bool enable_session, int *codechandle, char *stream_type, int stream_index)
1012 {
1013         int ret = MM_ERROR_NONE;
1014         int handle = 0;
1015         GVariant* params = NULL, *result = NULL;
1016         gboolean _enable_session = enable_session;
1017
1018         if (!filename || !codechandle) {
1019                 debug_error("Param for play is null");
1020                 return MM_ERROR_INVALID_ARGUMENT;
1021         }
1022
1023         debug_fenter();
1024
1025         params = g_variant_new("(siiiiiiiiibsi)", filename, tone, repeat, volume,
1026                       volume_config, priority, session_type, session_options, client_pid, handle_route, _enable_session, stream_type, stream_index);
1027         if (params) {
1028                 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_START, params, &result)) != MM_ERROR_NONE) {
1029                         debug_error("dbus play file failed");
1030                         goto cleanup;
1031                 }
1032         } else {
1033                 debug_error("Construct Param for method call failed");
1034         }
1035
1036         if (result) {
1037                 g_variant_get(result, "(i)",  &handle);
1038                 debug_log("handle : %d", handle);
1039                 *codechandle = handle;
1040         } else {
1041                 debug_error("reply null");
1042         }
1043
1044 cleanup:
1045         if (result)
1046                 g_variant_unref(result);
1047
1048         debug_fleave();
1049         return ret;
1050 }
1051
1052 int mm_sound_client_dbus_play_sound_with_stream_info(const char* filename, int repeat, int volume,
1053                                 int priority, int client_pid, int handle_route, int *codechandle, char *stream_type, int stream_index)
1054 {
1055         int ret = MM_ERROR_NONE;
1056         int handle = 0;
1057         GVariant* params = NULL, *result = NULL;
1058
1059         if (!filename || !codechandle) {
1060                 debug_error("Param for play is null");
1061                 return MM_ERROR_INVALID_ARGUMENT;
1062         }
1063
1064         debug_fenter();
1065
1066         params = g_variant_new("(siiiiisi)", filename, repeat, volume,
1067                         priority, client_pid, handle_route, stream_type, stream_index);
1068         if (params) {
1069                 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_START_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
1070                         debug_error("dbus play file failed");
1071                         goto cleanup;
1072                 }
1073         } else {
1074                 debug_error("Construct Param for method call failed");
1075         }
1076
1077         if (result) {
1078                 g_variant_get(result, "(i)",  &handle);
1079                 debug_log("handle : %d", handle);
1080                 *codechandle = handle;
1081         } else {
1082                 debug_error("reply null");
1083         }
1084
1085 cleanup:
1086         if (result)
1087                 g_variant_unref(result);
1088
1089         debug_fleave();
1090         return ret;
1091
1092
1093 }
1094
1095
1096 int mm_sound_client_dbus_stop_sound(int handle)
1097 {
1098         int ret = MM_ERROR_NONE;
1099         GVariant *result = NULL;
1100
1101         debug_fenter();
1102
1103         if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_STOP, g_variant_new("(i)", handle), &result)) != MM_ERROR_NONE) {
1104                 debug_error("dbus stop file playing failed");
1105                 goto cleanup;
1106         }
1107
1108 cleanup:
1109         if (result)
1110                 g_variant_unref(result);
1111
1112         debug_fleave();
1113         return ret;
1114 }
1115
1116 int mm_sound_client_dbus_clear_focus(int pid)
1117 {
1118         int ret = MM_ERROR_NONE;
1119         GVariant *result = NULL;
1120
1121         debug_fenter();
1122
1123         if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_CLEAR_FOCUS, g_variant_new("(i)", pid), &result)) != MM_ERROR_NONE) {
1124                 debug_error("dbus clear focus failed");
1125         }
1126
1127         if (result)
1128                 g_variant_unref(result);
1129
1130         debug_fleave();
1131         return ret;
1132 }
1133
1134 int mm_sound_client_dbus_is_route_available(mm_sound_route route, bool *is_available)
1135 {
1136         int ret = MM_ERROR_NONE;
1137
1138         debug_fenter();
1139         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1140         debug_fleave();
1141
1142         return ret;
1143 }
1144
1145 int mm_sound_client_dbus_foreach_available_route_cb(mm_sound_available_route_cb avail_cb, void *user_data)
1146 {
1147         int ret = MM_ERROR_NONE;
1148
1149         debug_fenter();
1150         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1151         debug_fleave();
1152
1153         return ret;
1154 }
1155
1156 int mm_sound_client_dbus_set_active_route(mm_sound_route route, bool need_broadcast)
1157 {
1158         int ret = MM_ERROR_NONE;
1159
1160         debug_fenter();
1161         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1162         debug_fleave();
1163
1164         return ret;
1165 }
1166
1167 int mm_sound_client_dbus_get_active_device(mm_sound_device_in *device_in, mm_sound_device_out *device_out)
1168 {
1169         int ret = MM_ERROR_NONE;
1170
1171         debug_fenter();
1172         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1173         debug_fleave();
1174
1175         return ret;
1176 }
1177
1178 int mm_sound_client_dbus_add_play_sound_end_callback(mm_sound_stop_callback_wrapper_func stop_cb, void* userdata, unsigned int *subs_id)
1179 {
1180         int ret = MM_ERROR_NONE;
1181
1182         debug_fenter();
1183
1184         if ((ret = _dbus_signal_subscribe_to(DBUS_TO_SOUND_SERVER, SIGNAL_PLAY_FILE_END, stop_cb, userdata, 0, subs_id)) != MM_ERROR_NONE) {
1185                 debug_error("add play sound end callback failed");
1186         }
1187
1188         debug_fleave();
1189
1190         return ret;
1191 }
1192
1193 int mm_sound_client_dbus_remove_play_sound_end_callback(unsigned int subs_id)
1194 {
1195         int ret = MM_ERROR_NONE;
1196         debug_fenter();
1197
1198         if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
1199                 debug_error("Remove Play File End callback failed");
1200         }
1201
1202         debug_fleave();
1203         return ret;
1204 }
1205
1206 int mm_sound_client_dbus_add_active_device_changed_callback(const char *name, mm_sound_active_device_changed_cb func, void* user_data)
1207 {
1208         int ret = MM_ERROR_NONE;
1209
1210         debug_fenter();
1211         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1212         debug_fleave();
1213
1214         return ret;
1215 }
1216
1217 int mm_sound_client_dbus_remove_active_device_changed_callback(const char *name)
1218 {
1219         int ret = MM_ERROR_NONE;
1220
1221         debug_fenter();
1222         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1223         debug_fleave();
1224
1225         return ret;
1226 }
1227
1228 int mm_sound_client_dbus_add_available_route_changed_callback(mm_sound_available_route_changed_cb func, void* user_data)
1229 {
1230         int ret = MM_ERROR_NONE;
1231
1232         debug_fenter();
1233         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1234         debug_fleave();
1235
1236         return ret;
1237 }
1238
1239 int mm_sound_client_dbus_remove_available_route_changed_callback(void)
1240 {
1241         int ret = MM_ERROR_NONE;
1242
1243         debug_fenter();
1244         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1245         debug_fleave();
1246
1247         return ret;
1248 }
1249
1250 int mm_sound_client_dbus_set_sound_path_for_active_device(mm_sound_device_out device_out, mm_sound_device_in device_in)
1251 {
1252         int ret = MM_ERROR_NONE;
1253
1254         debug_fenter();
1255         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1256         debug_fleave();
1257
1258         return ret;
1259 }
1260
1261 int mm_sound_client_dbus_set_active_route_auto(void)
1262 {
1263         int ret = MM_ERROR_NONE;
1264
1265         debug_fenter();
1266         ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1267         debug_fleave();
1268
1269         return ret;
1270 }
1271
1272 /*------------------------------------------ FOCUS --------------------------------------------------*/
1273 #ifdef USE_FOCUS
1274
1275 #ifdef SUPPORT_CONTAINER
1276 #ifdef USE_SECURITY
1277 char* _get_cookie(int cookie_size)
1278 {
1279         int retval = -1;
1280         char* cookie = NULL;
1281
1282         if (security_server_get_cookie_size() != cookie_size) {
1283                 debug_error ("[Security] security_server_get_cookie_size() != COOKIE_SIZE(%d)\n", cookie_size);
1284                 return false;
1285         }
1286
1287         cookie = (char*)malloc (cookie_size);
1288
1289         retval = security_server_request_cookie (cookie, cookie_size);
1290         if (retval == SECURITY_SERVER_API_SUCCESS) {
1291                 debug_msg ("[Security] security_server_request_cookie() returns [%d]\n", retval);
1292         } else {
1293                 debug_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
1294         }
1295
1296         return cookie;
1297 }
1298
1299 static GVariant* _get_cookie_variant ()
1300 {
1301         int i;
1302         GVariantBuilder builder;
1303         char* cookie = NULL;
1304
1305         cookie = _get_cookie(COOKIE_SIZE);
1306
1307         if (cookie == NULL)
1308                 return NULL;
1309
1310         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1311         for (i = 0; i < COOKIE_SIZE; i++)
1312                 g_variant_builder_add(&builder, "y", cookie[i]);
1313
1314         free (cookie);
1315         return g_variant_builder_end(&builder);
1316 }
1317
1318 #endif /* USE_SECURITY */
1319 #endif /* SUPPORT_CONTAINER */
1320
1321 int mm_sound_client_dbus_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, bool is_for_session, void* user_data)
1322 {
1323         int ret = MM_ERROR_NONE;
1324         GVariant* params = NULL, *result = NULL;
1325 #ifdef SUPPORT_CONTAINER
1326         char container[128];
1327 #endif
1328
1329         debug_fenter();
1330
1331 #ifdef SUPPORT_CONTAINER
1332 #ifdef USE_SECURITY
1333         params = g_variant_new("(@ayiisb)", _get_cookie_variant(), instance, id, stream_type, is_for_session);
1334 #else /* USE_SECURITY */
1335         gethostname(container, sizeof(container));
1336         debug_error("container = %s", container);
1337         params = g_variant_new("(siisb)", container, instance, id, stream_type, is_for_session);
1338 #endif /* USE_SECURITY */
1339
1340 #else /* SUPPORT_CONTAINER */
1341         params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
1342
1343 #endif /* SUPPORT_CONTAINER */
1344
1345         if (params) {
1346                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
1347                         debug_error("dbus register focus failed");
1348                 }
1349         } else {
1350                 debug_error("Construct Param for method call failed");
1351         }
1352
1353         if(ret != MM_ERROR_NONE)
1354                 g_variant_get(result, "(i)",  &ret);
1355         if (result)
1356                 g_variant_unref(result);
1357
1358         debug_fleave();
1359
1360         return ret;
1361
1362 }
1363
1364 int mm_sound_client_dbus_unregister_focus(int instance, int id, bool is_for_session)
1365 {
1366         int ret = MM_ERROR_NONE;
1367         GVariant* params = NULL, *result = NULL;
1368
1369         debug_fenter();
1370
1371         params = g_variant_new("(iib)", instance, id, is_for_session);
1372         if (params) {
1373                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
1374                         debug_error("dbus unregister focus failed");
1375                 }
1376         } else {
1377                 debug_error("Construct Param for method call failed");
1378         }
1379
1380         if (ret != MM_ERROR_NONE)
1381                 g_variant_get(result, "(i)",  &ret);
1382         if (result)
1383                 g_variant_unref(result);
1384
1385         debug_fleave();
1386
1387         return ret;
1388 }
1389
1390 int mm_sound_client_dbus_acquire_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
1391 {
1392         int ret = MM_ERROR_NONE;
1393         GVariant* params = NULL, *result = NULL;
1394
1395         debug_fenter();
1396
1397         params = g_variant_new("(iiisb)", instance, id, type, option, is_for_session);
1398         if (params) {
1399                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE) {
1400                         debug_error("dbus acquire focus failed");
1401                 }
1402         } else {
1403                 debug_error("Construct Param for method call failed");
1404         }
1405
1406         if (ret != MM_ERROR_NONE)
1407                 g_variant_get(result, "(i)",  &ret);
1408         if (result)
1409                 g_variant_unref(result);
1410
1411         debug_fleave();
1412         return ret;
1413 }
1414
1415 int mm_sound_client_dbus_release_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
1416 {
1417         int ret = MM_ERROR_NONE;
1418         GVariant* params = NULL, *result = NULL;
1419
1420         debug_fenter();
1421
1422         params = g_variant_new("(iiisb)", instance, id, type, option, is_for_session);
1423         if (params) {
1424                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE) {
1425                         debug_error("dbus release focus failed");
1426                 }
1427         } else {
1428                 debug_error("Construct Param for method call failed");
1429         }
1430
1431         if (ret != MM_ERROR_NONE)
1432                 g_variant_get(result, "(i)",  &ret);
1433         if (result)
1434                 g_variant_unref(result);
1435
1436         debug_fleave();
1437         return ret;
1438 }
1439
1440 int mm_sound_client_dbus_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* user_data)
1441 {
1442         int ret = MM_ERROR_NONE;
1443         GVariant* params = NULL, *result = NULL;
1444 #ifdef SUPPORT_CONTAINER
1445         char container[128];
1446 #endif
1447
1448         debug_fenter();
1449 #ifdef SUPPORT_CONTAINER
1450 #ifdef USE_SECURITY
1451         params = g_variant_new("(@ayiiib)", _get_cookie_variant(), instance, handle, type, is_for_session);
1452 #else /* USE_SECURITY */
1453         gethostname(container, sizeof(container));
1454         debug_error("container = %s", container);
1455         params = g_variant_new("(siiib)", container, instance, handle, type, is_for_session);
1456 #endif /* USE_SECURITY */
1457
1458 #else /* SUPPORT_CONTAINER */
1459         params = g_variant_new("(iiib)", instance, handle, type, is_for_session);
1460 #endif /* SUPPORT_CONTAINER */
1461
1462         if (params) {
1463                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1464                         debug_error("dbus set watch focus failed");
1465                 }
1466         } else {
1467                 debug_error("Construct Param for method call failed");
1468         }
1469
1470         if (ret != MM_ERROR_NONE)
1471                 g_variant_get(result, "(i)",  &ret);
1472         if (result)
1473                 g_variant_unref(result);
1474         debug_fleave();
1475
1476         return ret;
1477
1478 }
1479
1480 int mm_sound_client_dbus_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session)
1481 {
1482         int ret = MM_ERROR_NONE;
1483         GVariant* params = NULL, *result = NULL;
1484
1485         debug_fenter();
1486
1487         params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
1488         if (params) {
1489                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1490                         debug_error("dbus unset watch focus failed");
1491                 }
1492         } else {
1493                 debug_error("Construct Param for method call failed");
1494         }
1495         if (ret != MM_ERROR_NONE)
1496                 g_variant_get(result, "(i)",  &ret);
1497         if (result)
1498                 g_variant_unref(result);
1499
1500         debug_fleave();
1501
1502         return ret;
1503 }
1504
1505 int mm_sound_client_dbus_emergent_exit_focus(int exit_pid)
1506 {
1507         int ret = MM_ERROR_NONE;
1508         GVariant* params = NULL, *result = NULL;
1509
1510         debug_fenter();
1511
1512         params = g_variant_new("(i)", exit_pid);
1513         if (params) {
1514                 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_EMERGENT_EXIT_FOCUS, params, &result)) != MM_ERROR_NONE) {
1515                         debug_error("dbus emergent exit focus failed");
1516                         goto cleanup;
1517                 }
1518         } else {
1519                 debug_error("Construct Param for method call failed");
1520         }
1521
1522 cleanup:
1523         if (ret != MM_ERROR_NONE)
1524                 g_variant_get(result, "(i)",  &ret);
1525         if (result)
1526                 g_variant_unref(result);
1527
1528         debug_fleave();
1529         return ret;
1530 }
1531
1532 #endif /* USE_FOCUS */
1533 /*------------------------------------------ FOCUS --------------------------------------------------*/
1534
1535 int mm_sound_client_dbus_initialize(void)
1536 {
1537         int ret = MM_ERROR_NONE;
1538
1539         debug_fenter();
1540         debug_fleave();
1541
1542         return ret;
1543 }
1544
1545 int mm_sound_client_dbus_finalize(void)
1546 {
1547         int ret = MM_ERROR_NONE;
1548
1549         debug_fenter();
1550         debug_fleave();
1551
1552         return ret;
1553 }