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