b825c5e4ce5d97eff116c4d0d26d8f2f42168bbb
[platform/core/appfw/event-system.git] / src / modules / dbus_event / dbus_event_module.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <glib.h>
4 #include <aul.h>
5 #include <aul_svc.h>
6 #include <unistd.h>
7 #include <ctype.h>
8 #include <gio/gio.h>
9 #include <package-manager.h>
10 #include <pkgmgr-info.h>
11 #include <appsvc/appsvc.h>
12 #include <eventsystem.h>
13 #include <bundle_internal.h>
14 #include <fcntl.h>
15 #include <vconf.h>
16 #include <tzplatform_config.h>
17 #include <cert-svc/ccert.h>
18 #include <cert-svc/cinstance.h>
19 #include "log.hh"
20 #include "dbus_event_module.hh"
21
22 #define FREE_AND_NULL(ptr) do { \
23   if (ptr) { \
24     free((void *)ptr); \
25     ptr = NULL; \
26   } \
27 } while (0)
28
29 namespace {
30
31 #include "introspection_cb.hh"
32
33 constexpr const char ESD_BOOT_COMPLETED[] = "/tmp/esd_ready";
34 constexpr const char SYSTEMD_DBUS_DEST[] = "org.freedesktop.systemd1";
35 constexpr const char SYSTEMD_DBUS_IFACE_MANAGER[] = "org.freedesktop.systemd1.Manager";
36 constexpr const char SYSTEMD_DBUS_PATH[] = "/org/freedesktop/systemd1";
37 constexpr const char SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED[] = "StartupFinished";
38 constexpr const char SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED[] = "UserSessionStartupFinished";
39
40 #define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER)
41 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
42 constexpr const int ROOT_USER = 0;
43
44 constexpr const char SYS_EVENT_NAME_PREFIX[] = "tizen.system.event";
45 constexpr const char SYS_EVENT_OBJ_PATH[] = "/tizen/system/event";
46 constexpr const char REQUEST_LAST_DATA[] = "request_last_data";
47
48 GHashTable *event_launch_table; /* table of events for launch_on_event*/
49
50 const char *event_launch_support_list[] = {
51   SYS_EVENT_BATTERY_CHARGER_STATUS,
52   SYS_EVENT_USB_STATUS,
53   SYS_EVENT_EARJACK_STATUS,
54   SYS_EVENT_INCOMMING_MSG,
55   SYS_EVENT_OUTGOING_MSG,
56   SYS_EVENT_WIFI_STATE
57 };
58
59 const char *earlier_event_list[] = {
60   SYS_EVENT_ESD_STATUS,
61   SYS_EVENT_LOW_MEMORY,
62   SYS_EVENT_BOOT_COMPLETED,
63   SYS_EVENT_SYSTEM_SHUTDOWN,
64   SYS_EVENT_BATTERY_CHARGER_STATUS
65 };
66
67 GHashTable *earlier_event_table; /* table of events for earlier_data */
68
69 typedef struct __earlier_table_item {
70   char *event_name;
71   guint reg_id;
72   bundle *earlier_data; /* event-data from earlier occurrence */
73 } earlier_item;
74
75 GHashTable *user_last_event_table; /* table of user events for last data */
76
77 struct __last_event_item {
78   char *key;
79   char *app_id;
80   char *event_name;
81   char *own_name;
82   uid_t uid;
83 };
84
85 GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */
86
87 typedef struct __trusted_busname_item {
88   char *app_id;
89   char *bus_name;
90   int pid;
91   uid_t uid;
92 } trusted_item;
93
94 typedef struct __eventlaunch_item_param {
95   char *app_id;
96 } eventlaunch_item_param_s;
97
98 enum trusted_result {
99   TRUSTED_UNKNOWN,
100   TRUSTED_ALLOWED,
101   TRUSTED_DENIED,
102 };
103
104 typedef struct esd_list_item {
105   char *pkg_id;
106   char *app_id;
107   int trusted_info;
108   uid_t uid;
109 } esd_list_item_s;
110
111 typedef struct  __event_launch_table_item {
112   char *event_name;
113   char *package_name; /* just for passing pointer to app-list removal func */
114   GList *app_list_evtlaunch; /* app-list for on-event-launch */
115   guint reg_id;
116   uid_t uid;
117 } event_launch_item;
118
119 enum __pkg_event_type {
120   UNKNOWN = 0,
121   INSTALL,
122   UNINSTALL,
123   UPDATE,
124 };
125
126 typedef struct __pkgmgr_event {
127   int type;
128   char *pkgid;
129 } esd_pkgmgr_event;
130
131 typedef struct __esd_event_param {
132   char *event_name;
133   bundle *event_data;
134   uid_t sender_uid;
135   char *sender_appid;
136   bool is_user_event;
137   bool trusted;
138   void *user_data;
139 } esd_event_param;
140
141 typedef struct esd_info {
142   pkgmgr_client *client;
143 } esd_info_s;
144 static esd_info_s s_info;
145
146 typedef struct __esd_appctrl_cb_data {
147   char *appid;
148   char *pkgid;
149   uid_t uid;
150 } esd_appctrl_cb_data;
151
152 void __esd_event_handler(char *event_name, bundle *data, void *user_data);
153 int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data);
154
155 void free_saved_event(struct __last_event_item *item) {
156   if (!item)
157     return;
158
159   free(item->event_name);
160   free(item->own_name);
161   free(item->app_id);
162   free(item);
163 }
164
165 int __esd_check_earlier_support(const char *event_name) {
166   int i = 0;
167   int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
168
169   for (i = 0; i < size; i++) {
170     if (strcmp(earlier_event_list[i], event_name) == 0)
171       return true;
172   }
173
174   return false;
175 }
176
177 bool __esd_check_platform_cert(const char *pkgid, uid_t uid) {
178   _D("Checking if %s has a platform certification", pkgid);
179
180   int r;
181   const char *cert_value;
182   pkgmgrinfo_certinfo_h certinfo;
183   CertSvcInstance instance;
184   CertSvcCertificate certificate;
185   CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
186
187   r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
188   if (r != PMINFO_R_OK) {
189     _E("Failed to create certinfo");
190     return false;
191   }
192
193   r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
194   if (r != PMINFO_R_OK) {
195     _E("Failed to load certinfo");
196     pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
197     return false;
198   }
199
200   r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
201       PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
202   if (r != PMINFO_R_OK || cert_value == NULL) {
203     _E("Failed to get cert value");
204     pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
205     return false;
206   }
207
208   r = certsvc_instance_new(&instance);
209   if (r != CERTSVC_SUCCESS) {
210     _E("certsvc_instance_new() is failed.");
211     pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
212     return false;
213   }
214
215   r = certsvc_certificate_new_from_memory(instance,
216       (const unsigned char *)cert_value,
217       strlen(cert_value),
218       CERTSVC_FORM_DER_BASE64,
219       &certificate);
220   if (r != CERTSVC_SUCCESS) {
221     _E("certsvc_certificate_new_from_memory() is failed.");
222     pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
223     certsvc_instance_free(instance);
224     return false;
225   }
226
227   r = certsvc_certificate_get_visibility(certificate, &visibility);
228   if (r != CERTSVC_SUCCESS)
229     _E("certsvc_certificate_get_visibility() is failed.");
230
231   pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
232   certsvc_certificate_free(certificate);
233   certsvc_instance_free(instance);
234
235   _D("visibility is %d", visibility);
236   if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
237     _D("%s has a platform certification", pkgid);
238     return true;
239   }
240
241   return false;
242 }
243
244 int __esd_check_event_launch_support(const char *event_name) {
245   int i = 0;
246   int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list);
247
248   for (i = 0; i < size; i++) {
249     if (strcmp(event_launch_support_list[i], event_name) == 0)
250       return true;
251   }
252
253   return false;
254 }
255
256 int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type) {
257   GDBusMessage *msg = NULL;
258   GDBusMessage *reply = NULL;
259   GError *err = NULL;
260   GVariant *body;
261   int ret = -1;
262   unsigned int value;
263
264   msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
265     "org.freedesktop.DBus", type);
266   if (!msg) {
267     _E("Can't allocate new method call");
268     goto out;
269   }
270
271   g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
272   reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
273     G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
274
275   if (!reply) {
276     if (err != NULL) {
277       _E("Failed to get info [%s]", err->message);
278       g_error_free(err);
279     }
280     goto out;
281   }
282
283   body = g_dbus_message_get_body(reply);
284   g_variant_get(body, "(u)", &value);
285   ret = (int)value;
286
287 out:
288   if (msg)
289     g_object_unref(msg);
290   if (reply)
291     g_object_unref(reply);
292
293   return ret;
294 }
295
296 int __get_sender_pid(GDBusConnection *conn, const char *sender_name) {
297   int pid = 0;
298
299   pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID");
300   if (pid < 0) {
301     _E("failed to get pid");
302     pid = 0;
303   }
304
305   _D("sender_name(%s), pid(%d)", sender_name, pid);
306
307   return pid;
308 }
309
310 int __get_sender_uid(GDBusConnection *conn, const char *sender_name) {
311   int uid = -1;
312
313   uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser");
314   if (uid < 0)
315     _E("failed to get uid");
316
317   _D("sender_name(%s), uid(%d)", sender_name, uid);
318
319   return uid;
320 }
321
322 int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid) {
323   pkgmgrinfo_cert_compare_result_type_e res;
324   int ret = 0;
325
326   _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid);
327
328   ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res);
329   if (ret < 0) {
330     _E("failed to check certificate");
331     return ES_R_ERROR;
332   }
333
334   if (res != PMINFO_CERT_COMPARE_MATCH) {
335     _D("certificat not match (%s)", app_id);
336     return ES_R_EINVAL;
337   }
338
339   return ES_R_OK;
340 }
341
342 bool __esd_check_application_validation(uid_t uid, const char *appid) {
343   int ret = 0;
344   pkgmgrinfo_appinfo_h handle;
345
346   ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle);
347   if (ret != PMINFO_R_OK)
348     return false;
349
350   pkgmgrinfo_appinfo_destroy_appinfo(handle);
351
352   if (!aul_app_is_running_for_uid(appid, uid))
353     return false;
354
355   return true;
356 }
357
358 void __esd_trusted_busname_print_items() {
359   GHashTableIter iter;
360   gpointer key;
361   gpointer value;
362
363   g_hash_table_iter_init(&iter, trusted_busname_table);
364
365   while (g_hash_table_iter_next(&iter, &key, &value)) {
366     trusted_item *item = (trusted_item *)value;
367     if (item)
368       _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name);
369   }
370 }
371
372 int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid) {
373   char *app_id = NULL;
374   char *bus_name = NULL;
375   trusted_item *item = NULL;
376   trusted_item *new_item;
377
378   app_id = strdup(appid);
379   if (app_id == NULL) {
380     _E("out of memory");
381     return ES_R_ENOMEM;
382   }
383
384   bus_name = strdup(busname);
385   if (bus_name == NULL) {
386     _E("out of memory");
387     FREE_AND_NULL(app_id);
388     return ES_R_ENOMEM;
389   }
390
391   item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id);
392
393   if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 &&
394     (item->uid == uid)) {
395     _D("already exist (%s, %s)", app_id, bus_name);
396     FREE_AND_NULL(app_id);
397     FREE_AND_NULL(bus_name);
398   } else {
399     new_item = (trusted_item *)calloc(1, sizeof(trusted_item));
400     if (new_item == NULL) {
401       _E("memory alloc failed");
402       FREE_AND_NULL(app_id);
403       FREE_AND_NULL(bus_name);
404       return ES_R_ENOMEM;
405     }
406     new_item->uid = uid;
407     new_item->app_id = app_id;
408     new_item->bus_name = bus_name;
409     new_item->pid = pid;
410     g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item);
411     _D("added busname(%s)", new_item->bus_name);
412   }
413
414   return ES_R_OK;
415 }
416
417 int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) {
418   GVariant *result;
419   GError *error = NULL;
420   GVariantIter *iter;
421   gchar *str;
422   char tmp_appid[128] = {0, };
423   int pid = 0;
424   int uid = 0;
425   int ret = 0;
426
427   result = g_dbus_connection_call_sync(conn,
428     "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
429     list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE,
430     -1, NULL, &error);
431
432   if (result == NULL) {
433     _E("get (%s) error(%s)", list_name, error->message);
434     g_error_free(error);
435     return ES_R_ERROR;
436   }
437
438   g_variant_get(result, "(as)", &iter);
439   while (g_variant_iter_loop(iter, "s", &str)) {
440     if (!strstr((const char *)str, "event.busname.session"))
441       continue;
442
443     _D("list(%s), name(%s)", list_name, str);
444     pid = __get_sender_pid(conn, (const char *)str);
445     if (pid <= 0) {
446       _E("failed to get pid(%d)", pid);
447       continue;
448     }
449
450     uid = __get_sender_uid(conn, (const char *)str);
451     if (uid < 0) {
452       _E("failed to get uid(%d)", uid);
453       continue;
454     }
455     _D("uid(%d)", uid);
456
457     memset(tmp_appid, 0, sizeof(tmp_appid));
458     ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid);
459     if (ret != AUL_R_OK) {
460       _E("failed to get appid by pid(%d)", pid);
461       continue;
462     }
463
464     _D("appid(%s)", tmp_appid);
465     if (__esd_check_application_validation((uid_t)uid, tmp_appid)) {
466       _D("add to table");
467       ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid);
468       if (ret < 0)
469         _E("failed to add item");
470     }
471   }
472   g_variant_iter_free(iter);
473   g_variant_unref(result);
474
475   return ES_R_OK;
476 }
477
478 void __esd_print_appid_with_eventid(gpointer data, gpointer user_data) {
479   esd_list_item_s *item = (esd_list_item_s *)data;
480   char *event_name = (char *)user_data;
481
482   _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id);
483 }
484
485 void __esd_print_interested_event(gpointer data, gpointer user_data) {
486   event_launch_item *el_item = (event_launch_item *)data;
487   char *event_name = (char *)el_item->event_name;
488   _D("event_name = (%s)", event_name);
489   g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name);
490 }
491
492 void __esd_launch_table_print_items() {
493   GHashTableIter iter;
494   gpointer key;
495   gpointer value;
496
497   g_hash_table_iter_init(&iter, event_launch_table);
498
499   while (g_hash_table_iter_next(&iter, &key, &value))
500     __esd_print_interested_event(value, NULL);
501 }
502
503 int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data) {
504   esd_list_item_s *item_1 = (esd_list_item_s *)user_data;
505   esd_list_item_s *item_2 = (esd_list_item_s *)data;
506
507   return (item_1->uid != item_2->uid) |
508     strcmp(item_1->app_id, item_2->app_id) |
509     strcmp(item_1->pkg_id, item_2->pkg_id);
510 }
511
512 int __esd_add_list_item(uid_t uid, event_launch_item *el_item,
513     const char *app_id, const char *pkg_id) {
514   esd_list_item_s *item_of_list = NULL;
515
516   item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s));
517   if (item_of_list == NULL) {
518     _E("out_of_memory");
519     return ES_R_ENOMEM;
520   }
521   item_of_list->uid = uid;
522   item_of_list->app_id = (char *)app_id;
523   item_of_list->pkg_id = (char *)pkg_id;
524   item_of_list->trusted_info = TRUSTED_UNKNOWN;
525   el_item->app_list_evtlaunch =
526     g_list_append(el_item->app_list_evtlaunch, item_of_list);
527
528   return ES_R_OK;
529 }
530
531 int __esd_add_launch_item(uid_t uid, const char *event_name,
532     const char *appid, const char *pkgid) {
533   GList *app_list = NULL;
534   guint subscription_id = 0;
535   char *app_id = NULL;
536   char *pkg_id = NULL;
537   esd_list_item_s *item_of_list = NULL;
538   event_launch_item *eli;
539   event_launch_item *el_item =
540     (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
541
542   if (el_item) {
543     item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s));
544     if (item_of_list == NULL) {
545       _E("memory alloc failed");
546       return ES_R_ENOMEM;
547     }
548     item_of_list->uid = uid;
549     item_of_list->app_id = (char *)appid;
550     item_of_list->pkg_id = (char *)pkgid;
551
552     app_list = g_list_find_custom(el_item->app_list_evtlaunch,
553       item_of_list, (GCompareFunc)__esd_find_compare_by_list_item);
554     free(item_of_list);
555     if (app_list == NULL) {
556       _D("add new item (list item only)");
557       app_id = strdup((char *)appid);
558       if (!app_id) {
559         _E("out_of_memory");
560         return ES_R_ENOMEM;
561       }
562       pkg_id = strdup((char *)pkgid);
563       if (!pkg_id) {
564         _E("out_of_memory");
565         FREE_AND_NULL(app_id);
566         return ES_R_ENOMEM;
567       }
568       if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) {
569         _E("failed to add list item");
570         FREE_AND_NULL(app_id);
571         FREE_AND_NULL(pkg_id);
572         return ES_R_ERROR;
573       }
574     }
575   } else {
576     _D("add new item (all)");
577     eli = (event_launch_item *)calloc(1, sizeof(event_launch_item));
578     if (!eli) {
579       _E("memory alloc failed");
580       return ES_R_ENOMEM;
581     }
582
583     eli->event_name = strdup(event_name);
584     if (!eli->event_name) {
585       _E("out_of_memory");
586       FREE_AND_NULL(eli);
587       return ES_R_ENOMEM;
588     }
589
590     app_id = strdup((char *)appid);
591     if (!app_id) {
592       _E("out_of_memory");
593       FREE_AND_NULL(eli->event_name);
594       FREE_AND_NULL(eli);
595       return ES_R_ENOMEM;
596     }
597
598     pkg_id = strdup((char *)pkgid);
599     if (!pkg_id) {
600       _E("out_of_memory");
601       FREE_AND_NULL(app_id);
602       FREE_AND_NULL(eli->event_name);
603       FREE_AND_NULL(eli);
604       return ES_R_ENOMEM;
605     }
606
607     if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) {
608       _E("failed to add list item");
609       FREE_AND_NULL(app_id);
610       FREE_AND_NULL(pkg_id);
611       FREE_AND_NULL(eli->event_name);
612       FREE_AND_NULL(eli);
613       return ES_R_ERROR;
614     }
615
616     g_hash_table_insert(event_launch_table, eli->event_name, eli);
617
618     eventsystem_register_event(eli->event_name, &subscription_id,
619       (eventsystem_handler)__esd_event_handler, NULL);
620     if (subscription_id == 0) {
621       _E("signal subscription error, event_name(%s), app_id(%s)",
622         eli->event_name, app_id);
623       return ES_R_ERROR;
624     } else {
625       eli->reg_id = subscription_id;
626     }
627   }
628
629   return ES_R_OK;
630 }
631
632 void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data) {
633   esd_list_item_s *item = (esd_list_item_s *)data;
634   event_launch_item *eli = (event_launch_item *)user_data;
635
636   if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) {
637     _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name);
638     eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data);
639   }
640 }
641
642 int __esd_launch_table_remove_private_usr_items() {
643   GHashTableIter iter;
644   gpointer key;
645   gpointer value;
646   event_launch_item *eli = NULL;
647   GList *first_list = NULL;
648
649   g_hash_table_iter_init(&iter, event_launch_table);
650
651   while (g_hash_table_iter_next(&iter, &key, &value)) {
652     eli = (event_launch_item *)value;
653     g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli);
654
655     first_list = g_list_first(eli->app_list_evtlaunch);
656     if (first_list == NULL) {
657       if (eli->reg_id)
658         eventsystem_unregister_event(eli->reg_id);
659
660       g_hash_table_iter_remove(&iter);
661     }
662   }
663
664   return ES_R_OK;
665 }
666
667 void __esd_remove_app_list(gpointer data, gpointer user_data) {
668   bool skip = false;
669   esd_list_item_s *item = (esd_list_item_s *)data;
670   event_launch_item *eli = (event_launch_item *)user_data;
671
672   if (eli->uid != GLOBAL_USER && eli->uid != item->uid)
673     skip = true;
674
675   if (!skip && !strcmp(eli->package_name, item->pkg_id)) {
676     _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id);
677     eli->app_list_evtlaunch =
678       g_list_remove_all(eli->app_list_evtlaunch, data);
679   }
680 }
681
682 int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id) {
683   event_launch_item *eli = (event_launch_item *)data;
684   GList *first_list = NULL;
685
686   eli->uid = uid;
687   eli->package_name = (char *)pkg_id;
688   g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli);
689
690   first_list = g_list_first(eli->app_list_evtlaunch);
691   if (first_list == NULL) {
692     if (eli->reg_id)
693       eventsystem_unregister_event(eli->reg_id);
694
695     return ES_R_REMOVE;
696   }
697
698   return ES_R_OK;
699 }
700
701 int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id) {
702   GHashTableIter iter;
703   gpointer key;
704   gpointer value;
705
706   g_hash_table_iter_init(&iter, event_launch_table);
707
708   while (g_hash_table_iter_next(&iter, &key, &value)) {
709     if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) {
710       _D("remove item itself");
711       g_hash_table_iter_remove(&iter);
712     }
713   }
714
715   return ES_R_OK;
716 }
717
718 void __esd_event_launch_with_appid(gpointer data, gpointer user_data) {
719   esd_list_item_s *item = (esd_list_item_s *)data;
720   uid_t uid = item->uid;
721   char *app_id = item->app_id;
722   esd_event_param *eep = (esd_event_param *)user_data;
723   static unsigned int req_id;
724   int pid;
725   char event_uri[1024];
726   bundle *b;
727   int ret;
728
729   _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)",
730       app_id, eep->event_name, uid, eep->is_user_event, eep->trusted);
731
732   if (eep->is_user_event && eep->trusted) {
733     if (item->trusted_info == TRUSTED_UNKNOWN) {
734       ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid);
735       if (ret == ES_R_EINVAL) {
736         item->trusted_info = TRUSTED_DENIED;
737         return;
738       } else if (ret == ES_R_ERROR) {
739         return;
740       } else {
741         item->trusted_info = TRUSTED_ALLOWED;
742       }
743     } else if (item->trusted_info == TRUSTED_DENIED) {
744       return;
745     }
746   }
747
748   if (!aul_app_is_running_for_uid(app_id, uid)) {
749     b = bundle_dup(eep->event_data);
750     if (eep->is_user_event)
751       snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name);
752     else
753       snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name);
754
755     appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT);
756     appsvc_set_uri(b, event_uri);
757     appsvc_set_appid(b, app_id);
758
759     pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid);
760     _D("uid(%d), pid(%d)", uid, pid);
761
762     bundle_free(b);
763   } else {
764     _D("already is running or launch failed");
765   }
766 }
767
768 void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data) {
769   event_launch_item *el_item = (event_launch_item *)data;
770   esd_event_param *eep = (esd_event_param *)user_data;
771
772   if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) {
773     g_list_foreach(el_item->app_list_evtlaunch,
774       __esd_event_launch_with_appid, user_data);
775   }
776 }
777
778 void __esd_launch_event_handler(char *event_name, bundle *data,
779     const bool is_user_event, gboolean trusted,
780     const uid_t sender_uid, char *sender_appid, void *user_data) {
781   const char *val;
782   const char *msg_type;
783   const char *msg_id;
784   esd_event_param *eep;
785   event_launch_item *el_item;
786
787   _D("event_name(%s)", event_name);
788
789   el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name);
790   if (el_item == NULL)
791     return;
792
793   if (el_item->app_list_evtlaunch != NULL) {
794     if (is_user_event == false) {
795       if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) {
796         val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS);
797         _D("charger val(%s)", val);
798         if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0))
799           return;
800       } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) {
801         val = bundle_get_val(data, EVT_KEY_USB_STATUS);
802         _D("usb val(%s)", val);
803         if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0))
804           return;
805       } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) {
806         val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS);
807         _D("earjack val(%s)", val);
808         if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0))
809           return;
810       } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) {
811         msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE);
812         _D("msg_type(%s)", msg_type);
813         if (msg_type == NULL)
814           return;
815
816         msg_id = bundle_get_val(data, EVT_KEY_MSG_ID);
817         _D("msg_id(%s)", msg_id);
818         if (msg_id == NULL)
819           return;
820       } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) {
821         val = bundle_get_val(data, EVT_KEY_WIFI_STATE);
822         if (val == NULL)
823           return;
824         _D("wifi_state(%s)", val);
825         if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0)
826           return;
827       }
828     }
829
830     eep = (esd_event_param *)calloc(1, sizeof(esd_event_param));
831     if (!eep) {
832       _E("memory alloc failed");
833       return;
834     }
835     eep->event_name = event_name;
836     eep->event_data = data;
837     eep->sender_uid = sender_uid;
838     eep->sender_appid = sender_appid;
839     eep->is_user_event = is_user_event;
840     eep->trusted = (bool)trusted;
841     eep->user_data = (void *)user_data;
842     __esd_check_event_launch_with_eventid(el_item, eep);
843     free(eep);
844   }
845 }
846
847 void __esd_print_earlier_event(gpointer data, gpointer user_data) {
848   earlier_item *item = (earlier_item *)data;
849   char *event_name = (char *)item->event_name;
850   const char *val;
851
852   _D("event_name = (%s)", event_name);
853
854   if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
855     if (item->earlier_data) {
856       val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED);
857       _D("boot_completed(%s)", val);
858     }
859   } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
860     if (item->earlier_data) {
861       val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN);
862       _D("shutdown(%s)", val);
863     }
864   } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
865     if (item->earlier_data) {
866       val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY);
867       _D("low_memory(%s)", val);
868     }
869   } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
870     if (item->earlier_data) {
871       val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS);
872       _D("charger_status(%s)", val);
873     }
874   }
875 }
876
877 void __esd_earlier_table_print_items() {
878   GHashTableIter iter;
879   gpointer key;
880   gpointer value;
881
882   g_hash_table_iter_init(&iter, earlier_event_table);
883
884   while (g_hash_table_iter_next(&iter, &key, &value))
885     __esd_print_earlier_event(value, NULL);
886 }
887
888 void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data) {
889   earlier_item *item;
890   _D("event_name(%s)", event_name);
891
892   item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
893   if (item) {
894     /* update earlier value */
895     if (item->earlier_data != NULL)
896       bundle_free(item->earlier_data);
897
898     item->earlier_data = bundle_dup(data);
899   }
900 }
901
902 void __esd_event_handler(char *event_name, bundle *data, void *user_data) {
903   _D("event_name(%s)", event_name);
904
905   if (__esd_check_earlier_support(event_name))
906     __esd_earlier_event_handler(event_name, data, user_data);
907
908   if (__esd_check_event_launch_support(event_name))
909     __esd_launch_event_handler(event_name, data,
910         false, TRUE, ROOT_USER, NULL, user_data);
911 }
912
913 void __esd_trusted_busname_remove_item(char *bus_name) {
914   GHashTableIter iter;
915   gpointer key;
916   gpointer value;
917   trusted_item *item;
918
919   g_hash_table_iter_init(&iter, trusted_busname_table);
920
921   while (g_hash_table_iter_next(&iter, &key, &value)) {
922     item = (trusted_item *)value;
923     if (item) {
924       if (strcmp(bus_name, item->bus_name) == 0) {
925         _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name);
926         FREE_AND_NULL(item->app_id);
927         FREE_AND_NULL(item->bus_name);
928         FREE_AND_NULL(item);
929         g_hash_table_iter_remove(&iter);
930
931         __esd_trusted_busname_print_items();
932       }
933     }
934   }
935 }
936
937 void __esd_filter_name_owner_changed(GDBusConnection *connection,
938     const gchar *sender_name, const gchar *object_path,
939     const gchar *interface_name, const gchar *signal_name,
940     GVariant *parameters, gpointer user_data) {
941   char *name = NULL;
942   char *old_owner = NULL;
943   char *new_owner = NULL;
944   int old_len = 0;
945   int new_len = 0;
946
947   g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
948
949   if (strstr(name, "event.busname.session")) {
950     old_len = strlen(old_owner);
951     new_len = strlen(new_owner);
952
953     _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)",
954       name, old_owner, old_len, new_owner, new_len);
955
956     if (old_len > 0 && new_len == 0)
957       __esd_trusted_busname_remove_item(name);
958     else if (old_len == 0 && new_len > 0)
959       _D("new name owned");
960     else
961       _E("not-expected name change");
962   }
963 }
964
965 int __esd_dbus_name_monitor(GDBusConnection *connection) {
966   guint name_owner_changed_id = 0;
967
968   name_owner_changed_id = g_dbus_connection_signal_subscribe(connection,
969     "org.freedesktop.DBus", "org.freedesktop.DBus",
970     "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE,
971     __esd_filter_name_owner_changed, NULL, NULL);
972
973   _I("name_owner_changed_id(%d)", name_owner_changed_id);
974
975   return ES_R_OK;
976 }
977
978 int __esd_get_user_items(uid_t uid) {
979   int ret = 0;
980   pkgmgrinfo_appinfo_filter_h handle = NULL;
981
982   _I("get user items for uid(%d)", uid);
983   /* reset user's item */
984   __esd_launch_table_remove_private_usr_items();
985
986   ret = pkgmgrinfo_appinfo_filter_create(&handle);
987   if (ret < 0) {
988     _E("failed to create appinfo filter");
989     return ES_R_ERROR;
990   }
991   ret = pkgmgrinfo_appinfo_filter_add_string(handle,
992       PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp");
993   if (ret < 0) {
994     _E("failed to add appinfo filter string");
995     pkgmgrinfo_appinfo_filter_destroy(handle);
996     return ES_R_ERROR;
997   }
998   ret = pkgmgrinfo_appinfo_filter_add_string(handle,
999       PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT);
1000   if (ret < 0) {
1001     _E("failed to add appinfo filter string");
1002     pkgmgrinfo_appinfo_filter_destroy(handle);
1003     return ES_R_ERROR;
1004   }
1005   ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle,
1006       __esd_add_appinfo_handler, &uid, uid);
1007   if (ret < 0) {
1008     _E("appinfo filter foreach error");
1009     pkgmgrinfo_appinfo_filter_destroy(handle);
1010     return ES_R_ERROR;
1011   }
1012   pkgmgrinfo_appinfo_filter_destroy(handle);
1013
1014   __esd_launch_table_print_items();
1015
1016   return ES_R_OK;
1017 }
1018
1019 void __esd_signal_handler(GDBusConnection *connection,
1020     const gchar *sender_name,
1021     const gchar *object_path,
1022     const gchar *interface_name,
1023     const gchar *signal_name,
1024     GVariant *parameters,
1025     gpointer user_data) {
1026   int handle;
1027   bundle *b;
1028   guint64 uid = 0;
1029
1030   if (!g_strcmp0(signal_name,
1031         SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) {
1032     _I("System session finished");
1033
1034     b = bundle_create();
1035     bundle_add_str(b, EVT_KEY_BOOT_COMPLETED,
1036       EVT_VAL_BOOT_COMPLETED_TRUE);
1037     eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b);
1038     bundle_free(b);
1039
1040     handle = creat(ESD_BOOT_COMPLETED, 0640);
1041     if (handle != -1)
1042       close(handle);
1043   } else if (!g_strcmp0(signal_name,
1044         SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) {
1045     g_variant_get(parameters, "(t)", &uid);
1046     _I("User session finished uid : %d", (int)uid);
1047     if ((uid_t)uid != DEFAULT_USER)
1048       __esd_get_user_items((uid_t)uid);
1049   }
1050 }
1051
1052 static GDBusNodeInfo *introspection_data;
1053
1054 int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size) {
1055   int retval = ES_R_OK;
1056   int ret = 0;
1057
1058   if (pid <= 0) {
1059     _E("invalid pid(%d)", pid);
1060     retval = ES_R_ERROR;
1061   } else if (uid <= 0) {
1062     _E("invalid uid(%d)", uid);
1063     retval = ES_R_ERROR;
1064   } else {
1065     ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid);
1066     if (ret != AUL_R_OK) {
1067       _E("failed to get appid by pid");
1068       retval = ES_R_ERROR;
1069     }
1070     _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id);
1071   }
1072
1073   return retval;
1074 }
1075
1076 int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size) {
1077   int ret;
1078   int fd;
1079   char buf[128] = { 0, };
1080
1081   ret = aul_app_get_appid_bypid(pid, app_id, buf_size);
1082   if (ret != AUL_R_OK) {
1083     snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
1084
1085     fd = open(buf, O_RDONLY);
1086     if (fd < 0)
1087       return ES_R_ERROR;
1088
1089     ret = read(fd, app_id, buf_size - 1);
1090     close(fd);
1091
1092     if (ret <= 0)
1093       return ES_R_ERROR;
1094
1095     app_id[ret] = '\0';
1096     ret = ES_R_OK;
1097   }
1098
1099   return ret;
1100 }
1101
1102 int check_user_event_sender_valid(const char *event_name, const char *app_id) {
1103   char *valid_name = NULL;
1104   char *temp_name = NULL;
1105   char *tmp = NULL;
1106   int retval = ES_R_OK;
1107   int len = 0;
1108   int valid_name_len = 0;
1109
1110   temp_name = strdup(event_name);
1111   if (temp_name == NULL) {
1112     _E("out of memory");
1113     return ES_R_ENOMEM;
1114   }
1115
1116   tmp = strrchr(temp_name, '.');
1117   if (tmp == NULL || strlen(tmp) == 0) {
1118     _E("invalid event name");
1119     FREE_AND_NULL(temp_name);
1120     return ES_R_EINVAL;
1121   }
1122   len = strlen(tmp);
1123   if (len <= 1 || len > 128) {
1124     _E("invalid length(%d) of user-defined name", len);
1125     FREE_AND_NULL(temp_name);
1126     return ES_R_EINVAL;
1127   }
1128   *tmp = '\0';
1129
1130   _D("app_id(%s), len(%zu)", app_id, strlen(app_id));
1131
1132   valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1;
1133   valid_name = (char *)calloc(1, valid_name_len);
1134   if (valid_name == NULL) {
1135     _E("memory alloc failed");
1136     FREE_AND_NULL(temp_name);
1137     return ES_R_ENOMEM;
1138   }
1139   snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id);
1140   _D("valid_name(%s)", valid_name);
1141
1142   if (strcmp(temp_name, valid_name) != 0) {
1143     _E("appid misamatch");
1144     retval = ES_R_EINVAL;
1145   }
1146
1147   FREE_AND_NULL(temp_name);
1148   FREE_AND_NULL(valid_name);
1149
1150   return retval;
1151 }
1152
1153 static const GDBusInterfaceVTable interface_vtable = {
1154   esd::module::DbusEventModule::HandleMethodCallCb,
1155   nullptr,
1156   nullptr
1157 };
1158
1159 void __esd_on_bus_acquired(GDBusConnection *connection,
1160     const gchar *name, gpointer user_data) {
1161   _I("bus acquired(%s)", name);
1162
1163   guint reg_id = 0;
1164   guint boot_id = 0;
1165   guint user_boot_id = 0;
1166   GError *error = NULL;
1167
1168   reg_id = g_dbus_connection_register_object(connection,
1169     ESD_OBJECT_PATH,
1170     introspection_data->interfaces[0],
1171     &interface_vtable,
1172     user_data, NULL, &error);
1173   if (reg_id == 0) {
1174     _E("g_dbus_connection_register_object error(%s)", error->message);
1175     g_error_free(error);
1176   }
1177
1178   boot_id = g_dbus_connection_signal_subscribe(connection,
1179       NULL,
1180       SYSTEMD_DBUS_IFACE_MANAGER,
1181       SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED,
1182       SYSTEMD_DBUS_PATH,
1183       NULL,
1184       G_DBUS_SIGNAL_FLAGS_NONE,
1185       __esd_signal_handler,
1186       NULL,
1187       NULL);
1188
1189   if (boot_id == 0)
1190     _E("g_dbus_connection_signal_subscribe() is failed.");
1191
1192   user_boot_id = g_dbus_connection_signal_subscribe(connection,
1193       NULL,
1194       SYSTEMD_DBUS_IFACE_MANAGER,
1195       SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED,
1196       SYSTEMD_DBUS_PATH,
1197       NULL,
1198       G_DBUS_SIGNAL_FLAGS_NONE,
1199       __esd_signal_handler,
1200       NULL,
1201       NULL);
1202
1203   if (user_boot_id == 0)
1204     _E("g_dbus_connection_signal_subscribe() is failed.");
1205 }
1206
1207 void __esd_on_name_acquired(GDBusConnection *connection,
1208     const gchar *name, gpointer user_data) {
1209   bundle *b;
1210
1211   __esd_check_trusted_events(connection, "ListNames");
1212   __esd_check_trusted_events(connection, "ListActivatableNames");
1213
1214   b = bundle_create();
1215   bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED);
1216   eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b);
1217   bundle_free(b);
1218
1219   esd::module::DbusEventModule* mod =
1220       static_cast<esd::module::DbusEventModule*>(user_data);
1221   mod->SetVconfHandler();
1222
1223   __esd_trusted_busname_print_items();
1224
1225   __esd_get_user_items(DEFAULT_USER);
1226
1227   __esd_dbus_name_monitor(connection);
1228 }
1229
1230 void __esd_on_name_lost(GDBusConnection *connection,
1231     const gchar *name, gpointer user_data) {
1232 }
1233
1234 void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event) {
1235   pkg_event->type = UNKNOWN;
1236   if (pkg_event->pkgid) {
1237     free(pkg_event->pkgid);
1238     pkg_event->pkgid = NULL;
1239   }
1240 }
1241
1242 int __esd_appcontrol_cb(const char *operation,
1243     const char *uri, const char *mime, void *data) {
1244   esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data;
1245   char *appid = NULL;
1246   char *pkgid = NULL;
1247   char *event_name = NULL;
1248   uid_t uid = 0;
1249
1250   if (cb_data == NULL) {
1251     _E("invalid data");
1252     return 0;
1253   }
1254   appid = cb_data->appid;
1255   pkgid = cb_data->pkgid;
1256   uid = cb_data->uid;
1257
1258   _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)",
1259     uid, appid, pkgid, operation, uri, mime);
1260
1261   if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) {
1262     if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) {
1263       event_name = strdup(&uri[8]);
1264       if (event_name) {
1265         _D("appid(%s), event_name(%s)", appid, event_name);
1266         if (!__esd_check_event_launch_support(event_name))
1267           _E("failed to add item (not support event)");
1268         else if (!esd::module::PrivilegeChecker::AppHasPrivilege(uid, std::string(appid), std::string(event_name)))
1269           _E("failed to add item (no privilege)");
1270         else if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1271           _E("failed to add item");
1272
1273       } else {
1274         _E("out of memory");
1275       }
1276     } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) {
1277       event_name = strdup(uri);
1278       if (event_name) {
1279         _D("appid(%s), event_name(%s)", appid, event_name);
1280         if (__esd_check_platform_cert(pkgid, uid)) {
1281           if (__esd_add_launch_item(uid, event_name, appid, pkgid))
1282             _E("failed to add item");
1283         }
1284       } else {
1285         _E("out of memory");
1286       }
1287     }
1288     FREE_AND_NULL(event_name);
1289   }
1290
1291   return 0;
1292 }
1293
1294 int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) {
1295   char *appid = NULL;
1296   char *pkgid = NULL;
1297   int ret = 0;
1298   uid_t *p_uid = NULL;
1299
1300   if (data == NULL) {
1301     _E("invalid data");
1302     return ES_R_ERROR;
1303   }
1304
1305   p_uid = (uid_t *)data;
1306
1307   ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
1308   if (ret < 0) {
1309     _E("failed to get appid");
1310     return ES_R_ERROR;
1311   }
1312
1313   ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
1314   if (ret < 0) {
1315     _E("failed to get appid");
1316     return ES_R_ERROR;
1317   }
1318
1319   esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)calloc(1, sizeof(esd_appctrl_cb_data));
1320
1321   if (cb_data == NULL) {
1322     _E("memory alloc failed");
1323     return ES_R_ENOMEM;
1324   }
1325   cb_data->appid = strdup(appid);
1326   if (cb_data->appid == NULL) {
1327     _E("out_of_memory");
1328     FREE_AND_NULL(cb_data);
1329     return ES_R_ENOMEM;
1330   }
1331   cb_data->pkgid = strdup(pkgid);
1332   if (cb_data->pkgid == NULL) {
1333     _E("out_of_memory");
1334     FREE_AND_NULL(cb_data->appid);
1335     FREE_AND_NULL(cb_data);
1336     return ES_R_ENOMEM;
1337   }
1338   cb_data->uid = *p_uid;
1339
1340   ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle,
1341     (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data);
1342
1343   FREE_AND_NULL(cb_data->pkgid);
1344   FREE_AND_NULL(cb_data->appid);
1345   FREE_AND_NULL(cb_data);
1346
1347   if (ret < 0) {
1348     _E("failed to get appcontrol info");
1349     return ES_R_ERROR;
1350   }
1351
1352   return ES_R_OK;
1353 }
1354
1355 int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id,
1356     const char *pkg_type, const char *pkgid, const char *key,
1357     const char *val, const void *pmsg, void *data) {
1358   esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data;
1359   pkgmgrinfo_pkginfo_h handle = NULL;
1360   int ret = 0;
1361
1362   _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)",
1363     target_uid, req_id, pkg_type, pkgid, key, val);
1364
1365   if (strncmp(key, "start", strlen(key)) == 0) {
1366     if (strcmp(val, "install") == 0) {
1367       _D("install start");
1368       pkg_event->type = INSTALL;
1369     } else if (strcmp(val, "uninstall") == 0) {
1370       _D("unistall start");
1371       pkg_event->type = UNINSTALL;
1372     } else if (strcmp(val, "update") == 0) {
1373       _D("update start");
1374       pkg_event->type = UPDATE;
1375     } else {
1376       _D("val(%s) start", val);
1377       __esd_pkgmgr_event_free(pkg_event);
1378     }
1379   } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) {
1380     if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) {
1381       _D("install end (ok)");
1382       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle);
1383       if (ret < 0) {
1384         _E("failed to get pkginfo");
1385         __esd_pkgmgr_event_free(pkg_event);
1386         return 0;
1387       }
1388       ret = pkgmgrinfo_appinfo_get_usr_list(handle,
1389         PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid);
1390       if (ret < 0) {
1391         _E("failed to get appinfo");
1392         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1393         __esd_pkgmgr_event_free(pkg_event);
1394         return 0;
1395       }
1396       ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1397       if (ret < 0) {
1398         _E("failed to destroy pkginfo");
1399         __esd_pkgmgr_event_free(pkg_event);
1400         return 0;
1401       }
1402     } else if (pkg_event->type == UNINSTALL) {
1403       _D("uninstall end (ok)");
1404       __esd_launch_table_remove_items(target_uid, pkgid);
1405       __esd_launch_table_print_items();
1406     }
1407     __esd_pkgmgr_event_free(pkg_event);
1408   } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) {
1409     _E("pkg_event(%d) falied", pkg_event->type);
1410     __esd_pkgmgr_event_free(pkg_event);
1411   } else {
1412     if (strcmp(key, "install_percent") != 0)
1413       __esd_pkgmgr_event_free(pkg_event);
1414   }
1415
1416   return 0;
1417 }
1418
1419 void __esd_remove_esd_list_item(gpointer data, gpointer user_data) {
1420   esd_list_item_s *item = (esd_list_item_s *)data;
1421
1422   free(item->app_id);
1423   free(item->pkg_id);
1424 }
1425
1426 }  // namespace
1427
1428 namespace esd::module {
1429
1430 bool DbusEventModule::Startup(api::ToolBox* tools) {
1431   tools_ = tools;
1432   if (!Init())
1433     return false;
1434   return BeforeLoop();
1435 }
1436
1437 void DbusEventModule::Shutdown() {
1438   Fini();
1439 }
1440
1441 bool DbusEventModule::Init() {
1442   int req_id = 0;
1443   int ret = 0;
1444   pkgmgr_client *client;
1445   esd_pkgmgr_event *pkg_event;
1446
1447   auto checker = std::make_unique<PrivilegeChecker>();
1448   client = pkgmgr_client_new(PC_LISTENING);
1449   if (client == NULL) {
1450     _E("set pkgmgr client failed");
1451     return false;
1452   }
1453
1454   pkg_event = (esd_pkgmgr_event *)calloc(1, sizeof(esd_pkgmgr_event));
1455   if (pkg_event == NULL) {
1456     _E("memory alloc failed");
1457     ret = pkgmgr_client_free(client);
1458     if (ret != PKGMGR_R_OK)
1459       _E("pkgmgr_client_free failed(%d)", ret);
1460     return false;
1461   }
1462
1463   req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event);
1464   if (req_id < 0) {
1465     _E("pkgmgr client listen failed");
1466     ret = pkgmgr_client_free(client);
1467     if (ret != PKGMGR_R_OK)
1468       _E("pkgmgr_client_free failed(%d)", ret);
1469     free(pkg_event);
1470     return false;
1471   }
1472
1473   s_info.client = client;
1474   checker_ = std::move(checker);
1475
1476   _I("esd init done");
1477
1478   return true;
1479 }
1480
1481 void DbusEventModule::Fini() {
1482   gpointer key;
1483   gpointer value;
1484   GHashTableIter iter;
1485   trusted_item *item;
1486   event_launch_item *el_item;
1487   int ret = 0;
1488   earlier_item *er_item;
1489
1490   _D("esd finalize");
1491
1492   if (trusted_busname_table) {
1493     g_hash_table_iter_init(&iter, trusted_busname_table);
1494     while (g_hash_table_iter_next(&iter, &key, &value)) {
1495       item = (trusted_item *)value;
1496       if (item) {
1497         free(item->app_id);
1498         free(item->bus_name);
1499         free(item);
1500       } else {
1501         _E("item is null");
1502       }
1503       g_hash_table_iter_remove(&iter);
1504     }
1505     g_hash_table_unref(trusted_busname_table);
1506   }
1507
1508   if (earlier_event_table) {
1509     g_hash_table_iter_init(&iter, earlier_event_table);
1510     while (g_hash_table_iter_next(&iter, &key, &value)) {
1511       er_item = (earlier_item *)value;
1512       if (er_item) {
1513         eventsystem_unregister_event(er_item->reg_id);
1514         free(er_item->event_name);
1515         bundle_free(er_item->earlier_data);
1516         free(er_item);
1517       } else {
1518         _E("ealier item is NULL");
1519       }
1520       g_hash_table_iter_remove(&iter);
1521     }
1522     g_hash_table_unref(earlier_event_table);
1523   }
1524
1525   g_hash_table_destroy(user_last_event_table);
1526
1527   if (event_launch_table) {
1528     g_hash_table_iter_init(&iter, event_launch_table);
1529     while (g_hash_table_iter_next(&iter, &key, &value)) {
1530       el_item = (event_launch_item *)value;
1531       if (el_item) {
1532         eventsystem_unregister_event(el_item->reg_id);
1533         free(el_item->event_name);
1534         g_list_foreach(el_item->app_list_evtlaunch,
1535           __esd_remove_esd_list_item, NULL);
1536         g_list_free(el_item->app_list_evtlaunch);
1537         free(el_item);
1538       } else {
1539         _E("item is NULL");
1540       }
1541       g_hash_table_iter_remove(&iter);
1542     }
1543     g_hash_table_unref(event_launch_table);
1544   }
1545
1546   if (introspection_data)
1547     g_dbus_node_info_unref(introspection_data);
1548
1549   if (s_info.client) {
1550     ret = pkgmgr_client_free(s_info.client);
1551     if (ret != PKGMGR_R_OK)
1552       _E("pkgmgr_client_free failed(%d)", ret);
1553   }
1554
1555   checker_->Reset();
1556   _D("esd finalize end");
1557 }
1558
1559 bool DbusEventModule::BeforeLoop() {
1560   int ret = 0;
1561   GError *error = NULL;
1562   guint owner_id = 0;
1563
1564   guint subscription_id = 0;
1565   int i;
1566   int size;
1567   char *event_name;
1568   int fd;
1569   int val;
1570   int status;
1571   int charger_status;
1572   int charge_now;
1573   earlier_item *item;
1574
1575   earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal);
1576   user_last_event_table = g_hash_table_new_full(g_str_hash,
1577       g_str_equal, NULL, (GDestroyNotify)free_saved_event);
1578
1579   _I("register events for earlier_data");
1580   size = sizeof(earlier_event_list)/sizeof(*earlier_event_list);
1581   for (i = 0; i < size; i++) {
1582     event_name = (char *)earlier_event_list[i];
1583     _I("event_name(%s)", event_name);
1584
1585     item = (earlier_item *)calloc(1, sizeof(earlier_item));
1586     if (item == NULL) {
1587       _E("memery alloc failed");
1588       return false;
1589     }
1590     item->event_name = strdup(event_name);
1591     if (item->event_name == NULL) {
1592       _E("out of memory");
1593       free(item);
1594       return false;
1595     }
1596
1597     /* set initial data */
1598     if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) {
1599       fd = open(ESD_BOOT_COMPLETED, O_RDONLY);
1600       if (fd < 0) {
1601         _D("open file error(%d)", fd);
1602       } else {
1603         item->earlier_data = bundle_create();
1604         bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED,
1605           EVT_VAL_BOOT_COMPLETED_TRUE);
1606         close(fd);
1607       }
1608     } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) {
1609       ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val);
1610       if (ret != VCONF_OK) {
1611         _E("failed to get power_off status (%d)", ret);
1612       } else {
1613         if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT ||
1614           val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
1615           /* power-off requested */
1616           item->earlier_data = bundle_create();
1617           bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN,
1618             EVT_VAL_SYSTEM_SHUTDOWN_TRUE);
1619         }
1620       }
1621     } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) {
1622       ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status);
1623       if (ret != VCONF_OK) {
1624         _E("failed to get low_memory status (%d)", ret);
1625       } else {
1626         item->earlier_data = bundle_create();
1627         if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
1628           bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1629             EVT_VAL_MEMORY_SOFT_WARNING);
1630         else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING)
1631           bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1632             EVT_VAL_MEMORY_HARD_WARNING);
1633         else
1634           bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY,
1635             EVT_VAL_MEMORY_NORMAL);
1636       }
1637     } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) {
1638       ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status);
1639       if (ret != VCONF_OK) {
1640         _E("failed to get charger_status (%d)", ret);
1641       } else {
1642         ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now);
1643         if (ret != VCONF_OK)
1644           _E("failed to get charge_now (%d)", ret);
1645       }
1646
1647       if (ret == VCONF_OK) {
1648         item->earlier_data = bundle_create();
1649         if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
1650           if (charge_now == 0) {
1651             bundle_add_str(item->earlier_data,
1652               EVT_KEY_BATTERY_CHARGER_STATUS,
1653               EVT_VAL_BATTERY_CHARGER_DISCHARGING);
1654           } else {
1655             bundle_add_str(item->earlier_data,
1656               EVT_KEY_BATTERY_CHARGER_STATUS,
1657               EVT_VAL_BATTERY_CHARGER_CHARGING);
1658           }
1659         } else {
1660           bundle_add_str(item->earlier_data,
1661             EVT_KEY_BATTERY_CHARGER_STATUS,
1662             EVT_VAL_BATTERY_CHARGER_DISCONNECTED);
1663         }
1664       }
1665     }
1666
1667     eventsystem_register_event(event_name, &subscription_id,
1668       (eventsystem_handler)__esd_event_handler, NULL);
1669     if (subscription_id == 0) {
1670       _E("signal subscription error, event_name(%s)", event_name);
1671       if (item->earlier_data)
1672         bundle_free(item->earlier_data);
1673       free(item->event_name);
1674       free(item);
1675
1676       return false;
1677     } else {
1678       item->reg_id = subscription_id;
1679     }
1680
1681     g_hash_table_insert(earlier_event_table, event_name, item);
1682   }
1683
1684   __esd_earlier_table_print_items();
1685
1686   event_launch_table = g_hash_table_new(g_str_hash, g_str_equal);
1687   trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal);
1688
1689   /* gdbus setup for method call */
1690   introspection_data = g_dbus_node_info_new_for_xml(INTROSPECTION_XML, &error);
1691   if (!introspection_data) {
1692     _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
1693     g_error_free(error);
1694     return false;
1695   }
1696
1697   owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1698     ESD_BUS_NAME,
1699     G_BUS_NAME_OWNER_FLAGS_NONE,
1700     __esd_on_bus_acquired,
1701     __esd_on_name_acquired,
1702     __esd_on_name_lost,
1703     this, NULL);
1704   if (!owner_id) {
1705     _E("g_bus_own_name error");
1706     g_dbus_node_info_unref(introspection_data);
1707     return false;
1708   }
1709
1710   _I("esd before_loop done");
1711
1712   return true;
1713 }
1714
1715 void DbusEventModule::SetVconfHandler() {
1716   vconf_handler_ = std::make_unique<VconfEventHandler>();
1717   vconf_handler_->SetDefaultEvents();
1718 }
1719
1720 void DbusEventModule::HandleMethodCallCb(GDBusConnection *connection,
1721   const gchar *sender, const gchar *object_path,
1722   const gchar *interface_name, const gchar *method_name,
1723   GVariant *parameters, GDBusMethodInvocation *invocation,
1724   gpointer user_data) {
1725
1726   static std::map<std::string,
1727       std::function<void (DbusEventModule&, GDBusConnection*,
1728           const gchar*, GVariant*, GDBusMethodInvocation*)>> dispatcher = {
1729             { "CheckSenderValidation", &DbusEventModule::CheckSenderValidMethodCall },
1730             { "GetTrustedPeerList", &DbusEventModule::GetTrustedPeerMethodCall },
1731             { "SetupTrustedPeer", &DbusEventModule::SetupTrustedPeerMethodCall },
1732             { "CheckPrivilegeValidation", &DbusEventModule::CheckPrivilegeValidMethodCall },
1733             { "CheckUserSendValidation", &DbusEventModule::CheckSendEventValidMethodCall },
1734             { "GetEarlierData", &DbusEventModule::GetEarlierDataMethodCall },
1735             { "KeepLastData", &DbusEventModule::KeepLastDataMethodCall },
1736             { "CheckLastData", &DbusEventModule::CheckLastDataMethodCall },
1737             { "LaunchOnEventFromUserEvent", &DbusEventModule::LaunchOnEventFromUserEventMethodCall },
1738             { "CionGetUuid", &DbusEventModule::GetUuidMethodCall },
1739             { "CionSetDisplayName", &DbusEventModule::SetDisplayNameMethodCall },
1740             { "CionGetDisplayName", &DbusEventModule::GetDisplayNameMethodCall },
1741             { "CionSetEnabled", &DbusEventModule::SetEnabledMethodCall },
1742             { "CionGetEnabled", &DbusEventModule::GetEnabledMethodCall }
1743           };
1744
1745   if (dispatcher.find(method_name) == dispatcher.end())
1746     return;
1747
1748   auto* mod = reinterpret_cast<esd::module::DbusEventModule*>(user_data);
1749   dispatcher[method_name](*mod, connection, sender, parameters, invocation);
1750 }
1751
1752 std::string DbusEventModule::GetSenderAppId(GDBusConnection* connection,
1753     const gchar* sender) {
1754   int sender_pid = __get_sender_pid(connection, sender);
1755   char app_id[128] = { 0, };
1756   if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) {
1757     _E("failed to get appid by pid");
1758     return "";
1759   }
1760
1761   return app_id;
1762 }
1763
1764 void DbusEventModule::CheckSendEventValidMethodCall(GDBusConnection* connection,
1765     const gchar* sender, GVariant* parameters,
1766     GDBusMethodInvocation* invocation) {
1767   GVariant *param = NULL;
1768   int result = 0;
1769   char *event_name = NULL;
1770   char app_id[128] = {0, };
1771   int sender_pid = 0;
1772   uid_t sender_uid = 0;
1773
1774   g_variant_get(parameters, "(&s)", &event_name);
1775   _D("event_name(%s)", event_name);
1776
1777   sender_pid = __get_sender_pid(connection, sender);
1778   sender_uid = (uid_t)__get_sender_uid(connection, sender);
1779   if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1780     result = ES_R_ERROR;
1781   } else {
1782     if (check_user_event_sender_valid(event_name, app_id) < 0) {
1783       _E("invalid sender");
1784       result = ES_R_EINVAL;
1785     } else {
1786       result = 1;
1787     }
1788   }
1789
1790   param = g_variant_new("(i)", result);
1791   _D("event_name(%s), result(%d)", event_name, result);
1792   g_dbus_method_invocation_return_value(invocation, param);
1793 }
1794
1795 void DbusEventModule::CheckSenderValidMethodCall(GDBusConnection* connection,
1796     const gchar* sender, GVariant* parameters,
1797     GDBusMethodInvocation* invocation) {
1798   GVariant *param = NULL;
1799   int result = 0;
1800   char *event_name = NULL;
1801   char app_id[128] = {0, };
1802   int event_sender_pid = 0;
1803   uid_t sender_uid = 0;
1804
1805   g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name);
1806   _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name);
1807
1808   sender_uid = (uid_t)__get_sender_uid(connection, sender);
1809   if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1810     result = ES_R_ERROR;
1811   } else {
1812     if (check_user_event_sender_valid(event_name, app_id) < 0) {
1813       _E("invalid sender");
1814       result = ES_R_EINVAL;
1815     } else {
1816       result = 1;
1817     }
1818   }
1819
1820   param = g_variant_new("(is)", result, app_id);
1821   _D("event_name(%s), result(%d)", event_name, result);
1822   g_dbus_method_invocation_return_value(invocation, param);
1823 }
1824
1825 void DbusEventModule::GetTrustedPeerMethodCall(GDBusConnection* connection,
1826     const gchar* sender, GVariant* parameters,
1827     GDBusMethodInvocation* invocation) {
1828   GVariant *param = NULL;
1829   int result = 0;
1830   GVariantBuilder *builder = NULL;
1831   GHashTableIter iter;
1832   gpointer key, value;
1833   char *event_name = NULL;
1834   char app_id[128] = {0, };
1835   int sender_pid = 0;
1836   uid_t sender_uid = 0;
1837   int ret = 0;
1838   uid_t uid = 0;
1839   char *_appid = NULL;
1840   char *_busname = NULL;
1841   trusted_item *item;
1842
1843   g_variant_get(parameters, "(&s)", &event_name);
1844   _D("event_name(%s)", event_name);
1845
1846   sender_pid = __get_sender_pid(connection, sender);
1847   sender_uid = (uid_t)__get_sender_uid(connection, sender);
1848   if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1849     result = ES_R_ERROR;
1850   } else {
1851     builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1852
1853     g_hash_table_iter_init(&iter, trusted_busname_table);
1854     while (g_hash_table_iter_next(&iter, &key, &value)) {
1855       item = (trusted_item *)value;
1856       uid = item->uid;
1857       _appid = item->app_id;
1858       _busname = item->bus_name;
1859
1860       if (uid != GLOBAL_USER && uid != sender_uid)
1861         continue;
1862
1863       ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id);
1864       if (ret == ES_R_OK)
1865         g_variant_builder_add(builder, "s", _busname);
1866     }
1867
1868     result = 1;
1869   }
1870
1871   param = g_variant_new("(ias)", result, builder);
1872   _D("result(%d)", result);
1873   g_dbus_method_invocation_return_value(invocation, param);
1874   if (builder)
1875     g_variant_builder_unref(builder);
1876 }
1877
1878 void DbusEventModule::SetupTrustedPeerMethodCall(GDBusConnection* connection,
1879     const gchar* sender, GVariant* parameters,
1880     GDBusMethodInvocation* invocation) {
1881   GVariant *param = NULL;
1882   int result = 0;
1883   char *event_name = NULL;
1884   char *destination_name = NULL;
1885   char app_id[128] = {0, };
1886   int sender_pid = 0;
1887   uid_t sender_uid = 0;
1888   int ret = 0;
1889
1890   g_variant_get(parameters, "(&s&s)", &event_name, &destination_name);
1891   _D("event_name(%s), destination_name(%s)", event_name, destination_name);
1892
1893   if (destination_name && destination_name[0] != '\0') {
1894     sender_pid = __get_sender_pid(connection, sender);
1895     sender_uid = (uid_t)__get_sender_uid(connection, sender);
1896     if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1897       result = ES_R_ERROR;
1898     } else {
1899       ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name,
1900         sender_pid);
1901       if (ret < 0) {
1902         _E("failed to add trusted busname item");
1903         result = ES_R_ERROR;
1904       } else {
1905         result = 1;
1906       }
1907     }
1908   } else {
1909     _E("invalid destination name");
1910     result = ES_R_ERROR;
1911   }
1912
1913   param = g_variant_new("(i)", result);
1914   _D("event_name(%s), result(%d)", event_name, result);
1915   g_dbus_method_invocation_return_value(invocation, param);
1916 }
1917
1918 void DbusEventModule::CheckPrivilegeValidMethodCall(GDBusConnection* connection,
1919     const gchar* sender, GVariant* parameters,
1920     GDBusMethodInvocation* invocation) {
1921   GVariant *param = NULL;
1922   int result = 1;
1923   char *event_name = NULL;
1924   char app_id[128] = {0, };
1925   int sender_pid = 0;
1926   uid_t sender_uid = 0;
1927   std::string privilege_name;
1928
1929   g_variant_get(parameters, "(&s)", &event_name);
1930   privilege_name = checker_->CheckPrivilegeName(std::string(event_name));
1931   _D("event_name(%s), privilege_name(%s)", event_name, privilege_name.c_str());
1932
1933   if (!privilege_name.empty()) {
1934     sender_pid = __get_sender_pid(connection, sender);
1935     sender_uid = (uid_t)__get_sender_uid(connection, sender);
1936     if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) {
1937       result = ES_R_ERROR;
1938     } else {
1939       if(checker_->Check(connection, sender, sender_pid, privilege_name))
1940         result = 1;
1941       else
1942         result = ES_R_EINVAL;
1943     }
1944   }
1945
1946   param = g_variant_new("(i)", result);
1947   _D("event_name(%s), result(%d)", event_name, result);
1948   g_dbus_method_invocation_return_value(invocation, param);
1949 }
1950
1951 void DbusEventModule::GetEarlierDataMethodCall(GDBusConnection* connection,
1952     const gchar* sender, GVariant* parameters,
1953     GDBusMethodInvocation* invocation) {
1954   GVariant *param = NULL;
1955   int result = ES_R_ERROR;
1956   char *event_name = NULL;
1957   bundle *b = NULL;
1958   bundle_raw *raw = NULL;
1959   int len = 0;
1960   earlier_item *item;
1961
1962   g_variant_get(parameters, "(&s)", &event_name);
1963   _D("event_name(%s)", event_name);
1964
1965   item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name);
1966   if (item != NULL) {
1967     if (item->earlier_data) {
1968       b = bundle_dup(item->earlier_data);
1969       bundle_add_str(b, "is_earlier_data", "true");
1970       result = ES_R_OK;
1971     }
1972   }
1973
1974   if (result == ES_R_ERROR)
1975     b = bundle_create();
1976
1977   bundle_encode(b, &raw, &len);
1978   bundle_free(b);
1979
1980   param = g_variant_new("(iis)", result, len, raw);
1981
1982   _D("result(%d), len(%d)", result, len);
1983   g_dbus_method_invocation_return_value(invocation, param);
1984
1985   bundle_free_encoded_rawdata(&raw);
1986 }
1987
1988 void DbusEventModule::KeepLastDataMethodCall(GDBusConnection* connection,
1989     const gchar* sender, GVariant* parameters,
1990     GDBusMethodInvocation* invocation) {
1991   GVariant *param;
1992   int result = ES_R_OK;
1993   char *event_name;
1994   char *own_name;
1995   char *key;
1996   char app_id[128];
1997   int sender_pid;
1998   uid_t sender_uid;
1999   struct __last_event_item *item;
2000
2001   g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
2002
2003   if (!event_name || !own_name) {
2004     result = ES_R_ERROR;
2005     _E("invalid event_name and own_name");
2006     goto out;
2007   }
2008
2009   sender_pid = __get_sender_pid(connection, sender);
2010   sender_uid = (uid_t)__get_sender_uid(connection, sender);
2011   if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
2012         sizeof(app_id)) < 0) {
2013     _E("failed to get appid by pid");
2014     result = ES_R_ERROR;
2015     goto out;
2016   }
2017
2018   key = (char *)malloc(sizeof(event_name) + 10);
2019   if (!key) {
2020     result = ES_R_ENOMEM;
2021     _E("out of memory");
2022     goto out;
2023   }
2024
2025   snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
2026   item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
2027       key);
2028   if (!item) {
2029     item = (struct __last_event_item *)calloc(1, sizeof(*item));
2030     if (!item) {
2031       result = ES_R_ERROR;
2032       goto out;
2033     }
2034     item->key = key;
2035     item->event_name = strdup(event_name);
2036     item->own_name = strdup(own_name);
2037     item->uid = sender_uid;
2038     item->app_id = strdup(app_id);
2039     g_hash_table_insert(user_last_event_table,
2040         item->key, item);
2041   } else {
2042     free(item->own_name);
2043     item->own_name = strdup(own_name);
2044   }
2045
2046 out:
2047   param = g_variant_new("(i)", result);
2048
2049   g_dbus_method_invocation_return_value(invocation, param);
2050 }
2051
2052 void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection,
2053     const gchar* sender, GVariant* parameters,
2054     GDBusMethodInvocation* invocation) {
2055   GVariant *param;
2056   int result = ES_R_OK;
2057   char *event_name;
2058   char *own_name;
2059   char *key;
2060   char app_id[128];
2061   int sender_pid;
2062   uid_t sender_uid;
2063   struct __last_event_item *item;
2064
2065   g_variant_get(parameters, "(&s&s)", &event_name, &own_name);
2066
2067   if (!event_name || !own_name) {
2068     result = ES_R_ERROR;
2069     _E("invalid event_name and own_name");
2070     goto out;
2071   }
2072
2073   sender_pid = __get_sender_pid(connection, sender);
2074   sender_uid = (uid_t)__get_sender_uid(connection, sender);
2075   if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
2076         sizeof(app_id)) < 0) {
2077     result = ES_R_ERROR;
2078     _E("failed to get appid by pid");
2079     goto out;
2080   }
2081
2082   key = (char *)malloc(sizeof(event_name) + 10);
2083   if (!key) {
2084     result = ES_R_ENOMEM;
2085     _E("out of memory");
2086     goto out;
2087   }
2088
2089   snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid);
2090   item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table,
2091       key);
2092   free(key);
2093   if (item) {
2094     GVariant *gv;
2095     bundle *b;
2096     bundle_raw *raw;
2097     int len;
2098     int ret;
2099     GError *error = NULL;
2100
2101     b = bundle_create();
2102     if (!b) {
2103       result = ES_R_ERROR;
2104       goto out;
2105     }
2106     bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name);
2107     bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name);
2108     if (__esd_check_certificate_match(item->uid, item->app_id,
2109         sender_uid, app_id) == ES_R_OK)
2110       bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true");
2111     else
2112       bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false");
2113
2114     bundle_encode(b, &raw, &len);
2115     gv  = g_variant_new("(us)", len, raw);
2116     ret = g_dbus_connection_emit_signal(connection,
2117         item->own_name,
2118         SYS_EVENT_OBJ_PATH,
2119         SYS_EVENT_NAME_PREFIX,
2120         REQUEST_LAST_DATA,
2121         gv,
2122         &error);
2123     if (ret == FALSE) {
2124       _E("Unable to emit signal: %s", error->message);
2125       g_error_free(error);
2126     }
2127     bundle_free_encoded_rawdata(&raw);
2128     bundle_free(b);
2129   }
2130
2131 out:
2132   param = g_variant_new("(i)", result);
2133
2134   g_dbus_method_invocation_return_value(invocation, param);
2135 }
2136
2137 void DbusEventModule::LaunchOnEventFromUserEventMethodCall(GDBusConnection* connection,
2138     const gchar* sender, GVariant* parameters,
2139     GDBusMethodInvocation* invocation) {
2140   GVariant *param;
2141   int result = ES_R_OK;
2142   int len;
2143   gboolean trusted;
2144   int sender_pid;
2145   uid_t sender_uid;
2146   char *event_name;
2147   char app_id[128];
2148   char *buf;
2149   bundle *b;
2150
2151   g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted);
2152
2153   if (!event_name) {
2154     result = ES_R_ERROR;
2155     _E("invalid event_name");
2156     goto out;
2157   }
2158
2159   sender_pid = __get_sender_pid(connection, sender);
2160   sender_uid = (uid_t)__get_sender_uid(connection, sender);
2161   if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id,
2162         sizeof(app_id)) < 0) {
2163     _E("failed to get appid by pid");
2164     result = ES_R_ERROR;
2165     goto out;
2166   }
2167
2168   b = bundle_decode((bundle_raw *)buf, len);
2169   if (b == NULL) {
2170     _E("Out of memory");
2171     result = ES_R_ENOMEM;
2172     goto out;
2173   }
2174
2175   __esd_launch_event_handler(event_name, b, true, trusted,
2176       sender_uid, app_id, NULL);
2177
2178   bundle_free(b);
2179
2180 out:
2181   param = g_variant_new("(i)", result);
2182
2183   g_dbus_method_invocation_return_value(invocation, param);
2184 }
2185
2186 void DbusEventModule::GetUuidMethodCall(GDBusConnection* connection,
2187     const gchar* sender, GVariant* parameters,
2188     GDBusMethodInvocation* invocation) {
2189   GVariant* param = nullptr;
2190   int result = ES_R_OK;
2191   std::optional<std::string> uuid;
2192
2193   std::string app_id = GetSenderAppId(connection, sender);
2194   if (app_id.empty()) {
2195     param = g_variant_new("(is)", ES_R_ERROR, "");
2196     g_dbus_method_invocation_return_value(invocation, param);
2197     return;
2198   }
2199
2200   if (tools_->GetMethodBroker()
2201       .Invoke<const std::string&, std::optional<std::string>&>(
2202           "Cion.GetUuidWithGenerate", app_id, uuid)) {
2203     param = g_variant_new("(is)", ES_R_OK, (*uuid).c_str());
2204   } else {
2205     result = ES_R_ERROR;
2206   }
2207
2208   if (param == nullptr)
2209     param = g_variant_new("(is)", result, "");
2210
2211   g_dbus_method_invocation_return_value(invocation, param);
2212 }
2213
2214 void DbusEventModule::SetDisplayNameMethodCall(GDBusConnection* connection,
2215     const gchar* sender, GVariant* parameters,
2216     GDBusMethodInvocation* invocation) {
2217   GVariant* param = nullptr;
2218   int result = ES_R_OK;
2219   char* display_name = nullptr;
2220   char* service_name = nullptr;
2221   int ret = 0;
2222
2223   std::string app_id = GetSenderAppId(connection, sender);
2224   if (app_id.empty()) {
2225     param = g_variant_new("(i)", ES_R_ERROR);
2226     g_dbus_method_invocation_return_value(invocation, param);
2227     return;
2228   }
2229
2230   g_variant_get(parameters, "(&s&s)", &service_name, &display_name);
2231
2232   if (!tools_->GetMethodBroker()
2233       .Invoke<const std::string&, const std::string&, const std::string&, int&>(
2234           "Cion.SetDisplayName", app_id, service_name, display_name, ret)) {
2235     result = ES_R_ERROR;
2236   }
2237
2238   if (ret != 0)
2239     result = ES_R_ERROR;
2240
2241   param = g_variant_new("(i)", result);
2242   g_dbus_method_invocation_return_value(invocation, param);
2243 }
2244
2245 void DbusEventModule::GetDisplayNameMethodCall(GDBusConnection* connection,
2246     const gchar* sender, GVariant* parameters,
2247     GDBusMethodInvocation* invocation) {
2248   GVariant* param = nullptr;
2249   int result = ES_R_OK;
2250   char* service_name = nullptr;
2251   std::string display_name;
2252   int ret = -1;
2253
2254   std::string app_id = GetSenderAppId(connection, sender);
2255   if (app_id.empty()) {
2256     param = g_variant_new("(is)", ES_R_ERROR, "");
2257     g_dbus_method_invocation_return_value(invocation, param);
2258     return;
2259   }
2260
2261   g_variant_get(parameters, "(&s)", &service_name);
2262
2263   if (tools_->GetMethodBroker()
2264       .Invoke<const std::string&, const std::string&, std::string&, int&>(
2265           "Cion.GetDisplayName", app_id, service_name, display_name,
2266           ret)) {
2267     if (ret == 0)
2268       param = g_variant_new("(is)", result, display_name);
2269   } else {
2270     result = ES_R_ERROR;
2271   }
2272
2273   if (param == nullptr)
2274     param = g_variant_new("(is)", result, "");
2275
2276   g_dbus_method_invocation_return_value(invocation, param);
2277 }
2278
2279 void DbusEventModule::SetEnabledMethodCall(GDBusConnection* connection,
2280     const gchar* sender, GVariant* parameters,
2281     GDBusMethodInvocation* invocation) {
2282   GVariant* param = nullptr;
2283   int result = ES_R_OK;
2284   gboolean enabled;
2285   char* service_name = nullptr;
2286   int ret = -1;
2287
2288   std::string app_id = GetSenderAppId(connection, sender);
2289   if (app_id.empty()) {
2290     param = g_variant_new("(i)", ES_R_ERROR);
2291     g_dbus_method_invocation_return_value(invocation, param);
2292     return;
2293   }
2294
2295   g_variant_get(parameters, "(&sb)", &service_name, &enabled);
2296
2297   if (!tools_->GetMethodBroker()
2298       .Invoke<const std::string&, const std::string&, bool, int&>(
2299           "Cion.SetEnabled", app_id, service_name, (bool)enabled, ret)) {
2300     result = ES_R_ERROR;
2301   }
2302
2303   if (ret != 0)
2304     result = ES_R_ERROR;
2305
2306   param = g_variant_new("(i)", result);
2307   g_dbus_method_invocation_return_value(invocation, param);
2308 }
2309
2310 void DbusEventModule::GetEnabledMethodCall(GDBusConnection* connection,
2311     const gchar* sender, GVariant* parameters,
2312     GDBusMethodInvocation* invocation) {
2313   GVariant* param = nullptr;
2314   int result = ES_R_OK;
2315   char* service_name = nullptr;
2316   bool enabled = false;
2317   int ret = -1;
2318
2319   std::string app_id = GetSenderAppId(connection, sender);
2320   if (app_id.empty()) {
2321     param = g_variant_new("(ib)", ES_R_ERROR, false);
2322     g_dbus_method_invocation_return_value(invocation, param);
2323     return;
2324   }
2325
2326   g_variant_get(parameters, "(&s)", &service_name);
2327   if (!tools_->GetMethodBroker()
2328       .Invoke<const std::string&, const std::string&, bool&, int&>(
2329           "Cion.GetEnabled", app_id, service_name, enabled, ret)) {
2330     result = ES_R_ERROR;
2331   } else if (ret != 0) {
2332     result = ES_R_ERROR;
2333   } else {
2334     param = g_variant_new("(ib)", result, enabled);
2335   }
2336
2337   if (param == nullptr)
2338     param = g_variant_new("(ib)", result, false);
2339
2340   g_dbus_method_invocation_return_value(invocation, param);
2341 }
2342
2343
2344 }  // namespace esd::module