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