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