Apply coding rule
[platform/core/appfw/libeventsystem.git] / src / eventsystem.c
1 /**
2  * event system low-level API
3  */
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <dlog.h>
8 #include <bundle.h>
9 #include <bundle_internal.h>
10 #include <glib.h>
11 #include <gio/gio.h>
12 #include <eventsystem.h>
13 #include <fcntl.h>
14
15 #undef LOG_TAG
16 #define LOG_TAG "eventsystem"
17
18 #define SYS_EVENT_NAME_PREFIX "tizen.system.event"
19 #define EVENT_SYSTEM_PREFIX "eventsystem.id_"
20 #define EVENT_SYSTEM_PREFIX_LEN 15
21 #define EVENT_SYSTEM_MEMBER "eventsystem"
22 #define VALID_COUNT_OF_EVENTNAME_TOKEN 3
23 #define VALID_LAST_COUNT_FOR_EVENTNAME (VALID_COUNT_OF_EVENTNAME_TOKEN + 1)
24 #define MAX_COUNT_FOR_EVENTNAME_CHECK (VALID_LAST_COUNT_FOR_EVENTNAME + 1)
25
26 #define _E(fmt, arg...) LOGE(fmt, ##arg)
27 #define _D(fmt, arg...) LOGD(fmt, ##arg)
28 #define _W(fmt, arg...) LOGW(fmt, ##arg)
29 #define _I(fmt, arg...) LOGI(fmt, ##arg)
30
31 #define retvm_if(expr, val, fmt, arg...) do { \
32         if (expr) { \
33                 _E(fmt, ##arg); \
34                 _E("(%s) -> %s() return", #expr, __func__); \
35                 return val; \
36         } \
37 } while (0)
38
39 #define retv_if(expr, val) do { \
40         if (expr) { \
41                 _E("(%s) -> %s() return", #expr, __func__); \
42                 return val; \
43         } \
44 } while (0)
45
46 #define tryvm_if(expr, val, fmt, arg...) do { \
47          if (expr) { \
48                 _E("(%s) "fmt, #expr, ##arg); \
49                 val; \
50                 goto catch; \
51         } \
52 } while (0)
53
54 pthread_mutex_t send_sync_lock = PTHREAD_MUTEX_INITIALIZER;
55
56 static GList *system_event_list;
57 static int _initialized;
58 static GHashTable *check_tbl;
59 static GHashTable *filter_tbl;
60
61 typedef struct eventmap {
62         char *event_name;
63         char *interface_name;
64         char *member_name;
65         guint reg_id;
66         GBusType bus_type;
67         int event_type;
68         union {
69                 eventsystem_cb es_cb;
70                 eventsystem_handler ep_cb;
71         };
72 } eventmap_s;
73
74 typedef struct eventinfo {
75         char *event_name;
76         char *destination_name;
77         char *interface_name;
78         char *object_path;
79         char *member_name;
80         bool is_user_event;
81         bundle *event_data;
82 } eventinfo_s;
83
84 typedef struct sysevent_info {
85         guint owner_id;
86         guint owner_id_session;
87         char *own_name_system_bus;
88         char *own_name_session_bus;
89 } sysevent_info_s;
90 static sysevent_info_s s_info;
91
92 static int __eventsystem_check_user_send_validation(const char *event_name);
93 static int __eventsystem_requet_destination_list(const char *event_name, GList **dest_list);
94 static int __eventsystem_check_sender_validation(int sender_pid,
95                 const char *event_name, char **sender);
96
97 static int __event_compare_name_cb(gconstpointer a, gconstpointer b)
98 {
99         eventmap_s *key1 = (eventmap_s *)a;
100         eventmap_s *key2 = (eventmap_s *)b;
101         return strcmp(key1->interface_name, key2->interface_name) |
102                         strcmp(key1->member_name, key2->member_name);
103 }
104
105 static int __event_compare_reg_id_cb(gconstpointer a, gconstpointer b)
106 {
107         eventmap_s *key1 = (eventmap_s *)a;
108         eventmap_s *key2 = (eventmap_s *)b;
109         return !(key1->reg_id == key2->reg_id);
110 }
111
112 static void __initialize(void)
113 {
114 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
115         g_type_init();
116 #endif
117
118         _initialized = 1;
119 }
120
121 static int __eventsystem_get_sender_pid(GDBusConnection *conn, const char *sender_name)
122 {
123         GDBusMessage *msg = NULL;
124         GDBusMessage *reply = NULL;
125         GError *err = NULL;
126         GVariant *body;
127         int pid = 0;
128
129         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
130                 "org.freedesktop.DBus", "GetConnectionUnixProcessID");
131         if (!msg) {
132                 _E("Can't allocate new method call");
133                 goto out;
134         }
135
136         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
137         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
138                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
139
140         if (!reply) {
141                 if (err != NULL) {
142                         _E("Failed to get pid [%s]", err->message);
143                         g_error_free(err);
144                 }
145                 goto out;
146         }
147
148         body = g_dbus_message_get_body(reply);
149         g_variant_get(body, "(u)", &pid);
150
151 out:
152         if (msg)
153                 g_object_unref(msg);
154         if (reply)
155                 g_object_unref(reply);
156
157         return pid;
158 }
159
160 static char *__get_object_path(char *interface_name)
161 {
162         int i;
163         char *object_path = (char *)calloc(strlen(interface_name), sizeof(char) + 2);
164
165         if (object_path == NULL) {
166                 _E("failed to allocate memory");
167                 return NULL;
168         }
169
170         object_path[0] = '/';
171
172         for (i = 0; interface_name[i]; i++) {
173                 if (interface_name[i] == '.')
174                         object_path[i + 1] = '/';
175                 else
176                         object_path[i + 1] = interface_name[i];
177         }
178
179         return object_path;
180 }
181
182 static char *__get_encoded_interface_name(char *interface_name)
183 {
184         char *evtid = NULL;
185         int evtid_len = 0;
186         gchar *encoded_value;
187
188         encoded_value = g_compute_checksum_for_string(G_CHECKSUM_MD5,
189                 interface_name, strlen(interface_name));
190
191         evtid_len = EVENT_SYSTEM_PREFIX_LEN + strlen(encoded_value) + 1;
192
193         evtid = (char *)calloc(evtid_len, sizeof(char));
194         if (evtid == NULL) {
195                 _D("memory alloc failed");
196                 g_free(encoded_value);
197                 return NULL;
198         }
199
200         snprintf(evtid, evtid_len, "%s%s", EVENT_SYSTEM_PREFIX, (char *)encoded_value);
201
202         g_free(encoded_value);
203
204         return evtid;
205 }
206
207 static char *__get_member_name_from_eventname(char *event_name)
208 {
209         char *ptr = NULL;
210         char *ptr_last = NULL;
211         char *temp_name = NULL;
212         char *member_name = NULL;
213         char *save_ptr = NULL;
214         int count = 0;
215
216         temp_name = strdup(event_name);
217         if (temp_name == NULL) {
218                 _E("out of memory");
219                 return NULL;
220         }
221
222         ptr = strtok_r(temp_name, ".", &save_ptr);
223         if (ptr == NULL) {
224                 _E("invalid event_name(%s), count(%d)", event_name, count);
225                 FREE_AND_NULL(temp_name);
226                 return NULL;
227         }
228         count++;
229
230         while (count < MAX_COUNT_FOR_EVENTNAME_CHECK) {
231                 ptr = strtok_r(NULL, ".", &save_ptr);
232                 if (ptr == NULL)
233                         break;
234                 /* _D("(%d)ptr(%s)(%d)", count, ptr, strlen(ptr)); */
235                 ptr_last = ptr;
236                 count++;
237         }
238         FREE_AND_NULL(temp_name);
239
240         if (count != VALID_LAST_COUNT_FOR_EVENTNAME) {
241                 _E("invalid event_name(%s), count(%d)", event_name, count);
242                 return NULL;
243         }
244
245         if (ptr_last) {
246                 /* _D("new member_name(%s)(%d)", ptr_last, strlen(ptr_last)); */
247                 member_name = strdup(ptr_last);
248                 if (!member_name) {
249                         _E("out_of_memory");
250                         return NULL;
251                 }
252         } else {
253                 _E("ptr_last is NULL");
254                 return NULL;
255         }
256
257         _D("member_name(%s)", member_name);
258
259         return member_name;
260 }
261
262 static int __check_validation_usrevent_sender(int sender_pid,
263                 const char *interface_name, const char *event_name)
264 {
265         char *sender_id = NULL;
266         char *key = NULL;
267         char *val = NULL;
268
269         if (__eventsystem_check_sender_validation(sender_pid,
270                 event_name, &sender_id) < 0) {
271                 _E("invalid user-event sender");
272                 return ES_R_EINVAL;
273         }
274
275         if (sender_id == NULL) {
276                 _E("sender_id is null");
277                 return ES_R_EINVAL;
278         }
279
280         key = strdup(interface_name);
281         if (key == NULL) {
282                 _E("out of memory");
283                 return ES_R_ENOMEM;
284         }
285
286         val = strdup(sender_id);
287         if (val == NULL) {
288                 _E("out of memory");
289                 free(key);
290                 return ES_R_ENOMEM;
291         }
292
293         g_hash_table_insert(filter_tbl, key, val);
294
295         return ES_R_OK;
296 }
297
298 static int __check_validation_user_defined_name(const char *event_name)
299 {
300         char *event_id = NULL;
301         char *key = NULL;
302         int ret = 1;
303
304         if (check_tbl == NULL)
305                 check_tbl = g_hash_table_new(g_str_hash, g_str_equal);
306
307         event_id = (char *)g_hash_table_lookup(check_tbl, event_name);
308         if (event_id == NULL) {
309                 if (__eventsystem_check_user_send_validation(event_name) < 0) {
310                         _E("invalid user-event name");
311                         ret = 0;
312                 } else {
313                         key = strdup(event_name);
314                         if (key == NULL) {
315                                 _E("out_of_memory");
316                                 ret = 0;
317                         } else {
318                                 g_hash_table_insert(check_tbl, key, key);
319                         }
320                 }
321         }
322
323         return ret;
324 }
325
326 static int __check_interface_validation_user(char *interface_name)
327 {
328         int len = strlen(EVENT_SYSTEM_PREFIX);
329
330         if (strncmp(interface_name, EVENT_SYSTEM_PREFIX, len) != 0)
331                 return 0;
332
333         return 1;
334 }
335
336 static int __check_eventname_validation_user(char *event_name)
337 {
338         int len = strlen(USER_EVENT_NAME_PREFIX);
339
340         if (strncmp(event_name, USER_EVENT_NAME_PREFIX, len) != 0)
341                 return 0;
342
343         return 1;
344 }
345
346 static int __check_eventname_validation_system(char *event_name)
347 {
348         int len = strlen(SYS_EVENT_NAME_PREFIX);
349
350         if (strncmp(event_name, SYS_EVENT_NAME_PREFIX, len) != 0)
351                 return 0;
352
353         return 1;
354 }
355
356 static int __get_gdbus_shared_connection(GDBusConnection **connection, GBusType bus_type,
357                 eventsystem_event_type event_type)
358 {
359         GError *error = NULL;
360         guint owner_id = 0;
361         gchar *guid = NULL;
362         char own_name[128] = {0, };
363         GDBusConnection *conn_system = NULL;
364
365         if (!_initialized)
366                 __initialize();
367
368         *connection = g_bus_get_sync(bus_type, NULL, &error);
369         if (*connection == NULL) {
370                 if (error != NULL) {
371                         _E("Failed to get dbus [%s], bus_type [%d]",
372                                 error->message, bus_type);
373                         g_error_free(error);
374                 }
375                 return ES_R_ERROR;
376         }
377
378         if (((bus_type == G_BUS_TYPE_SYSTEM && !s_info.owner_id) ||
379                 (bus_type == G_BUS_TYPE_SESSION && !s_info.owner_id_session))) {
380                 guid = g_dbus_generate_guid();
381                 if (guid == NULL) {
382                         _E("failed to get guid");
383                         return ES_R_ERROR;
384                 }
385                 snprintf(own_name, 128, "%s.%s.id%s_%d_%d", "event.busname",
386                         (bus_type == G_BUS_TYPE_SESSION ? "session" : "system"),
387                         guid, getuid(), getpid());
388                 g_free(guid);
389
390                 _D("bus_name is [%s]", own_name);
391                 owner_id = g_bus_own_name_on_connection(*connection, own_name,
392                         G_BUS_NAME_OWNER_FLAGS_NONE,
393                         NULL, NULL, NULL, NULL);
394                 if (!owner_id) {
395                         _E("g_bus_own_name_on_connection, error");
396                         return ES_R_ERROR;
397                 }
398
399                 if (bus_type == G_BUS_TYPE_SESSION && event_type == ES_TYPE_USER) {
400                         /* set same name on system-bus */
401                         error = NULL;
402                         conn_system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
403                         if (conn_system == NULL) {
404                                 _E("failed to get system connection");
405                                 if (error != NULL) {
406                                         _E("error(%s)", error->message);
407                                         g_error_free(error);
408                                 }
409                                 return ES_R_ERROR;
410                         } else {
411                                 owner_id = g_bus_own_name_on_connection(conn_system,
412                                         own_name, G_BUS_NAME_OWNER_FLAGS_NONE,
413                                         NULL, NULL, NULL, NULL);
414                                 if (!owner_id) {
415                                         _E("g_bus_own_name_on_connection(for system), error");
416                                         g_object_unref(conn_system);
417                                         return ES_R_ERROR;
418                                 }
419
420                                 g_object_unref(conn_system);
421                         }
422                 }
423
424                 if (bus_type == G_BUS_TYPE_SESSION) {
425                         s_info.owner_id_session = owner_id;
426                         s_info.own_name_session_bus = strdup(own_name);
427                         if (s_info.own_name_session_bus == NULL) {
428                                 _E("out of memory");
429                                 return ES_R_ERROR;
430                         }
431                 } else {
432                         s_info.owner_id = owner_id;
433                         s_info.own_name_system_bus = strdup(own_name);
434                         if (s_info.own_name_system_bus == NULL) {
435                                 _E("out of memory");
436                                 return ES_R_ERROR;
437                         }
438                 }
439         }
440
441         return ES_R_OK;
442 }
443
444 static void __eventsystem_event_handler(GDBusConnection *connection,
445                 const gchar *sender_name, const gchar *object_path,
446                 const gchar *interface_name, const gchar *signal_name,
447                 GVariant *parameters, gpointer user_data)
448 {
449         int len;
450         eventmap_s em;
451         GList *cb_list = NULL;
452         bundle *buf = NULL;
453         bundle_raw *raw = NULL;
454
455         em.interface_name = (char *)interface_name;
456         em.member_name = (char *)signal_name;
457
458         _D("sender_name(%s), interface_name(%s), signal_name(%s)",
459                 sender_name, interface_name, signal_name);
460
461         cb_list = g_list_find_custom(system_event_list, &em,
462                 (GCompareFunc)__event_compare_name_cb);
463         if (cb_list == NULL)
464                 return;
465
466         g_variant_get(parameters, "(us)", &len, &raw);
467
468         buf = bundle_decode((bundle_raw *)raw, len);
469
470         em.event_name = ((eventmap_s *)cb_list->data)->event_name;
471         em.ep_cb = ((eventmap_s *)cb_list->data)->ep_cb;
472         if (em.ep_cb)
473                 em.ep_cb(em.event_name, buf, user_data);
474
475         bundle_free_encoded_rawdata(&raw);
476         bundle_free(buf);
477 }
478
479 static void __eventsystem_application_event_handler(int sender_pid,
480                 const gchar *interface_name, const gchar *signal_name,
481                 GVariant *parameters, gpointer user_data)
482 {
483         GList *cb_list = NULL;
484         eventmap_s em;
485         bundle_raw *raw = NULL;
486         int len;
487
488         em.interface_name = (char *)interface_name;
489         em.member_name = (char *)signal_name;
490
491         cb_list = g_list_find_custom(system_event_list, &em,
492                 (GCompareFunc)__event_compare_name_cb);
493
494         if (cb_list == NULL) {
495                 _E("not interested event");
496                 return;
497         }
498
499         em.event_name = ((eventmap_s *)cb_list->data)->event_name;
500
501         if (sender_pid > 0 && __check_interface_validation_user((char *)interface_name)) {
502                 if (__check_validation_usrevent_sender(sender_pid,
503                         (const char *)interface_name, em.event_name) < 0) {
504                         _E("invalid sender");
505                         return;
506                 }
507         }
508
509         g_variant_get(parameters, "(us)", &len, &raw);
510         em.es_cb = ((eventmap_s *)cb_list->data)->es_cb;
511         if (em.es_cb)
512                 em.es_cb(em.event_name, raw, len, user_data);
513
514         bundle_free_encoded_rawdata(&raw);
515 }
516
517 /**
518  * application-use filter for user-event
519  */
520 static void __eventsystem_filter_userevent_for_application(GDBusConnection *connection,
521                 const gchar *sender_name, const gchar *object_path,
522                 const gchar *interface_name, const gchar *signal_name,
523                 GVariant *parameters, gpointer user_data)
524 {
525         char *sender_id = NULL;
526         int sender_pid = -1;
527
528         _D("sender_name(%s), interface_name(%s)", sender_name, interface_name);
529
530         if (filter_tbl == NULL)
531                 filter_tbl = g_hash_table_new(g_str_hash, g_str_equal);
532
533         sender_id = (char *)g_hash_table_lookup(filter_tbl, interface_name);
534         if (sender_id == NULL) {
535                 sender_pid = __eventsystem_get_sender_pid(connection, sender_name);
536                 if (sender_pid <= 0) {
537                         _E("failed to get pid of sender(%s)", sender_name);
538                         return;
539                 }
540                 _D("sender_pid(%d)", sender_pid);
541         }
542
543         __eventsystem_application_event_handler(sender_pid, interface_name,
544                 signal_name, parameters, user_data);
545 }
546
547 /**
548  * application-use filter for system-event
549  */
550 static void __eventsystem_filter_sysevent_for_application(GDBusConnection *connection,
551                 const gchar *sender_name, const gchar *object_path,
552                 const gchar *interface_name, const gchar *signal_name,
553                 GVariant *parameters, gpointer user_data)
554 {
555         _D("sender_name(%s), interface_name(%s)", sender_name, interface_name);
556
557         __eventsystem_application_event_handler(-1, interface_name,
558                 signal_name, parameters, user_data);
559 }
560
561 /**
562  * internal-use filter for user-event
563  */
564 static void __eventsystem_filter_userevent_for_internal(GDBusConnection *connection,
565                 const gchar *sender_name, const gchar *object_path,
566                 const gchar *interface_name, const gchar *signal_name,
567                 GVariant *parameters, gpointer user_data)
568 {
569         _D("sender_name(%s), interface_name(%s), signal_name(%s)",
570                 sender_name, interface_name, signal_name);
571
572         __eventsystem_event_handler(connection, sender_name,
573                 object_path, interface_name, signal_name, parameters, user_data);
574 }
575
576 /**
577  * internal-use filter for system-event
578  */
579 static void __eventsystem_filter_sysevent_for_internal(GDBusConnection *connection,
580                 const gchar *sender_name, const gchar *object_path,
581                 const gchar *interface_name, const gchar *signal_name,
582                 GVariant *parameters, gpointer user_data)
583 {
584         _D("sender_name(%s), interface_name(%s), signal_name(%s)",
585                 sender_name, interface_name, signal_name);
586
587         __eventsystem_event_handler(connection, sender_name,
588                 object_path, interface_name, signal_name, parameters, user_data);
589 }
590
591 static int __eventsystem_register_event_internal(const char *event_name,
592                 eventmap_s **em_s, void *user_data)
593 {
594         eventmap_s *em = NULL;
595         char *interface_name = NULL;
596         char *object_path = NULL;
597         char *member_name = NULL;
598         char *sender_name = NULL;
599         GDBusSignalCallback filter;
600         GBusType bus_type;
601         guint subscription_id = 0;
602         int ret = 0;
603         int evt_type = ES_TYPE_UNKNOWN;
604         GDBusConnection *conn = NULL;
605
606         if (__check_eventname_validation_system((char *)event_name)) {
607                 evt_type = ES_TYPE_SYSTEM;
608         } else if (__check_eventname_validation_user((char *)event_name)) {
609                 evt_type = ES_TYPE_USER;
610         } else {
611                 evt_type = ES_TYPE_UNKNOWN;
612                 _E("unknown type event(%s)", event_name);
613                 return ES_R_EINVAL;
614         }
615
616         if (evt_type == ES_TYPE_SYSTEM) {
617                 interface_name = strdup(SYS_EVENT_NAME_PREFIX);
618                 if (interface_name == NULL) {
619                         _E("out of memory");
620                         ret = ES_R_ENOMEM;
621                         goto out_1;
622                 }
623
624                 member_name = __get_member_name_from_eventname((char *)event_name);
625                 if (member_name == NULL) {
626                         _E("invalid member_name");
627                         ret = ES_R_ERROR;
628                         goto out_2;
629                 }
630
631                 if (!g_dbus_is_member_name(member_name)) {
632                         _E("invalid member name");
633                         ret = ES_R_EINVAL;
634                         goto out_3;
635                 }
636                 filter = __eventsystem_filter_sysevent_for_internal;
637         } else {
638                 interface_name = __get_encoded_interface_name((char *)event_name);
639                 if (!interface_name) {
640                         _E("interface_name is NULL");
641                         ret = ES_R_ERROR;
642                         goto out_1;
643                 }
644                 if (!g_dbus_is_interface_name(interface_name)) {
645                         _E("invalid interface_name(%s)", interface_name);
646                         ret = ES_R_EINVAL;
647                         goto out_2;
648                 }
649                 member_name = strdup(EVENT_SYSTEM_MEMBER);
650                 if (!member_name) {
651                         _E("out_of_memory");
652                         ret = ES_R_ERROR;
653                         goto out_2;
654                 }
655                 filter = __eventsystem_filter_userevent_for_internal;
656         }
657
658         object_path = __get_object_path(interface_name);
659         if (!object_path) {
660                 _E("object_path is NULL");
661                 ret = ES_R_ERROR;
662                 goto out_3;
663         }
664         sender_name = NULL;
665
666         bus_type = G_BUS_TYPE_SYSTEM;
667
668         if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
669                 _E("getting gdbus-connetion error");
670                 goto out_4;
671         }
672
673         subscription_id = g_dbus_connection_signal_subscribe(conn,
674                 sender_name, /* sender */
675                 interface_name,
676                 member_name, /* member */
677                 object_path, /* object_path */
678                 NULL, /* arg0 */
679                 G_DBUS_SIGNAL_FLAGS_NONE,
680                 filter,
681                 user_data,
682                 NULL); /* user_data_free_func */
683
684         _D("event_name(%s), interface_name(%s)", event_name, interface_name);
685         _D("member_name(%s), subscription_id(%d), bus_type(%d)",
686                 member_name, subscription_id, bus_type);
687
688         if (subscription_id != 0) {
689                 em = calloc(1, sizeof(eventmap_s));
690                 if (!em) {
691                         _E("memory alloc failed");
692                         ret = ES_R_ENOMEM;
693                 } else {
694                         em->interface_name = strdup(interface_name);
695                         em->member_name = strdup(member_name);
696                         em->event_name = strdup(event_name);
697                         em->bus_type = bus_type;
698                         em->reg_id = subscription_id;
699                         em->event_type = evt_type;
700
701                         if (!em->interface_name || !em->member_name || !em->event_name) {
702                                 _E("out_of_memory");
703                                 FREE_AND_NULL(em->interface_name);
704                                 FREE_AND_NULL(em->member_name);
705                                 FREE_AND_NULL(em->event_name);
706                                 FREE_AND_NULL(em);
707                                 ret = ES_R_ENOMEM;
708                                 goto out_4;
709                         }
710
711                         *em_s = em;
712                         ret = ES_R_OK;
713                 }
714         } else {
715                 _D("dbus subscribe: error(%d), event(%s)", subscription_id, event_name);
716                 ret = ES_R_ERROR;
717         }
718
719 out_4:
720         FREE_AND_NULL(object_path);
721 out_3:
722         FREE_AND_NULL(member_name);
723 out_2:
724         FREE_AND_NULL(interface_name);
725 out_1:
726         if (conn)
727                 g_object_unref(conn);
728
729         return ret;
730 }
731
732 /**
733  * function : register the event
734  */
735 int eventsystem_register_event(const char *event_name, unsigned int *reg_id,
736                 eventsystem_handler callback, void *user_data)
737 {
738         eventmap_s *em = NULL;
739         int ret = ES_R_ERROR;
740
741         retvm_if(!g_dbus_is_interface_name(event_name), ES_R_EINVAL,
742                 "Invalid argument : event_name(%s)", event_name);
743         retvm_if(!reg_id, ES_R_EINVAL, "Invalid argument : reg_id");
744         retvm_if(!callback, ES_R_EINVAL, "Invalid argument : callback");
745
746         if (!_initialized)
747                 __initialize();
748
749         ret = __eventsystem_register_event_internal(event_name, &em, user_data);
750         if (ret == ES_R_OK && em) {
751                 em->ep_cb = callback;
752                 system_event_list = g_list_append(system_event_list, em);
753                 *reg_id = em->reg_id;
754                 ret = ES_R_OK;
755         } else {
756                 _E("error, ret(%d), em(%s)", ret, em);
757         }
758
759         return ret;
760 }
761
762 /**
763  * function : unregister the event
764  */
765 int eventsystem_unregister_event(unsigned int reg_id)
766 {
767         eventmap_s em;
768         eventmap_s *em_data = NULL;
769         GBusType bus_type;
770         GList *cb_list = NULL;
771         GDBusConnection *conn = NULL;
772         eventsystem_event_type evt_type;
773
774         retvm_if(reg_id == 0, ES_R_EINVAL, "Invalid argument : reg_id");
775
776         if (!_initialized)
777                 __initialize();
778
779         em.reg_id = reg_id;
780         cb_list = g_list_find_custom(system_event_list, &em,
781                 (GCompareFunc)__event_compare_reg_id_cb);
782         if (cb_list) {
783                 em_data = (eventmap_s *)cb_list->data;
784
785                 bus_type = em_data->bus_type;
786                 evt_type = em_data->event_type;
787
788                 _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type);
789
790                 if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
791                         _E("getting gdbus-connetion error");
792                         return ES_R_ERROR;
793                 }
794                 g_dbus_connection_signal_unsubscribe(conn, reg_id);
795
796                 system_event_list = g_list_remove(system_event_list, cb_list->data);
797
798                 FREE_AND_NULL(em_data->interface_name);
799                 FREE_AND_NULL(em_data->member_name);
800                 FREE_AND_NULL(em_data->event_name);
801                 FREE_AND_NULL(em_data);
802                 g_object_unref(conn);
803         }
804
805         return ES_R_OK;
806 }
807
808 static int __eventsystem_send_event(GDBusConnection *conn, eventinfo_s *evti, bundle *data)
809 {
810         GError *error = NULL;
811         GVariant *param = NULL;
812         gboolean ret;
813
814         bundle_raw *raw = NULL;
815         bundle *buf = data;
816         int len;
817
818         bundle_encode(buf, &raw, &len);
819
820         param = g_variant_new("(us)", len, raw);
821         ret = g_dbus_connection_emit_signal(conn,
822                 evti->destination_name,
823                 evti->object_path,
824                 evti->interface_name,
825                 evti->member_name,
826                 param,
827                 &error);
828
829         _D("interface_name(%s)", evti->interface_name);
830         _D("object_path(%s)", evti->object_path);
831         _D("member_name(%s)", evti->member_name);
832
833         bundle_free_encoded_rawdata(&raw);
834
835         if (ret == FALSE) {
836                 _E("Unable to connect to dbus: %s", error->message);
837                 g_error_free(error);
838                 return ES_R_ERROR;
839         }
840
841         return ES_R_OK;
842 }
843
844 static void __eventsystem_free_trusted_list(gpointer data)
845 {
846         char *name = (char *)data;
847
848         FREE_AND_NULL(name);
849 }
850
851 static int __eventsystem_send_trusted_event(GDBusConnection *conn, eventinfo_s *evti,
852                 bundle *data, GList *dest_list)
853 {
854         GList *tmp_list = NULL;
855         int ret = 0;
856         char *dest_name;
857
858         if (dest_list) {
859                 tmp_list = g_list_first(dest_list);
860
861                 while (tmp_list != NULL) {
862                         dest_name = (char *)tmp_list->data;
863                         if (dest_name && dest_name[0] != '\0') {
864                                 _D("dest_name(%s)", dest_name);
865                                 evti->destination_name = dest_name;
866                                 ret = __eventsystem_send_event(conn, evti, data);
867                                 if (ret != ES_R_OK) {
868                                         _E("send error");
869                                         ret = ES_R_ERROR;
870                                         break;
871                                 }
872                         }
873                         tmp_list = g_list_next(tmp_list);
874                 }
875                 g_list_free_full(dest_list, __eventsystem_free_trusted_list);
876         } else {
877                 _E("dest_list is null");
878         }
879
880         return ES_R_OK;
881 }
882
883 /**
884  * function : send the user-event
885  */
886 int eventsystem_send_user_event(const char *event_name, bundle *data, bool is_trusted)
887 {
888         int ret = 0;
889         eventinfo_s *evti = NULL;
890
891         /* check validation */
892         retvm_if(!event_name, ES_R_EINVAL, "Invalid argument : event_name is NULL");
893         retvm_if(!data, ES_R_EINVAL, "Invalid argument : data is NULL");
894         retvm_if(!__check_eventname_validation_user((char *)event_name), ES_R_EINVAL,
895                 "Invalid argument : event_name(%s)", event_name);
896
897         if (!__check_validation_user_defined_name(event_name)) {
898                 _E("Invalid event name(%s)", event_name);
899                 return ES_R_EINVAL;
900         }
901
902         evti = calloc(1, sizeof(eventinfo_s));
903         if (!evti) {
904                 _E("memory alloc failed");
905                 return ES_R_ENOMEM;
906         }
907         evti->event_name = strdup(event_name);
908         if (!evti->event_name) {
909                 _E("memory alloc failed");
910                 ret = ES_R_ENOMEM;
911                 goto out_1;
912         }
913
914         evti->interface_name = __get_encoded_interface_name(evti->event_name);
915         if (!evti->interface_name) {
916                 _E("interface_name is NULL");
917                 ret = ES_R_ERROR;
918                 goto out_2;
919         }
920         evti->member_name = strdup(EVENT_SYSTEM_MEMBER);
921         if (!evti->member_name) {
922                 _E("memory alloc failed");
923                 ret = ES_R_ENOMEM;
924                 goto out_3;
925         }
926
927         evti->object_path = __get_object_path(evti->interface_name);
928         if (!evti->object_path) {
929                 _E("object_path is NULL");
930                 ret = ES_R_ERROR;
931                 goto out_4;
932         }
933
934         evti->destination_name = NULL;
935         evti->is_user_event = true;
936
937         GDBusConnection *conn = NULL;
938         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SESSION, ES_TYPE_USER) == ES_R_OK) {
939                 if (is_trusted) {
940                         GList *dest_list = NULL;
941                         ret = __eventsystem_requet_destination_list(evti->event_name, &dest_list);
942                         if (ret < 0) {
943                                 _E("failed to get dest list");
944                                 ret = ES_R_ERROR;
945                         } else {
946                                 ret = __eventsystem_send_trusted_event(conn, evti,
947                                         data, dest_list);
948                         }
949                 } else {
950                         ret = __eventsystem_send_event(conn, evti, data);
951                 }
952         } else {
953                 _E("getting gdbus-connetion error");
954                 ret = ES_R_ERROR;
955         }
956
957         if (conn)
958                 g_object_unref(conn);
959
960         FREE_AND_NULL(evti->object_path);
961 out_4:
962         FREE_AND_NULL(evti->member_name);
963 out_3:
964         FREE_AND_NULL(evti->interface_name);
965 out_2:
966         FREE_AND_NULL(evti->event_name);
967 out_1:
968         FREE_AND_NULL(evti);
969
970         return ret;
971 }
972
973 /**
974  * function : send the system-event
975  */
976 int eventsystem_send_system_event(const char *event_name, bundle *data)
977 {
978         int ret = 0;
979         eventinfo_s *evti = NULL;
980         GDBusConnection *conn = NULL;
981
982         pthread_mutex_lock(&send_sync_lock);
983
984         /* check validation */
985         tryvm_if(!event_name, ret = ES_R_EINVAL, "Invalid argument : event_name is NULL");
986         tryvm_if(!data, ret = ES_R_EINVAL, "Invalid argument : data is NULL");
987         tryvm_if(!__check_eventname_validation_system((char *)event_name), ret = ES_R_EINVAL,
988                 "Invalid argument : event_name(%s)", event_name);
989         tryvm_if(!g_dbus_is_interface_name(event_name), ret = ES_R_EINVAL,
990                 "Invalid argument : event_name(%s)", event_name);
991
992         _D("event_name(%s)", event_name);
993
994         evti = calloc(1, sizeof(eventinfo_s));
995         if (!evti) {
996                 _E("memory alloc failed");
997                 pthread_mutex_unlock(&send_sync_lock);
998                 return ES_R_ENOMEM;
999         }
1000         evti->event_name = strdup(event_name);
1001         if (!evti->event_name) {
1002                 _E("out_of_memory");
1003                 ret = ES_R_ENOMEM;
1004                 goto out_1;
1005         }
1006         evti->interface_name = strdup(SYS_EVENT_NAME_PREFIX);
1007         if (!evti->interface_name) {
1008                 _E("out of memory");
1009                 ret = ES_R_ENOMEM;
1010                 goto out_2;
1011         }
1012         evti->member_name = __get_member_name_from_eventname(evti->event_name);
1013         if (!evti->member_name) {
1014                 _E("member_name is NULL");
1015                 ret = ES_R_ERROR;
1016                 goto out_3;
1017         }
1018         if (!g_dbus_is_member_name(evti->member_name)) {
1019                 _E("Invalid member_name(%s)", evti->member_name);
1020                 ret = ES_R_EINVAL;
1021                 goto out_4;
1022         }
1023         evti->object_path = __get_object_path(evti->interface_name);
1024         if (!evti->object_path) {
1025                 _E("object_path is NULL");
1026                 ret = ES_R_ERROR;
1027                 goto out_4;
1028         }
1029         evti->destination_name = NULL;
1030         evti->is_user_event = false;
1031
1032         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) == ES_R_OK) {
1033                 ret = __eventsystem_send_event(conn, evti, data);
1034         } else {
1035                 _E("getting gdbus-connection error");
1036                 ret = ES_R_ERROR;
1037         }
1038
1039         if (conn)
1040                 g_object_unref(conn);
1041
1042         FREE_AND_NULL(evti->object_path);
1043 out_4:
1044         FREE_AND_NULL(evti->member_name);
1045 out_3:
1046         FREE_AND_NULL(evti->interface_name);
1047 out_2:
1048         FREE_AND_NULL(evti->event_name);
1049 out_1:
1050         FREE_AND_NULL(evti);
1051
1052 catch:
1053         pthread_mutex_unlock(&send_sync_lock);
1054
1055         return ret;
1056 }
1057
1058 /**
1059  * function : request sending the event
1060  */
1061 int eventsystem_request_sending_system_event(const char *event_name, bundle *data)
1062 {
1063         int ret = 0;
1064         GDBusConnection *conn = NULL;
1065         GError *error = NULL;
1066         GDBusProxy *proxy = NULL;
1067         GVariant *param = NULL;
1068         GVariant *value = NULL;
1069         gint result = 0;
1070         bundle_raw *raw = NULL;
1071         int len = 0;
1072
1073         _D("event_name(%s)", event_name);
1074
1075         if (!_initialized)
1076                 __initialize();
1077
1078         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1079                 _E("getting gdbus-connetion error");
1080                 ret = ES_R_ERROR;
1081                 goto out_1;
1082         }
1083
1084         proxy = g_dbus_proxy_new_sync(conn,
1085                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1086                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1087                 NULL, &error);
1088         if (proxy == NULL) {
1089                 _E("failed to create new proxy, error(%s)", error->message);
1090                 g_error_free(error);
1091                 ret = ES_R_ERROR;
1092                 goto out_1;
1093         }
1094
1095         bundle_encode(data, &raw, &len);
1096
1097         param = g_variant_new("(ssi)", event_name, raw, len);
1098         value = g_dbus_proxy_call_sync(proxy, "RequestSendingEvent", param,
1099                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1100         if (error != NULL) {
1101                 _E("proxy call sync error(%s)", error->message);
1102                 g_error_free(error);
1103                 ret = ES_R_ERROR;
1104                 goto out_2;
1105         }
1106
1107         g_variant_get(value, "(i)", &result);
1108
1109         _D("result(%d)", result);
1110
1111         ret = ES_R_OK;
1112
1113 out_2:
1114         g_variant_unref(value);
1115 out_1:
1116         if (conn)
1117                 g_object_unref(conn);
1118
1119         return ret;
1120 }
1121
1122 static int __eventsystem_check_sender_validation(int sender_pid, const char *event_name,
1123                 char **sender_id)
1124 {
1125         int ret = ES_R_EINVAL;
1126         GDBusConnection *conn = NULL;
1127         GError *error = NULL;
1128         GDBusProxy *proxy = NULL;
1129         GVariant *param = NULL;
1130         GVariant *value = NULL;
1131         gint result = 0;
1132
1133         if (!_initialized)
1134                 __initialize();
1135
1136         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1137                 _E("getting gdbus-connetion error");
1138                 ret = ES_R_ERROR;
1139                 goto out_1;
1140         }
1141
1142         proxy = g_dbus_proxy_new_sync(conn,
1143                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1144                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1145                 NULL, &error);
1146         if (proxy == NULL) {
1147                 _E("failed to create new proxy, error(%s)", error->message);
1148                 g_error_free(error);
1149                 ret = ES_R_ERROR;
1150                 goto out_1;
1151         }
1152
1153         param = g_variant_new("(is)", sender_pid, event_name);
1154         value = g_dbus_proxy_call_sync(proxy, "CheckSenderValidation", param,
1155                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1156         if (error != NULL) {
1157                 _E("proxy call sync error(%s)", error->message);
1158                 g_error_free(error);
1159                 ret = ES_R_ERROR;
1160                 goto out_2;
1161         }
1162
1163         g_variant_get(value, "(is)", &result, sender_id);
1164
1165         _D("result(%d)", result);
1166
1167         if (result == 1)
1168                 ret = ES_R_OK;
1169 out_2:
1170         g_variant_unref(value);
1171 out_1:
1172         if (conn)
1173                 g_object_unref(conn);
1174
1175         return ret;
1176 }
1177
1178 static int __eventsystem_check_user_send_validation(const char *event_name)
1179 {
1180         int ret = ES_R_EINVAL;
1181         GDBusConnection *conn = NULL;
1182         GError *error = NULL;
1183         GDBusProxy *proxy = NULL;
1184         GVariant *param = NULL;
1185         GVariant *value = NULL;
1186         gint result = 0;
1187
1188         if (!_initialized)
1189                 __initialize();
1190
1191         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1192                 _E("getting gdbus-connetion error");
1193                 ret = ES_R_ERROR;
1194                 goto out_1;
1195         }
1196
1197         proxy = g_dbus_proxy_new_sync(conn,
1198                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1199                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1200                 NULL, &error);
1201         if (proxy == NULL) {
1202                 _E("failed to create new proxy, error(%s)", error->message);
1203                 g_error_free(error);
1204                 ret = ES_R_ERROR;
1205                 goto out_1;
1206         }
1207
1208         param = g_variant_new("(s)", event_name);
1209         value = g_dbus_proxy_call_sync(proxy, "CheckUserSendValidation", param,
1210                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1211         if (error != NULL) {
1212                 _E("proxy call sync error(%s)", error->message);
1213                 g_error_free(error);
1214                 ret = ES_R_ERROR;
1215                 goto out_2;
1216         }
1217
1218         g_variant_get(value, "(i)", &result);
1219
1220         _D("result(%d)", result);
1221
1222         if (result == 1)
1223                 ret = ES_R_OK;
1224 out_2:
1225         g_variant_unref(value);
1226 out_1:
1227         if (conn)
1228                 g_object_unref(conn);
1229
1230         return ret;
1231 }
1232
1233 static int __eventsystem_check_privilege_validation(const char *event_name)
1234 {
1235         int ret = ES_R_ENOTPERMITTED;
1236         GDBusConnection *conn = NULL;
1237         GError *error = NULL;
1238         GDBusProxy *proxy = NULL;
1239         GVariant *param = NULL;
1240         GVariant *value = NULL;
1241         gint result = 0;
1242
1243         if (!_initialized)
1244                 __initialize();
1245
1246         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1247                 _E("getting gdbus-connetion error");
1248                 ret = ES_R_ERROR;
1249                 goto out_1;
1250         }
1251
1252         proxy = g_dbus_proxy_new_sync(conn,
1253                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1254                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1255                 NULL, &error);
1256         if (proxy == NULL) {
1257                 _E("failed to create new proxy, error(%s)", error->message);
1258                 g_error_free(error);
1259                 ret = ES_R_ERROR;
1260                 goto out_1;
1261         }
1262
1263         param = g_variant_new("(s)", event_name);
1264         value = g_dbus_proxy_call_sync(proxy, "CheckPrivilegeValidation", param,
1265                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1266         if (error != NULL) {
1267                 _E("proxy call sync error(%s)", error->message);
1268                 g_error_free(error);
1269                 ret = ES_R_ERROR;
1270                 goto out_2;
1271         }
1272
1273         g_variant_get(value, "(i)", &result);
1274
1275         _D("result(%d)", result);
1276
1277         if (result == 1)
1278                 ret = ES_R_OK;
1279 out_2:
1280         g_variant_unref(value);
1281 out_1:
1282         if (conn)
1283                 g_object_unref(conn);
1284
1285         return ret;
1286 }
1287
1288 static int __eventsystem_setup_trusted_peer(const char *event_name, const char *dest_bus_name)
1289 {
1290         int ret = ES_R_ERROR;
1291         GDBusConnection *conn = NULL;
1292         GError *error = NULL;
1293         GDBusProxy *proxy = NULL;
1294         GVariant *param = NULL;
1295         GVariant *value = NULL;
1296         gint result = 0;
1297
1298         if (!_initialized)
1299                 __initialize();
1300
1301         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1302                 _E("getting gdbus-connetion error");
1303                 ret = ES_R_ERROR;
1304                 goto out_1;
1305         }
1306
1307         proxy = g_dbus_proxy_new_sync(conn,
1308                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1309                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1310                 NULL, &error);
1311         if (proxy == NULL) {
1312                 _E("failed to create new proxy, error(%s)", error->message);
1313                 g_error_free(error);
1314                 ret = ES_R_ERROR;
1315                 goto out_1;
1316         }
1317
1318         param = g_variant_new("(ss)", event_name, dest_bus_name);
1319
1320         value = g_dbus_proxy_call_sync(proxy, "SetupTrustedPeer", param,
1321                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1322         if (error != NULL) {
1323                 _E("proxy call sync error(%s)", error->message);
1324                 g_error_free(error);
1325                 ret = ES_R_ERROR;
1326                 goto out_2;
1327         }
1328
1329         g_variant_get(value, "(i)", &result);
1330
1331         _D("result(%d)", result);
1332
1333         if (result == 1)
1334                 ret = ES_R_OK;
1335 out_2:
1336         g_variant_unref(value);
1337 out_1:
1338         if (conn)
1339                 g_object_unref(conn);
1340
1341         return ret;
1342 }
1343
1344 static int __eventsystem_requet_destination_list(const char *event_name, GList **dest_list)
1345 {
1346         int ret = ES_R_ERROR;
1347         GDBusConnection *conn = NULL;
1348         GError *error = NULL;
1349         GDBusProxy *proxy = NULL;
1350         GVariant *param = NULL;
1351         GVariant *value = NULL;
1352         GVariantIter *iter;
1353         gchar *str;
1354         char *dest_name = NULL;
1355         gint result = 0;
1356
1357         if (!_initialized)
1358                 __initialize();
1359
1360         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1361                 _E("getting gdbus-connetion error");
1362                 ret = ES_R_ERROR;
1363                 goto out_1;
1364         }
1365
1366         proxy = g_dbus_proxy_new_sync(conn,
1367                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1368                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1369                 NULL, &error);
1370         if (proxy == NULL) {
1371                 _E("failed to create new proxy, error(%s)", error->message);
1372                 g_error_free(error);
1373                 ret = ES_R_ERROR;
1374                 goto out_1;
1375         }
1376
1377         param = g_variant_new("(s)", event_name);
1378
1379         value = g_dbus_proxy_call_sync(proxy, "GetTrustedPeerList", param,
1380                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1381         if (error != NULL) {
1382                 _E("proxy call sync error(%s)", error->message);
1383                 g_error_free(error);
1384                 ret = ES_R_ERROR;
1385                 goto out_2;
1386         }
1387
1388         g_variant_get(value, "(ias)", &result, &iter);
1389
1390         _D("result(%d)", result);
1391
1392         if (result == 1) {
1393                 ret = ES_R_OK;
1394                 while (g_variant_iter_loop(iter, "s", &str)) {
1395                         dest_name = strdup((char *)str);
1396                         if (dest_name) {
1397                                 _D("dest name(%s)", str);
1398                                 *dest_list = g_list_append(*dest_list, dest_name);
1399                         } else {
1400                                 _E("out of memory");
1401                                 ret = ES_R_ENOMEM;
1402                                 break;
1403                         }
1404                 }
1405         }
1406         g_variant_iter_free(iter);
1407
1408 out_2:
1409         g_variant_unref(value);
1410 out_1:
1411         if (conn)
1412                 g_object_unref(conn);
1413
1414         return ret;
1415 }
1416
1417 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1418 static int __eventsystem_request_earlier_data(const char *event_name,
1419                 eventsystem_cb callback, void *user_data)
1420 {
1421         int ret = 0;
1422         GDBusConnection *conn = NULL;
1423         GError *error = NULL;
1424         GDBusProxy *proxy = NULL;
1425         GVariant *param = NULL;
1426         GVariant *value = NULL;
1427         gint result = 0;
1428         bundle_raw *raw = NULL;
1429         int len = 0;
1430
1431         if (!_initialized)
1432                 __initialize();
1433
1434         if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM, ES_TYPE_SYSTEM) < 0) {
1435                 _E("getting gdbus-connetion error");
1436                 ret = ES_R_ERROR;
1437                 goto out_1;
1438         }
1439
1440         proxy = g_dbus_proxy_new_sync(conn,
1441                 G_DBUS_PROXY_FLAGS_NONE, NULL,
1442                 ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
1443                 NULL, &error);
1444
1445         if (proxy == NULL) {
1446                 _E("failed to create new proxy, error(%s)", error->message);
1447                 g_error_free(error);
1448                 ret = ES_R_ERROR;
1449                 goto out_1;
1450         }
1451
1452         param = g_variant_new("(s)", event_name);
1453         value = g_dbus_proxy_call_sync(proxy, "GetEarlierData", param,
1454                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1455         if (error != NULL) {
1456                 _E("proxy call sync error(%s)", error->message);
1457                 g_error_free(error);
1458                 ret = ES_R_ERROR;
1459                 goto out_2;
1460         }
1461
1462         g_variant_get(value, "(iis)", &result, &len, &raw);
1463         g_variant_unref(value);
1464
1465         _D("result(%d), len(%d)", result, len);
1466
1467         if (!result && raw && len > 0) {
1468                 callback(event_name, raw, len, user_data);
1469                 bundle_free_encoded_rawdata(&raw);
1470         }
1471
1472         ret = ES_R_OK;
1473
1474 out_2:
1475         g_variant_unref(value);
1476 out_1:
1477         if (conn)
1478                 g_object_unref(conn);
1479
1480         return ret;
1481 }
1482 #endif
1483
1484 int eventsystem_register_application_event(const char *event_name, unsigned int *reg_id,
1485                 int *event_type, eventsystem_cb callback, void *user_data)
1486 {
1487         eventmap_s *em;
1488         char *interface_name = NULL;
1489         char *object_path = NULL;
1490         char *member_name = NULL;
1491         char *sender_name = NULL;
1492         GDBusSignalCallback filter;
1493         GBusType bus_type;
1494         guint  subscription_id  = 0;
1495         int ret = 0;
1496         GDBusConnection *conn = NULL;
1497
1498         if (!_initialized)
1499                 __initialize();
1500
1501         if (__check_eventname_validation_system((char *)event_name)) {
1502                 if (__eventsystem_check_privilege_validation(event_name) != ES_R_OK) {
1503                         _E("invalid privilege(%s)", event_name);
1504                         return ES_R_ENOTPERMITTED;
1505                 }
1506                 *event_type = ES_TYPE_SYSTEM;
1507         } else if (__check_eventname_validation_user((char *)event_name)) {
1508                 *event_type = ES_TYPE_USER;
1509         } else {
1510                 *event_type = ES_TYPE_UNKNOWN;
1511                 _E("unknown type event(%s)", event_name);
1512                 return ES_R_EINVAL;
1513         }
1514
1515         if (*event_type == ES_TYPE_SYSTEM) {
1516                 interface_name = strdup(SYS_EVENT_NAME_PREFIX);
1517                 if (interface_name == NULL) {
1518                         _E("out of memory");
1519                         return ES_R_ENOMEM;
1520                 }
1521                 if (!g_dbus_is_interface_name(interface_name)) {
1522                         _E("invalid interface_name(%s)", interface_name);
1523                         FREE_AND_NULL(interface_name);
1524                         return ES_R_EINVAL;
1525                 }
1526                 member_name = __get_member_name_from_eventname((char *)event_name);
1527                 if (member_name == NULL) {
1528                         _E("member_name is NULL(%s)", event_name);
1529                         FREE_AND_NULL(interface_name);
1530                         return ES_R_ERROR;
1531                 }
1532                 if (!g_dbus_is_member_name(member_name)) {
1533                         _E("Invalid member_name(%s)", member_name);
1534                         FREE_AND_NULL(interface_name);
1535                         FREE_AND_NULL(member_name);
1536                         return ES_R_ERROR;
1537                 }
1538                 filter = __eventsystem_filter_sysevent_for_application;
1539                 bus_type = G_BUS_TYPE_SYSTEM;
1540         } else {
1541                 interface_name = __get_encoded_interface_name((char *)event_name);
1542                 if (!interface_name) {
1543                         _E("interface_name is NULL");
1544                         return ES_R_ERROR;
1545                 }
1546                 if (!g_dbus_is_interface_name(interface_name)) {
1547                         _E("invalid interface_name(%s)", interface_name);
1548                         FREE_AND_NULL(interface_name);
1549                         return ES_R_EINVAL;
1550                 }
1551                 member_name = strdup(EVENT_SYSTEM_MEMBER);
1552                 if (!member_name) {
1553                         _E("out_of_memory");
1554                         FREE_AND_NULL(interface_name);
1555                         return ES_R_ERROR;
1556                 }
1557                 filter = __eventsystem_filter_userevent_for_application;
1558                 bus_type = G_BUS_TYPE_SESSION;
1559         }
1560
1561         object_path = __get_object_path(interface_name);
1562         if (!object_path) {
1563                 _E("failed get object_path");
1564                 FREE_AND_NULL(interface_name);
1565                 FREE_AND_NULL(member_name);
1566                 return ES_R_ERROR;
1567         }
1568         sender_name = NULL;
1569
1570         _D("interface_name(%s), object_path(%s)", interface_name, object_path);
1571         _D(" member_name(%s), sender_name(%s), type(%d), bus_type(%d)",
1572                 member_name, sender_name, *event_type, bus_type);
1573
1574         if (__get_gdbus_shared_connection(&conn, bus_type, *event_type) < 0) {
1575                 _E("getting gdbus-connetion error");
1576                 FREE_AND_NULL(interface_name);
1577                 FREE_AND_NULL(object_path);
1578                 FREE_AND_NULL(member_name);
1579                 return ES_R_ERROR;
1580         }
1581
1582 #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE
1583         __eventsystem_request_earlier_data(event_name, callback, user_data);
1584 #endif
1585
1586         subscription_id = g_dbus_connection_signal_subscribe(conn,
1587                 sender_name, /* sender */
1588                 interface_name,
1589                 member_name, /* member */
1590                 object_path, /* object_path */
1591                 NULL, /* arg0 */
1592                 G_DBUS_SIGNAL_FLAGS_NONE,
1593                 filter,
1594                 user_data,
1595                 NULL); /* user_data_free_func */
1596
1597         _D("event_name(%s), subscription_id(%d)", event_name, subscription_id);
1598
1599         if (subscription_id != 0) {
1600                 em = calloc(1, sizeof(eventmap_s));
1601                 if (!em) {
1602                         _E("memory alloc failed");
1603                         ret = ES_R_ENOMEM;
1604                 } else {
1605                         em->interface_name = strdup(interface_name);
1606                         em->member_name = strdup(member_name);
1607                         em->event_name = strdup(event_name);
1608                         em->es_cb = callback;
1609                         em->bus_type = bus_type;
1610                         em->reg_id = subscription_id;
1611                         em->event_type = *event_type;
1612
1613                         if (!em->interface_name || !em->member_name ||
1614                                 !em->event_name) {
1615                                 _E("out_of_memory");
1616                                 FREE_AND_NULL(em->interface_name);
1617                                 FREE_AND_NULL(em->member_name);
1618                                 FREE_AND_NULL(em->event_name);
1619                                 FREE_AND_NULL(em);
1620                                 ret = ES_R_ENOMEM;
1621                         } else {
1622                                 system_event_list =
1623                                         g_list_append(system_event_list, em);
1624                                 *reg_id = subscription_id;
1625
1626                                 ret = ES_R_OK;
1627
1628                                 if (em->bus_type == G_BUS_TYPE_SESSION &&
1629                                          em->event_type == ES_TYPE_USER) {
1630                                         if (s_info.own_name_session_bus == NULL) {
1631                                                 _E("session bus is not ready");
1632                                                 ret = ES_R_ERROR;
1633                                         } else {
1634                                                 if (__eventsystem_setup_trusted_peer(event_name,
1635                                                         s_info.own_name_session_bus) < 0) {
1636                                                         _E("failed to setup trusted peer");
1637                                                         ret = ES_R_ERROR;
1638                                                 }
1639                                         }
1640                                 }
1641                         }
1642                 }
1643         } else {
1644                 _E("dbus subscribe: error(%d)", subscription_id);
1645                 ret = ES_R_ERROR;
1646         }
1647
1648         FREE_AND_NULL(interface_name);
1649         FREE_AND_NULL(object_path);
1650         FREE_AND_NULL(member_name);
1651         if (conn)
1652                 g_object_unref(conn);
1653
1654         return ret;
1655 }
1656
1657 int eventsystem_unregister_application_event(unsigned int reg_id)
1658 {
1659         eventmap_s em;
1660         eventmap_s *em_data = NULL;
1661         GBusType bus_type;
1662         GList *cb_list = NULL;
1663         GDBusConnection *conn = NULL;
1664         eventsystem_event_type evt_type;
1665
1666         retvm_if(reg_id == 0, ES_R_EINVAL, "Invalid argument : reg_id");
1667
1668         if (!_initialized)
1669                 __initialize();
1670
1671         em.reg_id = reg_id;
1672         cb_list = g_list_find_custom(system_event_list, &em,
1673                 (GCompareFunc)__event_compare_reg_id_cb);
1674         if (cb_list) {
1675                 em_data = (eventmap_s *)cb_list->data;
1676
1677                 bus_type = em_data->bus_type;
1678                 evt_type = em_data->event_type;
1679
1680                 _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type);
1681
1682                 if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) {
1683                         _E("getting gdbus-connetion error");
1684                         return ES_R_ERROR;
1685                 }
1686                 g_dbus_connection_signal_unsubscribe(conn, reg_id);
1687
1688                 system_event_list = g_list_remove(system_event_list, cb_list->data);
1689
1690                 FREE_AND_NULL(em_data->interface_name);
1691                 FREE_AND_NULL(em_data->member_name);
1692                 FREE_AND_NULL(em_data->event_name);
1693                 FREE_AND_NULL(em_data);
1694                 g_object_unref(conn);
1695         } else {
1696                 _E("not found matched item");
1697                 return ES_R_ERROR;
1698         }
1699
1700         return ES_R_OK;
1701 }
1702
1703 int eventsystem_application_finalize(void)
1704 {
1705         gpointer key;
1706         gpointer value;
1707         GHashTableIter iter;
1708         char *key_item;
1709         char *val_item;
1710
1711         _D("release all resouces");
1712
1713         if (system_event_list)
1714                 g_list_free(system_event_list);
1715
1716         if (check_tbl) {
1717                 g_hash_table_iter_init(&iter, check_tbl);
1718
1719                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1720                         val_item = (char *)value;
1721                         if (val_item)
1722                                 free(val_item);
1723                         else
1724                                 _E("check_tbl, val_item is NULL");
1725                         g_hash_table_iter_remove(&iter);
1726                 }
1727                 g_hash_table_unref(check_tbl);
1728         }
1729
1730         if (filter_tbl) {
1731                 g_hash_table_iter_init(&iter, filter_tbl);
1732
1733                 while (g_hash_table_iter_next(&iter, &key, &value)) {
1734                         key_item = (char *)key;
1735                         if (key_item)
1736                                 free(key_item);
1737                         else
1738                                 _E("filter_tbl, key_item is NULL");
1739
1740                         val_item = (char *)value;
1741                         if (val_item)
1742                                 free(val_item);
1743                         else
1744                                 _E("filter_tbl, val_item is NULL");
1745
1746                         g_hash_table_iter_remove(&iter);
1747                 }
1748                 g_hash_table_unref(filter_tbl);
1749         }
1750
1751         FREE_AND_NULL(s_info.own_name_system_bus);
1752         FREE_AND_NULL(s_info.own_name_session_bus);
1753
1754         return 0;
1755 }