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