fixup! Enhance session backward compatibility
[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_dbus.h"
11 #include "include/mm_sound_mgr_focus_ipc.h"
12 #include "../include/mm_sound_dbus.h"
13
14
15 #define BUS_NAME_FOCUS_SERVER "org.tizen.FocusServer"
16 #define OBJECT_FOCUS_SERVER "/org/tizen/FocusServer1"
17 #define INTERFACE_FOCUS_SERVER "org.tizen.FocusServer1"
18
19 /* Introspection data for the service we are exporting */
20 static const gchar introspection_xml[] =
21   "<node>"
22   "  <interface name='org.tizen.FocusServer1'>"
23   "    <method name='GetUniqueId'>"
24   "      <arg name='id' type='i' direction='out'/>"
25   "    </method>"
26   "    <method name='RegisterFocus'>"
27   "      <arg name='pid' type='i' direction='in'/>"
28   "      <arg name='handle_id' type='i' direction='in'/>"
29   "      <arg name='stream_type' type='s' direction='in'/>"
30   "      <arg name='is_for_session' type='b' 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   "      <arg name='is_for_session' type='b' direction='in'/>"
36   "    </method>"
37   "    <method name='SetFocusReacquisition'>"
38   "      <arg name='pid' type='i' direction='in'/>"
39   "      <arg name='handle_id' type='i' direction='in'/>"
40   "      <arg name='reacquisition' type='b' direction='in'/>"
41   "      <arg name='is_for_session' type='b' direction='in'/>"
42   "    </method>"
43   "    <method name='GetAcquiredFocusStreamType'>"
44   "      <arg name='focus_type' type='i' direction='in'/>"
45   "      <arg name='stream_type' type='s' direction='out'/>"
46   "      <arg name='option' type='i' direction='out'/>"
47   "      <arg name='ext_info' type='s' direction='out'/>"
48   "    </method>"
49   "    <method name='AcquireFocus'>"
50   "      <arg name='pid' type='i' direction='in'/>"
51   "      <arg name='handle_id' type='i' direction='in'/>"
52   "      <arg name='focus_type' type='i' direction='in'/>"
53   "      <arg name='option' type='i' direction='in'/>"
54   "      <arg name='ext_info' type='s' direction='in'/>"
55   "      <arg name='is_for_session' type='b' direction='in'/>"
56   "    </method>"
57   "    <method name='ReleaseFocus'>"
58   "      <arg name='pid' type='i' direction='in'/>"
59   "      <arg name='handle_id' type='i' direction='in'/>"
60   "      <arg name='focus_type' type='i' direction='in'/>"
61   "      <arg name='option' type='i' direction='in'/>"
62   "      <arg name='ext_info' type='s' direction='in'/>"
63   "      <arg name='is_for_session' type='b' direction='in'/>"
64   "    </method>"
65   "    <method name='WatchFocus'>"
66   "      <arg name='pid' type='i' direction='in'/>"
67   "      <arg name='handle_id' type='i' direction='in'/>"
68   "      <arg name='focus_type' type='i' direction='in'/>"
69   "      <arg name='is_for_session' type='b' direction='in'/>"
70   "    </method>"
71   "    <method name='UnwatchFocus'>"
72   "      <arg name='pid' type='i' direction='in'/>"
73   "      <arg name='handle_id' type='i' direction='in'/>"
74   "      <arg name='is_for_session' type='b' 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
106 /* Currently , Just using method's name and handler */
107 /* TODO : generate introspection xml automatically, with these value include argument and reply */
108 /* TODO : argument check with these information */
109 /* TODO : divide object and interface with features (ex. play, path, device, focus, asm) */
110 static mm_sound_dbus_method_intf_t methods[AUDIO_METHOD_MAX] = {
111         [AUDIO_METHOD_GET_UNIQUE_ID] = {
112                 .info = {
113                         .name = "GetUniqueId",
114                 },
115                 .handler = handle_method_get_unique_id
116         },
117         [AUDIO_METHOD_REGISTER_FOCUS] = {
118                 .info = {
119                         .name = "RegisterFocus",
120                 },
121                 .handler = handle_method_register_focus
122         },
123         [AUDIO_METHOD_UNREGISTER_FOCUS] = {
124                 .info = {
125                         .name = "UnregisterFocus",
126                 },
127                 .handler = handle_method_unregister_focus
128         },
129         [AUDIO_METHOD_SET_FOCUS_REACQUISITION] = {
130                 .info = {
131                         .name = "SetFocusReacquisition",
132                 },
133                 .handler = handle_method_set_focus_reacquisition
134         },
135         [AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE] = {
136                 .info = {
137                         .name = "GetAcquiredFocusStreamType",
138                 },
139                 .handler = handle_method_get_acquired_focus_stream_type
140         },
141         [AUDIO_METHOD_ACQUIRE_FOCUS] = {
142                 .info = {
143                         .name = "AcquireFocus",
144                 },
145                 .handler = handle_method_acquire_focus
146         },
147         [AUDIO_METHOD_RELEASE_FOCUS] = {
148                 .info = {
149                         .name = "ReleaseFocus",
150                 },
151                 .handler = handle_method_release_focus
152         },
153         [AUDIO_METHOD_WATCH_FOCUS] = {
154                 .info = {
155                         .name = "WatchFocus",
156                 },
157                 .handler = handle_method_watch_focus
158         },
159         [AUDIO_METHOD_UNWATCH_FOCUS] = {
160                 .info = {
161                         .name = "UnwatchFocus",
162                 },
163                 .handler = handle_method_unwatch_focus
164         }
165 };
166
167 static GDBusNodeInfo *introspection_data = NULL;
168 guint focus_server_owner_id ;
169 unsigned emergent_exit_subs_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 _get_sender_pid(GDBusMethodInvocation* invocation)
213 {
214         GVariant* value;
215         guint pid = 0;
216         const gchar* sender;
217         GDBusConnection * connection = NULL;
218         GError* err = NULL;
219
220         connection = g_dbus_method_invocation_get_connection(invocation);
221         sender = g_dbus_method_invocation_get_sender(invocation);
222
223         debug_msg("connection = %p, sender = %s", connection, sender);
224
225         value = g_dbus_connection_call_sync(connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
226                                                                                 "org.freedesktop.DBus", "GetConnectionUnixProcessID",
227                                                                                 g_variant_new("(s)", sender, NULL), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
228         if (value) {
229                 g_variant_get(value, "(u)", &pid);
230                 debug_msg("Sender PID = [%d]", pid);
231                 g_variant_unref(value);
232         } else {
233                 debug_error("err code = %d, err msg = %s", err->code, err->message);
234         }
235         return pid;
236 }
237
238 static void _method_call_return_value(GDBusMethodInvocation *invocation, GVariant *params)
239 {
240         const char *method_name;
241         method_name = g_dbus_method_invocation_get_method_name(invocation);
242         debug_msg("Method Call '%s' success", method_name);
243         g_dbus_method_invocation_return_value(invocation, params);
244 }
245 static void _method_call_return_error(GDBusMethodInvocation *invocation, int ret)
246 {
247         const char *err_name, *method_name;
248         err_name = _convert_error_code(ret);
249         method_name = g_dbus_method_invocation_get_method_name(invocation);
250         debug_error("Method Call '%s' failed, err '%s(%X)'", method_name, err_name, ret);
251         g_dbus_method_invocation_return_dbus_error(invocation, err_name, "failed");
252 }
253
254 static void handle_method_get_unique_id(GDBusMethodInvocation* invocation)
255 {
256         static int unique_id = 0;
257
258         debug_fenter();
259
260         _method_call_return_value(invocation, g_variant_new("(i)", ++unique_id));
261
262         debug_fleave();
263 }
264
265 static void handle_method_register_focus(GDBusMethodInvocation* invocation)
266 {
267         int ret = MM_ERROR_NONE;
268         int handle_id = 0;
269         const char* stream_type = NULL;
270         gboolean is_for_session;
271         GVariant *params = NULL;
272         int pid = 0;
273
274         debug_fenter();
275
276         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
277                 debug_error("Parameter for Method is NULL");
278                 ret = MM_ERROR_SOUND_INTERNAL;
279                 goto send_reply;
280         }
281
282         g_variant_get(params, "(ii&sb)", &pid, &handle_id, &stream_type, &is_for_session);
283         ret = __mm_sound_mgr_focus_ipc_register_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, stream_type, is_for_session);
284
285 send_reply:
286         if (ret == MM_ERROR_NONE) {
287                 _method_call_return_value(invocation, g_variant_new("()"));
288         } else {
289                 _method_call_return_error(invocation, ret);
290         }
291
292         debug_fleave();
293 }
294
295 static void handle_method_unregister_focus(GDBusMethodInvocation* invocation)
296 {
297         int ret = MM_ERROR_NONE;
298         int pid = 0, handle_id = 0;
299         gboolean is_for_session;
300         GVariant *params = NULL;
301
302         debug_fenter();
303
304         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
305                 debug_error("Parameter for Method is NULL");
306                 ret = MM_ERROR_SOUND_INTERNAL;
307                 goto send_reply;
308         }
309
310         g_variant_get(params, "(iib)", &pid, &handle_id, &is_for_session);
311         ret = __mm_sound_mgr_focus_ipc_unregister_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, is_for_session);
312
313 send_reply:
314         if (ret == MM_ERROR_NONE) {
315                 _method_call_return_value(invocation, g_variant_new("()"));
316         } else {
317                 _method_call_return_error(invocation, ret);
318         }
319
320         debug_fleave();
321 }
322
323 static void handle_method_set_focus_reacquisition(GDBusMethodInvocation* invocation)
324 {
325         int ret = MM_ERROR_NONE;
326         int pid = 0, handle_id = 0;
327         gboolean reacquisition;
328         gboolean is_for_session;
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, "(iibb)", &pid, &handle_id, &reacquisition, &is_for_session);
340         ret = __mm_sound_mgr_focus_ipc_set_focus_reacquisition(_get_sender_pid(invocation), handle_id, reacquisition, is_for_session);
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
349         debug_fleave();
350 }
351
352 static void handle_method_get_acquired_focus_stream_type(GDBusMethodInvocation* invocation)
353 {
354         int ret = MM_ERROR_NONE;
355         int focus_type = 0;
356         char *stream_type = NULL;
357         int option = 0;
358         char *ext_info = NULL;
359         GVariant *params = NULL;
360
361         debug_fenter();
362
363         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
364                 debug_error("Parameter for Method is NULL");
365                 ret = MM_ERROR_SOUND_INTERNAL;
366                 goto send_reply;
367         }
368
369         g_variant_get(params, "(i)", &focus_type);
370         ret = __mm_sound_mgr_focus_ipc_get_acquired_focus_stream_type(focus_type, &stream_type, &option, &ext_info);
371
372 send_reply:
373         if (ret == MM_ERROR_NONE) {
374                 _method_call_return_value(invocation, g_variant_new("(sis)", stream_type, option, ext_info));
375         } else {
376                 _method_call_return_error(invocation, ret);
377         }
378
379         debug_fleave();
380 }
381
382 static void handle_method_acquire_focus(GDBusMethodInvocation* invocation)
383 {
384         int ret = MM_ERROR_NONE;
385         int pid = 0, handle_id = 0, focus_type = 0, option = 0;
386         const char* ext_info = NULL;
387         gboolean is_for_session;
388         GVariant *params = NULL;
389
390         debug_fenter();
391
392         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
393                 debug_error("Parameter for Method is NULL");
394                 ret = MM_ERROR_SOUND_INTERNAL;
395                 goto send_reply;
396         }
397
398         g_variant_get(params, "(iiiisb)", &pid, &handle_id, &focus_type, &option, &ext_info, &is_for_session);
399         ret = __mm_sound_mgr_focus_ipc_acquire_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, option, ext_info, is_for_session);
400
401 send_reply:
402         if (ret == MM_ERROR_NONE) {
403                 _method_call_return_value(invocation, g_variant_new("()"));
404         } else {
405                 _method_call_return_error(invocation, ret);
406         }
407
408         debug_fleave();
409 }
410
411 static void handle_method_release_focus(GDBusMethodInvocation* invocation)
412 {
413         int ret = MM_ERROR_NONE;
414         int pid = 0, handle_id = 0, focus_type = 0, option = 0;
415         const char* ext_info = NULL;
416         gboolean is_for_session;
417         GVariant *params = NULL;
418
419         debug_fenter();
420
421         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
422                 debug_error("Parameter for Method is NULL");
423                 ret = MM_ERROR_SOUND_INTERNAL;
424                 goto send_reply;
425         }
426
427         g_variant_get(params, "(iiiisb)", &pid, &handle_id, &focus_type, &option, &ext_info, &is_for_session);
428         ret = __mm_sound_mgr_focus_ipc_release_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, option, ext_info, is_for_session);
429
430 send_reply:
431         if (ret == MM_ERROR_NONE) {
432                 _method_call_return_value(invocation, g_variant_new("()"));
433         } else {
434                 _method_call_return_error(invocation, ret);
435         }
436
437         debug_fleave();
438 }
439
440 static void handle_method_watch_focus(GDBusMethodInvocation* invocation)
441 {
442         int ret = MM_ERROR_NONE;
443         int handle_id = 0, focus_type = 0;
444         gboolean is_for_session;
445         GVariant *params = NULL;
446         int pid = 0;
447
448         debug_fenter();
449
450         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
451                 debug_error("Parameter for Method is NULL");
452                 ret = MM_ERROR_SOUND_INTERNAL;
453                 goto send_reply;
454         }
455
456         g_variant_get(params, "(iiib)", &pid, &handle_id, &focus_type, &is_for_session);
457         ret = __mm_sound_mgr_focus_ipc_watch_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id, focus_type, is_for_session);
458
459 send_reply:
460         if (ret == MM_ERROR_NONE) {
461                 _method_call_return_value(invocation, g_variant_new("()"));
462         } else {
463                 _method_call_return_error(invocation, ret);
464         }
465
466         debug_fleave();
467 }
468
469 static void handle_method_unwatch_focus(GDBusMethodInvocation* invocation)
470 {
471         int ret = MM_ERROR_NONE;
472         int pid = 0;
473         int handle_id = 0;
474         gboolean is_for_session;
475         GVariant *params = NULL;
476
477         debug_fenter();
478
479         if (!(params = g_dbus_method_invocation_get_parameters(invocation))) {
480                 debug_error("Parameter for Method is NULL");
481                 ret = MM_ERROR_SOUND_INTERNAL;
482                 goto send_reply;
483         }
484
485         g_variant_get(params, "(iib)", &pid, &handle_id, &is_for_session);
486         ret = __mm_sound_mgr_focus_ipc_unwatch_focus((is_for_session) ? pid : _get_sender_pid(invocation), handle_id);
487
488 send_reply:
489         if (ret == MM_ERROR_NONE) {
490                 _method_call_return_value(invocation, g_variant_new("()"));
491         } else {
492                 _method_call_return_error(invocation, ret);
493         }
494
495         debug_fleave();
496 }
497
498 /**********************************************************************************/
499 static void handle_method_call(GDBusConnection *connection,
500                                                         const gchar *sender,
501                                                         const gchar *object_path,
502                                                         const gchar *interface_name,
503                                                         const gchar *method_name,
504                                                         GVariant *parameters,
505                                                         GDBusMethodInvocation *invocation,
506                                                         gpointer userdata)
507 {
508         int method_idx = 0;
509
510         if (!parameters) {
511                 debug_error("Parameter Null");
512                 return;
513         }
514         debug_log("Method Call, obj : %s, intf : %s, method : %s", object_path, interface_name, method_name);
515
516         for (method_idx = AUDIO_METHOD_GET_UNIQUE_ID; method_idx < AUDIO_METHOD_MAX; method_idx++) {
517                 if (!g_strcmp0(method_name, methods[method_idx].info.name)) {
518                         methods[method_idx].handler(invocation);
519                 }
520         }
521 }
522
523
524 static GVariant* handle_get_property(GDBusConnection *connection,
525                                                                         const gchar *sender,
526                                                                         const gchar *object_path,
527                                                                         const gchar *interface_name,
528                                                                         const gchar *property_name,
529                                                                         GError **error,
530                                                                         gpointer userdata)
531 {
532         debug_log("Get Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
533         return NULL;
534 }
535
536 static gboolean handle_set_property(GDBusConnection *connection,
537                                                                         const gchar *sender,
538                                                                         const gchar *object_path,
539                                                                         const gchar *interface_name,
540                                                                         const gchar *property_name,
541                                                                         GVariant *value,
542                                                                         GError **error,
543                                                                         gpointer userdata)
544 {
545         debug_log("Set Property, obj : %s, intf : %s, prop : %s", object_path, interface_name, property_name);
546         return TRUE;
547 }
548
549 void emergent_exit_signal_handler(audio_event_t event, GVariant *param, void *userdata)
550 {
551         int ret = MM_ERROR_NONE;
552         int pid = 0;
553
554         if (event != AUDIO_EVENT_EMERGENT_EXIT)
555                 return;
556
557         debug_fenter();
558
559         g_variant_get(param, "(i)", &pid);
560         debug_log("emergent exit : pid %d", pid);
561         ret = __mm_sound_mgr_focus_ipc_emergent_exit(pid);
562         if (ret)
563                 debug_error("__mm_sound_mgr_focus_ipc_emergent_exit failed : 0x%x", ret);
564
565         debug_fleave();
566 }
567
568 static const GDBusInterfaceVTable interface_vtable =
569 {
570         handle_method_call,
571         handle_get_property,
572         handle_set_property
573 };
574
575 static void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
576 {
577         guint reg_id;
578         debug_log("Bus Acquired (%s)", name);
579
580         conn_g = connection;
581         reg_id = g_dbus_connection_register_object(connection,
582                                           OBJECT_FOCUS_SERVER,
583                                           introspection_data->interfaces[0],
584                                           &interface_vtable,
585                                           NULL,
586                                           NULL,
587                                           NULL);
588         if (!reg_id) {
589                 debug_error("Register object(%s) failed", OBJECT_FOCUS_SERVER);
590                 return ;
591         }
592 }
593
594 static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
595 {
596         debug_log("Name Acquired (%s)", name);
597 }
598
599 static void on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
600 {
601         debug_log("Name Lost (%s)", name);
602 }
603
604 static int _mm_sound_mgr_focus_dbus_own_name(GBusType bus_type, const char* wellknown_name, guint* owner_id)
605 {
606         guint oid;
607
608         debug_msg("Own name (%s) for focus-server", wellknown_name);
609
610         oid = g_bus_own_name(bus_type, wellknown_name, G_BUS_NAME_OWNER_FLAGS_NONE,
611                         on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL);
612         if (oid <= 0) {
613                 debug_error("Dbus own name failed");
614                 return MM_ERROR_SOUND_INTERNAL;
615         } else {
616                 *owner_id = oid;
617         }
618
619         debug_msg("OwnerID (%d) for focus-server", *owner_id);
620
621         return MM_ERROR_NONE;
622 }
623
624 static void _mm_sound_mgr_focus_dbus_unown_name(guint oid)
625 {
626         debug_msg("Unown name for focus-server [%d]", oid);
627         if (oid > 0) {
628                 g_bus_unown_name(oid);
629         }
630 }
631
632 #define PA_BUS_NAME                                    "org.pulseaudio.Server"
633 #define PA_STREAM_MANAGER_OBJECT_PATH                  "/org/pulseaudio/StreamManager"
634 #define PA_STREAM_MANAGER_INTERFACE                    "org.pulseaudio.StreamManager"
635 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST  "GetStreamList"
636 int __mm_sound_mgr_focus_dbus_get_stream_list(stream_list_t* stream_list)
637 {
638         int ret = MM_ERROR_NONE;
639         GVariant *result = NULL;
640         GVariant *child = NULL;
641         GDBusConnection *conn = NULL;
642         GError *err = NULL;
643         int i = 0;
644
645         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
646         if (!conn && err) {
647                 LOGE("g_bus_get_sync() error (%s)", err->message);
648                 g_error_free(err);
649                 ret = MM_ERROR_SOUND_INTERNAL;
650                 return ret;
651         }
652         result = g_dbus_connection_call_sync(conn,
653                                                         PA_BUS_NAME,
654                                                         PA_STREAM_MANAGER_OBJECT_PATH,
655                                                         PA_STREAM_MANAGER_INTERFACE,
656                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST,
657                                                         NULL,
658                                                         G_VARIANT_TYPE("(vv)"),
659                                                         G_DBUS_CALL_FLAGS_NONE,
660                                                         2000,
661                                                         NULL,
662                                                         &err);
663         if (!result && err) {
664                 debug_error("g_dbus_connection_call_sync() error (%s)", err->message);
665                 ret = MM_ERROR_SOUND_INTERNAL;
666         } else {
667                 GVariantIter iter;
668                 GVariant *item = NULL;
669                 child = g_variant_get_child_value(result, 0);
670                 item = g_variant_get_variant(child);
671                 gchar *name;
672                 i = 0;
673                 g_variant_iter_init(&iter, item);
674                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "&s", &name)) {
675                         debug_log("name : %s", name);
676                         stream_list->stream_types[i++] = strdup(name);
677                 }
678                 g_variant_unref(item);
679                 g_variant_unref(child);
680
681                 child = g_variant_get_child_value(result, 1);
682                 item = g_variant_get_variant(child);
683                 gint32 priority;
684                 i = 0;
685                 g_variant_iter_init(&iter, item);
686                 while ((i < AVAIL_STREAMS_MAX) && g_variant_iter_loop(&iter, "i", &priority)) {
687                         debug_log("priority : %d", priority);
688                         stream_list->priorities[i++] = priority;
689                 }
690                 g_variant_unref(item);
691                 g_variant_unref(child);
692
693                 g_variant_unref(result);
694         }
695         g_object_unref(conn);
696
697         return ret;
698 }
699
700 int MMSoundMgrFocusDbusInit(void)
701 {
702         debug_enter();
703
704         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
705         if (!introspection_data)
706                 return MM_ERROR_SOUND_INTERNAL;
707
708         if (_mm_sound_mgr_focus_dbus_own_name(G_BUS_TYPE_SYSTEM, BUS_NAME_FOCUS_SERVER, &focus_server_owner_id) != MM_ERROR_NONE) {
709                 debug_error("dbus own name for focus-server error\n");
710                 return MM_ERROR_SOUND_INTERNAL;
711         }
712         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) {
713                 debug_error("dbus signal subscribe for emergent exit error\n");
714                 return MM_ERROR_SOUND_INTERNAL;
715         }
716
717         debug_leave();
718
719         return MM_ERROR_NONE;
720 }
721
722 void MMSoundMgrFocusDbusFini(void)
723 {
724         debug_enter();
725
726         if (emergent_exit_subs_id != 0)
727                 mm_sound_dbus_signal_unsubscribe(emergent_exit_subs_id);
728         _mm_sound_mgr_focus_dbus_unown_name(focus_server_owner_id);
729         g_dbus_node_info_unref(introspection_data);
730
731         debug_leave();
732 }
733
734
735