add eventsystem_keep_last_event_data api 21/77421/9 accepted/tizen/3.0/common/20161114.105413 accepted/tizen/3.0/ivi/20161011.044254 accepted/tizen/3.0/mobile/20161015.033446 accepted/tizen/3.0/tv/20161016.004850 accepted/tizen/3.0/wearable/20161015.083157 accepted/tizen/common/20160809.184029 accepted/tizen/ivi/20160809.232629 accepted/tizen/mobile/20160809.232408 accepted/tizen/tv/20160809.232519 accepted/tizen/wearable/20160809.232724 submit/tizen/20160809.011327 submit/tizen/20160809.051427 submit/tizen_3.0_common/20161104.104000 submit/tizen_3.0_ivi/20161010.000003 submit/tizen_3.0_mobile/20161015.000003 submit/tizen_3.0_tv/20161015.000003 submit/tizen_3.0_wearable/20161015.000003
authorJiwoong Im <jiwoong.im@samsung.com>
Wed, 29 Jun 2016 13:49:14 +0000 (22:49 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Fri, 5 Aug 2016 07:41:28 +0000 (16:41 +0900)
- To keep last event data for future event receiver

Change-Id: Ib7b72fc44977a7f61c9ec6cb6011a03d181d7e71
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
include/eventsystem.h
include/eventsystem_internal.h
src/eventsystem.c

index e6e1467..90cbb79 100644 (file)
@@ -161,6 +161,10 @@ API int eventsystem_send_system_event(const char *event_name, bundle *data);
  */
 API int eventsystem_request_sending_system_event(const char *event_name, bundle *data);
 
+/**
+ * function : Request to keep last event data
+ */
+API int eventsystem_keep_last_event_data(const char *event_name);
 
 #ifdef __cplusplus
 }
