98d85d6e1f149fdf78e3ab88a58b8087b29f716d
[platform/core/multimedia/libmm-sound.git] / focus_server / mm_sound_mgr_focus_dbus.c
1
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <mm_error.h>
6 #include <mm_debug.h>
7
8 #include <gio/gio.h>
9
10 #include "include/mm_sound_mgr_focus.h"
11 #include "include/mm_sound_mgr_focus_dbus.h"
12 #include "include/mm_sound_mgr_focus_ipc.h"
13 #include "../include/mm_sound_dbus.h"
14
15
16 #define BUS_NAME_FOCUS_SERVER "org.tizen.FocusServer"
17 #define OBJECT_FOCUS_SERVER "/org/tizen/FocusServer1"
18 #define INTERFACE_FOCUS_SERVER "org.tizen.FocusServer1"
19
20 /* Introspection data for the service we are exporting */
21 static const gchar introspection_xml[] =
22         "<node>"
23         "  <interface name='org.tizen.FocusServer1'>"
24         "    <method name='GetUniqueId'>"
25         "      <arg name='id' type='i' direction='out'/>"
26         "    </method>"
27         "    <method name='RegisterFocus'>"
28         "      <arg name='pid' type='i' direction='in'/>"
29         "      <arg name='handle_id' type='i' direction='in'/>"
30         "      <arg name='stream_type' type='s' direction='in'/>"
31         "    </method>"
32         "    <method name='UnregisterFocus'>"
33         "      <arg name='pid' type='i' direction='in'/>"
34         "      <arg name='handle_id' type='i' direction='in'/>"
35         "    </method>"
36         "    <method name='SetFocusReacquisition'>"
37         "      <arg name='pid' type='i' direction='in'/>"
38         "      <arg name='handle_id' type='i' direction='in'/>"
39         "      <arg name='reacquisition' type='b' direction='in'/>"
40         "    </method>"
41         "    <method name='GetAcquiredFocusStreamType'>"
42         "      <arg name='focus_type' type='i' direction='in'/>"
43         "      <arg name='stream_type' type='s' direction='out'/>"
44         "      <arg name='option' type='i' direction='out'/>"
45         "      <arg name='ext_info' type='s' direction='out'/>"
46         "    </method>"
47         "    <method name='AcquireFocus'>"
48         "      <arg name='pid' type='i' direction='in'/>"
49         "      <arg name='handle_id' type='i' direction='in'/>"
50         "      <arg name='focus_type' type='i' direction='in'/>"
51         "      <arg name='option' type='i' direction='in'/>"
52         "      <arg name='ext_info' type='s' direction='in'/>"
53         "    </method>"
54         "    <method name='ReleaseFocus'>"
55         "      <arg name='pid' type='i' direction='in'/>"
56         "      <arg name='handle_id' type='i' direction='in'/>"
57         "      <arg name='focus_type' type='i' direction='in'/>"
58         "      <arg name='option' type='i' direction='in'/>"
59         "      <arg name='ext_info' type='s' direction='in'/>"
60         "    </method>"
61         "    <method name='WatchFocus'>"
62         "      <arg name='pid' type='i' direction='in'/>"
63         "      <arg name='handle_id' type='i' direction='in'/>"
64         "      <arg name='focus_type' type='i' direction='in'/>"
65         "    </method>"
66         "    <method name='UnwatchFocus'>"
67         "      <arg name='pid' type='i' direction='in'/>"
68         "      <arg name='handle_id' type='i' direction='in'/>"
69         "    </method>"
70         "    <method name='DeliverFocus'>"
71         "      <arg name='pid' type='i' direction='in'/>"
72         "      <arg name='src_handle_id' type='i' direction='in'/>"
73         "      <arg name='dst_handle_id' type='i' direction='in'/>"
74         "      <arg name='focus_type' type='i' direction='in'/>"
75         "    </method>"
76         "    <method name='EmergentExitFocus'>"
77         "      <arg name='pid' type='i' direction='in'/>"
78         "    </method>"
79         "  </interface>"
80         "</node>";
81 static GDBusConnection* conn_g;
82
83 typedef void (*dbus_method_handler)(GDBusMethodInvocation *invocation);
84 typedef int (*dbus_signal_sender)(GDBusConnection *conn, GVariant *parameter);
85
86 struct mm_sound_mgr_focus_dbus_method {
87         struct mm_sound_dbus_method_info info;
88         dbus_method_handler handler;
89 };
90
91 struct mm_sound_mgr_focus_dbus_signal {
92         struct mm_sound_dbus_signal_info info;
93         dbus_signal_sender sender;
94 };
95
96 static void handle_method_get_unique_id(GDBusMethodInvocation* invocation);
97 static void handle_method_register_focus(GDBusMethodInvocation* invocation);
98 static void handle_method_unregister_focus(GDBusMethodInvocation* invocation);
99 static void handle_method_set_focus_reacquisition(GDBusMethodInvocation* invocation);
100 static void handle_method_get_acquired_focus_stream_type(GDBusMethodInvocation* invocation);
101 static void handle_method_acquire_focus(GDBusMethodInvocation* invocation);
102 static void handle_method_release_focus(GDBusMethodInvocation* invocation);
103 static void handle_method_watch_focus(GDBusMethodInvocation* invocation);
104 static void handle_method_unwatch_focus(GDBusMethodInvocation* invocation);
105 static void handle_method_deliver_focus(GDBusMethodInvocation* invocation);
106
107 /* Currently , Just using method's name and handler */
108 /* TODO : generate introspection xml automatically, with these value include argument and reply */
109 /* TODO : argument check with these information */
110 /* TODO : divide object and interface with features (ex. play, path, device, focus, asm) */
111 static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
112         [AUDIO_METHOD_GET_UNIQUE_ID] = {
113                 .info = {
114                         .name = "GetUniqueId",
115                 },
116                 .handler = handle_method_get_unique_id
117         },
118         [AUDIO_METHOD_REGISTER_FOCUS] = {
119                 .info = {
120                         .name = "RegisterFocus",
121                 },
122                 .handler = handle_method_register_focus
123         },
124         [AUDIO_METHOD_UNREGISTER_FOCUS] = {
125                 .info = {
126                         .name = "UnregisterFocus",
127                 },
128                 .handler = handle_method_unregister_focus
129         },
130         [AUDIO_METHOD_SET_FOCUS_REACQUISITION] = {
131                 .info = {
132                         .name = "SetFocusReacquisition",
133                 },
134                 .handler = handle_method_set_focus_reacquisition
135         },
136         [AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE] = {
137                 .info = {
138                         .name = "GetAcquiredFocusStreamType",
139                 },
140                 .handler = handle_method_get_acquired_focus_stream_type
141         },
142         [AUDIO_METHOD_ACQUIRE_FOCUS] = {
143                 .info = {
144                         .name = "AcquireFocus",
145                 },
146                 .handler = handle_method_acquire_focus
147         },
148         [AUDIO_METHOD_RELEASE_FOCUS] = {
149                 .info = {
150                         .name = "ReleaseFocus",
151                 },
152                 .handler = handle_method_release_focus
153         },
154         [AUDIO_METHOD_WATCH_FOCUS] = {
155                 .info = {
156                         .name = "WatchFocus",
157                 },
158                 .handler = handle_method_watch_focus
159         },
160         [AUDIO_METHOD_UNWATCH_FOCUS] = {
161                 .info = {
162                         .name = "UnwatchFocus",
163                 },
164                 .handler = handle_method_unwatch_focus
165         },
166         [AUDIO_METHOD_DELIVER_FOCUS] = {
167                 .info = {
168                         .name = "DeliverFocus",
169                 },
170                 .handler = handle_method_deliver_focus
171         }
172 };
173
174 static GDBusNodeInfo *introspection_data = NULL;
175 guint focus_server_owner_id ;
176 unsigned emergent_exit_subs_id;
177
178 /*
179         For pass error code with 'g_dbus_method_invocation_return_error'
180         We have to use some glib features like GError, GQuark
181 */
182 /* Only For error types which is currently being used in server-side */
183 static const GDBusErrorEntry mm_sound_error_entries[] = {
184         {MM_ERROR_OUT_OF_MEMORY, "org.tizen.multimedia.OutOfMemory"},
185         {MM_ERROR_OUT_OF_STORAGE, "org.tizen.multimedia.OutOfStorage"},
186         {MM_ERROR_INVALID_ARGUMENT, "org.tizen.multimedia.InvalidArgument"},
187         {MM_ERROR_POLICY_INTERNAL, "org.tizen.multimedia.PolicyInternal"},
188         {MM_ERROR_NOT_SUPPORT_API, "org.tizen.multimedia.NotSupportAPI"},
189         {MM_ERROR_POLICY_BLOCKED, "org.tizen.multimedia.PolicyBlocked"},
190         {MM_ERROR_END_OF_FILE, "org.tizen.multimedia.EndOfFile"},
191         {MM_ERROR_COMMON_OUT_OF_RANGE, "org.tizen.multimedia.common.OutOfRange"},
192         {MM_ERROR_COMMON_UNKNOWN, "org.tizen.multimedia.common.Unknown"},
193         {MM_ERROR_COMMON_NO_FREE_SPACE, "org.tizen.multimedia.common.NoFreeSpace"},
194         {MM_ERROR_SOUND_INTERNAL, "org.tizen.multimedia.audio.Internal"},
195         {MM_ERROR_SOUND_INVALID_STATE, "org.tizen.multimedia.audio.InvalidState"},
196         {MM_ERROR_SOUND_NO_FREE_SPACE, "org.tizen.multimedia.audio.NoFreeSpace"},
197         {MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE, "org.tizen.multimedia.audio.UnsupportedMediaType"},
198         {MM_ERROR_SOUND_INVALID_POINTER, "org.tizen.multimedia.audio.InvalidPointer"},
199         {MM_ERROR_SOUND_INVALID_FILE, "org.tizen.multimedia.audio.InvalidFile"},
200         {MM_ERROR_SOUND_FILE_NOT_FOUND, "org.tizen.multimedia.audio.FileNotFound"},
201         {MM_ERROR_SOUND_NO_DATA, "org.tizen.multimedia.audio.NoData"},
202         {MM_ERROR_SOUND_INVALID_PATH, "org.tizen.multimedia.audio.InvalidPath"},
203 };
204
205 static const char* _convert_error_code(int err_code)
206 {
207         int i = 0;
208
209         for (i = 0; i < G_N_ELEMENTS(mm_sound_error_entries); i++) {
210                 if (err_code == mm_sound_error_entries[i].error_code)
211                         return mm_sound_error_entries[i].dbus_error_name;
212         }
213
214         return "org.tizen.multimedia.common.Unknown";
215 }
216
217 static int _get_sender_pid(GDBusMethodInvocation* invocation)
218 {
219         GVariant* value;
220         guint pid = 0;
221         const gchar* sender;
222         GDBusConnection * connection = NULL;
223         GError* err = NULL;
224
225         connection = g_dbus_method_invocation_get_connection(invocation);
226         sender = g_dbus_method_invocation_get_sender(invocation);
227
228         debug_msg("connection = %p, sender = %s", connection, sender);
229
230         value = g_dbus_connection_call_sync(connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
231                                                                                 "org.freedesktop.DBus", "GetConnectionUnixProcessID",
232                                                                                 g_variant_new("(s)", sender, NULL), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
233         if (value) {
234                 g_variant_get(value, "(u)", &pid);
235                 debug_msg("Sender PID = [%d]", pid);
236                 g_variant_unref(value);
237         } else {
238                 debug_error("err code = %d, err msg = %s", err->code, err->message);
239         }
240         return pid;
241 }
242
243 static void _method_call_return_value(GDBusMethodInvocation *invocation, GVariant *params)
244 {
245         const char *method_name;
246         method_name = g_dbus_method_invocation_get_method_name(invocation);
247         debug_msg("Method Call '%s' success", method_name);
248         g_dbus_method_invocation_return_value(invocation, params);
249 }
250 static void _method_call_return_error(GDBusMethodInvocation *invocation, int ret)
251 {
252         const char *err_name, *method_name;
253         err_name = _convert_error_code(ret);
254         method_name = g_dbus_method_invocation_get_method_name(invocation);
255         debug_error("Method Call '%s' failed, err '%s(%X)'", method_name, err_name, ret);
256         g_dbus_method_invocation_return_dbus_error(invocation, err_name, "failed");
257 }
258
259 static void handle_method_get_unique_id(GDBusMethodInvocation* invocation)
260 {
261         static int unique_id = 0;
262
263         debug_fenter();
264
265         _method_call_return_value(invocation, g_variant_new("(i)", ++unique_id));
266
267         debug_fleave();
268 }
269
270 static void handle_method_register_focus(GDBusMethodInvocation* invocation)
271 {
272         int ret = MM_ERROR_NONE;
273         int handle_id = 0;
274         const char* stream_type = NULL;
275         GVariant *params = NULL;
276         int pid = 0;
277
278         debug_fenter();
279
280         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
281                 debug_error("Parameter for Method is NULL");
282                 ret = MM_ERROR_SOUND_INTERNAL;
283                 goto send_reply;
284         }
285
286         g_variant_get(params, "(ii&s)", &pid, &handle_id, &stream_type);
287         ret = __mm_sound_mgr_focus_ipc_register_focus(_get_sender_pid(invocation), handle_id, stream_type);
288
289 send_reply:
290         if (ret == MM_ERROR_NONE)
291                 _method_call_return_value(invocation, g_variant_new("()"));
292         else
293                 _method_call_return_error(invocation, ret);
294
295         debug_fleave();
296 }
297
298 static void handle_method_unregister_focus(GDBusMethodInvocation* invocation)
299 {
300         int ret = MM_ERROR_NONE;
301         int pid = 0, handle_id = 0;
302         GVariant *params = NULL;
303
304         debug_fenter();
305
306         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
307                 debug_error("Parameter for Method is NULL");
308                 ret = MM_ERROR_SOUND_INTERNAL;
309                 goto send_reply;
310         }
311
312         g_variant_get(params, "(ii)", &pid, &handle_id);
313         ret = __mm_sound_mgr_focus_ipc_unregister_focus(_get_sender_pid(invocation), handle_id);
314
315 send_reply:
316         if (ret == MM_ERROR_NONE)
317                 _method_call_return_value(invocation, g_variant_new("()"));
318         else
319                 _method_call_return_error(invocation, ret);
320
321         debug_fleave();
322 }
323
324 static void handle_method_set_focus_reacquisition(GDBusMethodInvocation* invocation)
325 {
326         int ret = MM_ERROR_NONE;
327         int pid = 0, handle_id = 0;
328         gboolean reacquisition;
329         GVariant *params = NULL;
330
331         debug_fenter();
332
333         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
334                 debug_error("Parameter for Method is NULL");
335                 ret = MM_ERROR_SOUND_INTERNAL;
336                 goto send_reply;
337         }
338
339         g_variant_get(params, "(iib)", &pid, &handle_id, &reacquisition);
340         ret = __mm_sound_mgr_focus_ipc_set_focus_reacquisition(_get_sender_pid(invocation), handle_id, reacquisition);
341
342 send_reply:
343         if (ret == MM_ERROR_NONE)
344                 _method_call_return_value(invocation, g_variant_new("()"));
345         else
346                 _method_call_return_error(invocation, ret);
347
348         debug_fleave();
349 }
350
351 static void handle_method_get_acquired_focus_stream_type(GDBusMethodInvocation* invocation)
352 {
353         int ret = MM_ERROR_NONE;
354         int focus_type = 0;
355         char *stream_type = NULL;
356         int option = 0;
357         char *ext_info = NULL;
358         GVariant *params = NULL;
359
360         debug_fenter();
361
362         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
363                 debug_error("Parameter for Method is NULL");
364                 ret = MM_ERROR_SOUND_INTERNAL;
365                 goto send_reply;
366         }
367
368         g_variant_get(params, "(i)", &focus_type);
369         ret = __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(focus_type, &stream_type, &option, &ext_info);
370
371 send_reply:
372         if (ret == MM_ERROR_NONE)
373                 _method_call_return_value(invocation, g_variant_new("(sis)", stream_type, option, ext_info));
374         else
375                 _method_call_return_error(invocation, ret);
376
377         debug_fleave();
378 }
379
380 static void handle_method_acquire_focus(GDBusMethodInvocation* invocation)
381 {
382         int ret = MM_ERROR_NONE;
383         int pid = 0, handle_id = 0, focus_type = 0, option = 0;
384         const char* ext_info = NULL;
385         GVariant *params = NULL;
386
387         debug_fenter();
388
389         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
390                 debug_error("Parameter for Method is NULL");
391                 ret = MM_ERROR_SOUND_INTERNAL;
392                 goto send_reply;
393         }
394
395         g_variant_get(params, "(iiiis)", &pid, &handle_id, &focus_type, &option, &ext_info);
396         ret = __mm_sound_mgr_focus_ipc_acquire_focus(_get_sender_pid(invocation),
397                                                                                                 handle_id, focus_type, option, ext_info, false);
398
399 send_reply:
400         if (ret == MM_ERROR_NONE)
401                 _method_call_return_value(invocation, g_variant_new("()"));
402         else
403                 _method_call_return_error(invocation, ret);
404
405         debug_fleave();
406 }
407
408 static void handle_method_release_focus(GDBusMethodInvocation* invocation)
409 {
410         int ret = MM_ERROR_NONE;
411         int pid = 0, handle_id = 0, focus_type = 0, option = 0;
412         const char* ext_info = NULL;
413         GVariant *params = NULL;
414
415         debug_fenter();
416
417         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
418                 debug_error("Parameter for Method is NULL");
419                 ret = MM_ERROR_SOUND_INTERNAL;
420                 goto send_reply;
421         }
422
423         g_variant_get(params, "(iiiis)", &pid, &handle_id, &focus_type, &option, &ext_info);
424         ret = __mm_sound_mgr_focus_ipc_release_focus(_get_sender_pid(invocation),
425                                                                                                 handle_id, focus_type, option, ext_info, false);
426
427 send_reply:
428         if (ret == MM_ERROR_NONE)
429                 _method_call_return_value(invocation, g_variant_new("()"));
430         else
431                 _method_call_return_error(invocation, ret);
432
433         debug_fleave();
434 }
435
436 static void handle_method_watch_focus(GDBusMethodInvocation* invocation)
437 {
438         int ret = MM_ERROR_NONE;
439         int handle_id = 0, focus_type = 0;
440         GVariant *params = NULL;
441         int pid = 0;
442
443         debug_fenter();
444
445         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
446                 debug_error("Parameter for Method is NULL");
447                 ret = MM_ERROR_SOUND_INTERNAL;
448                 goto send_reply;
449         }
450
451         g_variant_get(params, "(iii)", &pid, &handle_id, &focus_type);
452         ret = __mm_sound_mgr_focus_ipc_watch_focus(_get_sender_pid(invocation), handle_id, focus_type);
453
454 send_reply:
455         if (ret == MM_ERROR_NONE)
456                 _method_call_return_value(invocation, g_variant_new("()"));
457         else
458                 _method_call_return_error(invocation, ret);
459
460         debug_fleave();
461 }
462
463 static void handle_method_unwatch_focus(GDBusMethodInvocation* invocation)
464 {
465         int ret = MM_ERROR_NONE;
466         int pid = 0;
467         int handle_id = 0;
468         GVariant *params = NULL;
469
470         debug_fenter();
471
472         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
473                 debug_error("Parameter for Method is NULL");
474                 ret = MM_ERROR_SOUND_INTERNAL;
475                 goto send_reply;
476         }
477
478         g_variant_get(params, "(ii)", &pid, &handle_id);
479         ret = __mm_sound_mgr_focus_ipc_unwatch_focus(_get_sender_pid(invocation), handle_id);
480
481 send_reply:
482         if (ret == MM_ERROR_NONE)
483                 _method_call_return_value(invocation, g_variant_new("()"));
484         else
485                 _method_call_return_error(invocation, ret);
486
487         debug_fleave();
488 }
489
490 static void handle_method_deliver_focus(GDBusMethodInvocation* invocation)
491 {
492         int ret = MM_ERROR_NONE;
493         int pid = 0;
494         int src_handle_id = 0;
495         int dst_handle_id = 0;
496         int focus_type = 0;
497         GVariant *params = NULL;
498
499         debug_fenter();
500
501         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
502                 debug_error("Parameter for Method is NULL");
503                 ret = MM_ERROR_SOUND_INTERNAL;
504                 goto send_reply;
505         }
506
507         g_variant_get(params, "(iiii)", &pid, &src_handle_id, &dst_handle_id, &focus_type);
508         ret = __mm_sound_mgr_focus_ipc_deliver_focus(pid, src_handle_id, dst_handle_id, focus_type);
509
510 send_reply:
511         if (ret == MM_ERROR_NONE)
512                 _method_call_return_value(invocation, g_variant_new("()"));
513         else
514                 _method_call_return_error(invocation, ret);
515
516         debug_fleave();
517 }
518
519 /**********************************************************************************/
520 static void handle_method_call(GDBusConnection *connection,
521                                                         const gchar *sender,
522                                                         const gchar *object_path,
523                                                         const gchar *interface_name,
524                                                         const gchar *method_name,
525                                                         GVariant *parameters,
526                                                         GDBusMethodInvocation *invocation,
527                                                         gpointer userdata)
528 {
529         int method_idx = 0;
530
531         if (!parameters) {
532                 debug_error("Parameter Null");
533                 return;
534         }
535         debug_msg("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
536
537         for (method_idx = AUDIO_METHOD_GET_UNIQUE_ID; method_idx < AUDIO_METHOD_MAX; method_idx++) {
538                 if (!g_strcmp0(method_name, methods[method_idx].info.name))
539                         methods[method_idx].handler(invocation);
540         }
541 }
542
543 static GVariant* handle_get_property(GDBusConnection *connection,
544                                                                         const gchar *sender,
545                                                                         const gchar *object_path,
546                                                                         const gchar *interface_name,
547                                                                         const gchar *property_name,
548                                                                         GError **error,
549                                                                         gpointer userdata)
550 {
551         debug_log("Get Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
552         return NULL;
553 }
554
555 static gboolean handle_set_property(GDBusConnection *connection,
556                                                                         const gchar *sender,
557                                                                         const gchar *object_path,
558                                                                         const gchar *interface_name,
559                                                                         const gchar *property_name,
560                                                                         GVariant *value,
561                                                                         GError **error,
562                                                                         gpointer userdata)
563 {
564         debug_log("Set Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
565         return TRUE;
566 }
567
568 void emergent_exit_signal_handler(audio_event_t event, GVariant *param, void *userdata)
569 {
570         int ret = MM_ERROR_NONE;
571         int pid = 0;
572
573         if (event != AUDIO_EVENT_EMERGENT_EXIT)
574                 return;
575
576         debug_fenter();
577
578         g_variant_get(param, "(i)", &pid);
579         debug_log("emergent exit : pid %d", pid);
580         ret = __mm_sound_mgr_focus_ipc_emergent_exit(pid);
581         if (ret)
582                 debug_error("__mm_sound_mgr_focus_ipc_emergent_exit failed : 0x%x", ret);
583
584         debug_fleave();
585 }
586
587 static const GDBusInterfaceVTable interface_vtable = {
588         handle_method_call,
589         handle_get_property,
590         handle_set_property
591 };
592
593 static void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
594 {
595         guint reg_id;
596         debug_log("Bus Acquired (%s)", name);
597
598         conn_g = connection;
599         reg_id = g_dbus_connection_register_object(connection,
600                                           OBJECT_FOCUS_SERVER,
601                                           introspection_data->interfaces[0],
602                                           &interface_vtable,
603                                           NULL,
604                                           NULL,
605                                           NULL);
606         if (!reg_id) {
607                 debug_error("Register object(%s) failed", OBJECT_FOCUS_SERVER);
608                 return ;
609         }
610 }
611
612 static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
613 {
614         debug_log("Name Acquired (%s)", name);
615 }
616
617 static void on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
618 {
619         debug_log("Name Lost (%s)", name);
620 }
621
622 static int _mm_sound_mgr_focus_dbus_own_name(GBusType bus_type, const char* wellknown_name, guint* owner_id)
623 {
624         guint oid;
625
626         debug_msg("Own name (%s) for focus-server", wellknown_name);
627
628         oid = g_bus_own_name(bus_type, wellknown_name, G_BUS_NAME_OWNER_FLAGS_NONE,
629                         on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL);
630         if (oid <= 0) {
631                 debug_error("Dbus own name failed");
632                 return MM_ERROR_SOUND_INTERNAL;
633         } else {
634                 *owner_id = oid;
635         }
636
637         debug_msg("OwnerID (%d) for focus-server", *owner_id);
638
639         return MM_ERROR_NONE;
640 }
641
642 static void _mm_sound_mgr_focus_dbus_unown_name(guint oid)
643 {
644         debug_msg("Unown name for focus-server [%d]", oid);
645         if (oid > 0)
646                 g_bus_unown_name(oid);
647 }
648
649 #define PA_BUS_NAME                                    "org.pulseaudio.Server"
650 #define PA_STREAM_MANAGER_OBJECT_PATH                  "/org/pulseaudio/StreamManager"
651 #define PA_STREAM_MANAGER_INTERFACE                    "org.pulseaudio.StreamManager"
652 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST  "GetStreamList"
653 int __mm_sound_mgr_focus_dbus_get_stream_list(stream_list_t* stream_list)
654 {
655         int ret = MM_ERROR_NONE;
656         GVariant *result = NULL;
657         GVariant *child = NULL;
658         GDBusConnection *conn = NULL;
659         GError *err = NULL;
660         int i = 0;
661
662         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
663         if (!conn || err) {
664                 LOGE("g_bus_get_sync() error (%s)", err ? err->message : NULL);
665                 g_error_free(err);
666                 ret = MM_ERROR_SOUND_INTERNAL;
667                 return ret;
668         }
669         result = g_dbus_connection_call_sync(conn,
670                                                         PA_BUS_NAME,
671                                                         PA_STREAM_MANAGER_OBJECT_PATH,
672                                                         PA_STREAM_MANAGER_INTERFACE,
673                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST,
674                                                         NULL,
675                                                         G_VARIANT_TYPE("(vv)"),
676                                                         G_DBUS_CALL_FLAGS_NONE,
677                                                         2000,
678                                                         NULL,
679                                                         &err);
680         if (!result || err) {
681                 debug_error("g_dbus_connection_call_sync() error (%s)", err ? err->message : NULL);
682                 g_error_free(err);
683                 ret = MM_ERROR_SOUND_INTERNAL;
684         } else {
685                 GVariantIter iter;
686                 GVariant *item = NULL;
687                 child = g_variant_get_child_value(result, 0);
688                 item = g_variant_get_variant(child);
689                 gchar *name;
690                 i = 0;
691                 g_variant_iter_init(&iter, item);
692                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "&s", &name)) {
693                         debug_log("name : %s", name);
694                         stream_list->stream_types[i++] = strdup(name);
695                 }
696                 g_variant_unref(item);
697                 g_variant_unref(child);
698
699                 child = g_variant_get_child_value(result, 1);
700                 item = g_variant_get_variant(child);
701                 gint32 priority;
702                 i = 0;
703                 g_variant_iter_init(&iter, item);
704                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "i", &priority)) {
705                         debug_log("priority : %d", priority);
706                         stream_list->priorities[i++] = priority;
707                 }
708                 g_variant_unref(item);
709                 g_variant_unref(child);
710         }
711
712         g_variant_unref(result);
713         g_object_unref(conn);
714
715         return ret;
716 }
717
718 int MMSoundMgrFocusDbusInit(void)
719 {
720         debug_enter();
721
722         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
723         if (!introspection_data)
724                 return MM_ERROR_SOUND_INTERNAL;
725
726         if (_mm_sound_mgr_focus_dbus_own_name(G_BUS_TYPE_SYSTEM, BUS_NAME_FOCUS_SERVER, &focus_server_owner_id) != MM_ERROR_NONE) {
727                 debug_error("dbus own name for focus-server error");
728                 return MM_ERROR_SOUND_INTERNAL;
729         }
730         if (mm_sound_dbus_signal_subscribe_to(AUDIO_PROVIDER_AUDIO_CLIENT, AUDIO_EVENT_EMERGENT_EXIT, emergent_exit_signal_handler, NULL, NULL, &emergent_exit_subs_id) != MM_ERROR_NONE) {
731                 debug_error("dbus signal subscribe for emergent exit error");
732                 return MM_ERROR_SOUND_INTERNAL;
733         }
734
735         debug_leave();
736
737         return MM_ERROR_NONE;
738 }
739
740 void MMSoundMgrFocusDbusFini(void)
741 {
742         debug_enter();
743
744         if (emergent_exit_subs_id != 0)
745                 mm_sound_dbus_signal_unsubscribe(emergent_exit_subs_id);
746         _mm_sound_mgr_focus_dbus_unown_name(focus_server_owner_id);
747         g_dbus_node_info_unref(introspection_data);
748
749         debug_leave();
750 }