index 154e2cb..ccbc2de 100644 (file)
@@ -39,6 +39,13 @@ extern "C" {
 #define EVT_VAL_ESD_STARTED "started"
 #define EVT_VAL_ESD_STOPPED "stopped"
 
+/** esd : for sending saved event date request */
+#define SYS_EVENT_REQUEST_LAST_DATA "tizen.system.event.request_last_data"
+/* key */
+#define EVT_KEY_KEPT_EVENT_NAME "kept_event_name"
+#define EVT_KEY_KEPT_OWN_NAME "kept_own_name"
+#define EVT_KEY_KEPT_IS_TRUSTED "kept_is_trusted"
+
 /** battery : charger status */
 #define SYS_EVENT_BATTERY_CHARGER_STATUS "tizen.system.event.battery_charger_status"
 /* key */
index 99d72c1..963e974 100644 (file)
@@ -64,6 +64,13 @@ static GList *system_event_list;
 static int _initialized;
 static GHashTable *check_tbl;
 static GHashTable *filter_tbl;
+static GHashTable *last_data_tbl;
+
+struct last_data_item {
+       char *event_name;
+       GVariant *param;
+       GVariant *trusted_param;
+};
 
 typedef struct eventmap {
        char *event_name;
@@ -85,6 +92,7 @@ typedef struct eventinfo {
        char *object_path;
        char *member_name;
        bool is_user_event;
+       bool is_trusted;
        bundle *event_data;
 } eventinfo_s;
 
@@ -843,14 +851,14 @@ static int __eventsystem_send_event(GDBusConnection *conn, eventinfo_s *evti, bu
        _D("object_path(%s)", evti->object_path);
        _D("member_name(%s)", evti->member_name);
 
-       bundle_free_encoded_rawdata(&raw);
-
        if (ret == FALSE) {
                _E("Unable to connect to dbus: %s", error->message);
                g_error_free(error);
                return ES_R_ERROR;
        }
 
+       bundle_free_encoded_rawdata(&raw);
+
        return ES_R_OK;
 }
 
@@ -900,6 +908,9 @@ int eventsystem_send_user_event(const char *event_name, bundle *data, bool is_tr
 {
        int ret = 0;
        eventinfo_s *evti = NULL;
+       struct last_data_item *item;
+       bundle_raw *raw = NULL;
+       int len;
 
        /* check validation */
        retvm_if(!event_name, ES_R_EINVAL, "Invalid argument : event_name is NULL");
@@ -946,6 +957,7 @@ int eventsystem_send_user_event(const char *event_name, bundle *data, bool is_tr
 
        evti->destination_name = NULL;
        evti->is_user_event = true;
+       evti->is_trusted = is_trusted;
 
        GDBusConnection *conn = NULL;
        if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SESSION, ES_TYPE_USER) == ES_R_OK) {
@@ -962,6 +974,27 @@ int eventsystem_send_user_event(const char *event_name, bundle *data, bool is_tr
                } else {
                        ret = __eventsystem_send_event(conn, evti, data);
                }
+
+               if (bundle_encode(data, &raw, &len)) {
+                       _E("Unable to encode bundle");
+                       ret = ES_R_ERROR;
+                       goto out_5;
+               }
+
+               item = (struct last_data_item *)g_hash_table_lookup(last_data_tbl,
+                               evti->event_name);
+               if (item) {
+                       if (!evti->is_trusted) {
+                               if (item->param)
+                                       g_variant_unref(item->param);
+                               item->param = g_variant_new("(us)", len, raw);
+                       }
+                       if (item->trusted_param)
+                               g_variant_unref(item->trusted_param);
+                       item->trusted_param = g_variant_new("(us)", len, raw);
+               }
+
+               bundle_free_encoded_rawdata(&raw);
        } else {
                _E("getting gdbus-connetion error");
                ret = ES_R_ERROR;
@@ -970,6 +1003,7 @@ int eventsystem_send_user_event(const char *event_name, bundle *data, bool is_tr
        if (conn)
                g_object_unref(conn);
 
+out_5:
        FREE_AND_NULL(evti->object_path);
 out_4:
        FREE_AND_NULL(evti->member_name);
@@ -1492,6 +1526,198 @@ out_1:
 }
 #endif
 
+static int __request_esd_for_last_data(const char *event_name, bool check)
+{
+       int ret = 0;
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+       GDBusProxy *proxy = NULL;
+       GVariant *param = NULL;
+       GVariant *value = NULL;
+       gint result = 0;
+
+       if (!_initialized)
+               __initialize();
+
+       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SYSTEM,
+                               ES_TYPE_SYSTEM) < 0) {
+               _E("getting gdbus-connetion error");
+               ret = ES_R_ERROR;
+               goto out_1;
+       }
+
+       proxy = g_dbus_proxy_new_sync(conn,
+               G_DBUS_PROXY_FLAGS_NONE, NULL,
+               ESD_BUS_NAME, ESD_OBJECT_PATH, ESD_INTERFACE_NAME,
+               NULL, &error);
+
+       if (proxy == NULL) {
+               _E("failed to create new proxy, error(%s)", error->message);
+               g_error_free(error);
+               ret = ES_R_ERROR;
+               goto out_1;
+       }
+
+       param = g_variant_new("(ss)", event_name,
+                       check ? s_info.own_name_session_bus :
+                       s_info.own_name_system_bus);
+       value = g_dbus_proxy_call_sync(proxy,
+                       check ? "CheckLastData" : "KeepLastData", param,
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+       if (error != NULL) {
+               _E("proxy call sync error(%s)", error->message);
+               g_error_free(error);
+               ret = ES_R_ERROR;
+               goto out_2;
+       }
+
+       g_variant_get(value, "(i)", &result);
+
+       _D("result(%d)", result);
+
+       ret = result;
+
+out_2:
+       g_variant_unref(value);
+out_1:
+       if (conn)
+               g_object_unref(conn);
+
+       return ret;
+}
+
+static void _send_last_user_event(const char *event_name,
+               bundle *data, void *user_data)
+{
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+       eventinfo_s *evti = NULL;
+       int ret;
+       struct last_data_item *item;
+       const char *is_trusted;
+
+       _D("send last data");
+
+       if (g_strcmp0(event_name, SYS_EVENT_REQUEST_LAST_DATA) != 0)
+               return;
+
+       evti = calloc(1, sizeof(eventinfo_s));
+       if (!evti) {
+               _E("memory alloc failed");
+               return;
+       }
+
+       evti->event_name = (char *)bundle_get_val(data,
+                       EVT_KEY_KEPT_EVENT_NAME);
+       if (!evti->event_name) {
+               _E("memory alloc failed");
+               goto out_1;
+       }
+
+       item = (struct last_data_item *)g_hash_table_lookup(last_data_tbl,
+                       evti->event_name);
+       if (!item)
+               goto out_1;
+
+       evti->interface_name = __get_encoded_interface_name(evti->event_name);
+       if (!evti->interface_name) {
+               _E("interface_name is NULL");
+               goto out_1;
+       }
+
+       evti->member_name = strdup(EVENT_SYSTEM_MEMBER);
+       if (!evti->member_name) {
+               _E("memory alloc failed");
+               goto out_2;
+       }
+
+       evti->object_path = __get_object_path(evti->interface_name);
+       if (!evti->object_path) {
+               _E("object_path is NULL");
+               goto out_3;
+       }
+
+       evti->destination_name = (char *)bundle_get_val(data,
+                       EVT_KEY_KEPT_OWN_NAME);
+       if (!evti->destination_name) {
+               _E("object_path is NULL");
+               goto out_4;
+       }
+
+       is_trusted = bundle_get_val(data, EVT_KEY_KEPT_IS_TRUSTED);
+       if (!is_trusted) {
+               _E("object_path is NULL");
+               goto out_4;
+       }
+
+       if (strncmp("true", is_trusted, sizeof("true")) != 0) {
+                       if (!item->trusted_param)
+                               goto out_4;
+                       evti->is_trusted = true;
+       } else {
+                       if (!item->param)
+                               goto out_4;
+                       evti->is_trusted = false;
+       }
+
+       if (__get_gdbus_shared_connection(&conn, G_BUS_TYPE_SESSION,
+                               ES_TYPE_USER) == ES_R_OK) {
+               ret = g_dbus_connection_emit_signal(conn,
+                               evti->destination_name,
+                               evti->object_path,
+                               evti->interface_name,
+                               evti->member_name,
+                               evti->is_trusted ? item->trusted_param : item->param,
+                               &error);
+               if (ret == FALSE) {
+                       _E("Unable to connect to dbus: %s", error->message);
+                       g_error_free(error);
+               }
+       }
+
+       if (conn)
+               g_object_unref(conn);
+
+out_4:
+       FREE_AND_NULL(evti->object_path);
+out_3:
+       FREE_AND_NULL(evti->member_name);
+out_2:
+       FREE_AND_NULL(evti->interface_name);
+out_1:
+       FREE_AND_NULL(evti);
+}
+
+int eventsystem_keep_last_event_data(const char *event_name)
+{
+       int ret = 0;
+       unsigned int reg_id;
+       struct last_data_item *item;
+
+       if (last_data_tbl == NULL)
+               last_data_tbl = g_hash_table_new(g_str_hash, g_str_equal);
+
+       ret = __request_esd_for_last_data(event_name, false);
+       if (ret != ES_R_OK)
+               return ret;
+
+       item = calloc(1, sizeof(*item));
+       if (!item)
+               return ES_R_ENOMEM;
+
+       item->event_name = strdup(event_name);
+       item->param = NULL;
+       item->trusted_param = NULL;
+
+       g_hash_table_insert(last_data_tbl, (char *)event_name, item);
+
+       ret = eventsystem_register_event(SYS_EVENT_REQUEST_LAST_DATA,
+                       &reg_id, _send_last_user_event, NULL);
+
+       return ret;
+}
+
 int eventsystem_register_application_event(const char *event_name, unsigned int *reg_id,
                int *event_type, eventsystem_cb callback, void *user_data)
 {
@@ -1662,6 +1888,8 @@ int eventsystem_register_application_event(const char *event_name, unsigned int
        if (conn)
                g_object_unref(conn);
 
+       __request_esd_for_last_data(event_name, true);
+
        return ret;
 }
 
@@ -1759,6 +1987,26 @@ int eventsystem_application_finalize(void)
                g_hash_table_unref(filter_tbl);
        }
 
+       if (last_data_tbl) {
+               g_hash_table_iter_init(&iter, last_data_tbl);
+
+               while (g_hash_table_iter_next(&iter, &key, &value)) {
+                       key_item = (char *)key;
+                       if (key_item)
+                               free(key_item);
+                       else
+                               _E("last_data_tbl, val_item is NULL");
+
+                       val_item = (char *)value;
+                       if (val_item)
+                               free(val_item);
+                       else
+                               _E("last_data_tbl, val_item is NULL");
+                       g_hash_table_iter_remove(&iter);
+               }
+               g_hash_table_unref(check_tbl);
+       }
+
        FREE_AND_NULL(s_info.own_name_system_bus);
        FREE_AND_NULL(s_info.own_name_session_bus);